1 2 /* Author : Stephen Smalley, <sds (at) tycho.nsa.gov> */ 3 4 /* 5 * Updated: Trusted Computer Solutions, Inc. <dgoeddel (at) trustedcs.com> 6 * 7 * Support for enhanced MLS infrastructure. 8 * 9 * Updated: Frank Mayer <mayerf (at) tresys.com> and Karl MacMillan <kmacmillan (at) tresys.com> 10 * 11 * Added conditional policy language extensions 12 * 13 * Updated: Red Hat, Inc. James Morris <jmorris (at) redhat.com> 14 * Fine-grained netlink support 15 * IPv6 support 16 * Code cleanup 17 * 18 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. 19 * Copyright (C) 2003 - 2005 Tresys Technology, LLC 20 * Copyright (C) 2003 - 2007 Red Hat, Inc. 21 * Copyright (C) 2017 Mellanox Technologies Inc. 22 * 23 * This library is free software; you can redistribute it and/or 24 * modify it under the terms of the GNU Lesser General Public 25 * License as published by the Free Software Foundation; either 26 * version 2.1 of the License, or (at your option) any later version. 27 * 28 * This library is distributed in the hope that it will be useful, 29 * but WITHOUT ANY WARRANTY; without even the implied warranty of 30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 31 * Lesser General Public License for more details. 32 * 33 * You should have received a copy of the GNU Lesser General Public 34 * License along with this library; if not, write to the Free Software 35 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 36 */ 37 38 /* FLASK */ 39 40 /* 41 * Implementation of the policy database. 42 */ 43 44 #include <assert.h> 45 #include <stdlib.h> 46 47 #include <sepol/policydb/policydb.h> 48 #include <sepol/policydb/expand.h> 49 #include <sepol/policydb/conditional.h> 50 #include <sepol/policydb/avrule_block.h> 51 #include <sepol/policydb/util.h> 52 #include <sepol/policydb/flask.h> 53 54 #include "private.h" 55 #include "debug.h" 56 #include "mls.h" 57 58 #define POLICYDB_TARGET_SZ ARRAY_SIZE(policydb_target_strings) 59 const char *policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING }; 60 61 /* These need to be updated if SYM_NUM or OCON_NUM changes */ 62 static struct policydb_compat_info policydb_compat[] = { 63 { 64 .type = POLICY_KERN, 65 .version = POLICYDB_VERSION_BOUNDARY, 66 .sym_num = SYM_NUM, 67 .ocon_num = OCON_XEN_PCIDEVICE + 1, 68 .target_platform = SEPOL_TARGET_XEN, 69 }, 70 { 71 .type = POLICY_KERN, 72 .version = POLICYDB_VERSION_XEN_DEVICETREE, 73 .sym_num = SYM_NUM, 74 .ocon_num = OCON_XEN_DEVICETREE + 1, 75 .target_platform = SEPOL_TARGET_XEN, 76 }, 77 { 78 .type = POLICY_KERN, 79 .version = POLICYDB_VERSION_BASE, 80 .sym_num = SYM_NUM - 3, 81 .ocon_num = OCON_FSUSE + 1, 82 .target_platform = SEPOL_TARGET_SELINUX, 83 }, 84 { 85 .type = POLICY_KERN, 86 .version = POLICYDB_VERSION_BOOL, 87 .sym_num = SYM_NUM - 2, 88 .ocon_num = OCON_FSUSE + 1, 89 .target_platform = SEPOL_TARGET_SELINUX, 90 }, 91 { 92 .type = POLICY_KERN, 93 .version = POLICYDB_VERSION_IPV6, 94 .sym_num = SYM_NUM - 2, 95 .ocon_num = OCON_NODE6 + 1, 96 .target_platform = SEPOL_TARGET_SELINUX, 97 }, 98 { 99 .type = POLICY_KERN, 100 .version = POLICYDB_VERSION_NLCLASS, 101 .sym_num = SYM_NUM - 2, 102 .ocon_num = OCON_NODE6 + 1, 103 .target_platform = SEPOL_TARGET_SELINUX, 104 }, 105 { 106 .type = POLICY_KERN, 107 .version = POLICYDB_VERSION_MLS, 108 .sym_num = SYM_NUM, 109 .ocon_num = OCON_NODE6 + 1, 110 .target_platform = SEPOL_TARGET_SELINUX, 111 }, 112 { 113 .type = POLICY_KERN, 114 .version = POLICYDB_VERSION_AVTAB, 115 .sym_num = SYM_NUM, 116 .ocon_num = OCON_NODE6 + 1, 117 .target_platform = SEPOL_TARGET_SELINUX, 118 }, 119 { 120 .type = POLICY_KERN, 121 .version = POLICYDB_VERSION_RANGETRANS, 122 .sym_num = SYM_NUM, 123 .ocon_num = OCON_NODE6 + 1, 124 .target_platform = SEPOL_TARGET_SELINUX, 125 }, 126 { 127 .type = POLICY_KERN, 128 .version = POLICYDB_VERSION_POLCAP, 129 .sym_num = SYM_NUM, 130 .ocon_num = OCON_NODE6 + 1, 131 .target_platform = SEPOL_TARGET_SELINUX, 132 }, 133 { 134 .type = POLICY_KERN, 135 .version = POLICYDB_VERSION_PERMISSIVE, 136 .sym_num = SYM_NUM, 137 .ocon_num = OCON_NODE6 + 1, 138 .target_platform = SEPOL_TARGET_SELINUX, 139 }, 140 { 141 .type = POLICY_KERN, 142 .version = POLICYDB_VERSION_BOUNDARY, 143 .sym_num = SYM_NUM, 144 .ocon_num = OCON_NODE6 + 1, 145 .target_platform = SEPOL_TARGET_SELINUX, 146 }, 147 { 148 .type = POLICY_KERN, 149 .version = POLICYDB_VERSION_FILENAME_TRANS, 150 .sym_num = SYM_NUM, 151 .ocon_num = OCON_NODE6 + 1, 152 .target_platform = SEPOL_TARGET_SELINUX, 153 }, 154 { 155 .type = POLICY_KERN, 156 .version = POLICYDB_VERSION_ROLETRANS, 157 .sym_num = SYM_NUM, 158 .ocon_num = OCON_NODE6 + 1, 159 .target_platform = SEPOL_TARGET_SELINUX, 160 }, 161 { 162 .type = POLICY_KERN, 163 .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, 164 .sym_num = SYM_NUM, 165 .ocon_num = OCON_NODE6 + 1, 166 .target_platform = SEPOL_TARGET_SELINUX, 167 }, 168 { 169 .type = POLICY_KERN, 170 .version = POLICYDB_VERSION_DEFAULT_TYPE, 171 .sym_num = SYM_NUM, 172 .ocon_num = OCON_NODE6 + 1, 173 .target_platform = SEPOL_TARGET_SELINUX, 174 }, 175 { 176 .type = POLICY_KERN, 177 .version = POLICYDB_VERSION_CONSTRAINT_NAMES, 178 .sym_num = SYM_NUM, 179 .ocon_num = OCON_NODE6 + 1, 180 .target_platform = SEPOL_TARGET_SELINUX, 181 }, 182 { 183 .type = POLICY_KERN, 184 .version = POLICYDB_VERSION_XPERMS_IOCTL, 185 .sym_num = SYM_NUM, 186 .ocon_num = OCON_NODE6 + 1, 187 .target_platform = SEPOL_TARGET_SELINUX, 188 }, 189 { 190 .type = POLICY_KERN, 191 .version = POLICYDB_VERSION_INFINIBAND, 192 .sym_num = SYM_NUM, 193 .ocon_num = OCON_IBENDPORT + 1, 194 .target_platform = SEPOL_TARGET_SELINUX, 195 }, 196 { 197 .type = POLICY_BASE, 198 .version = MOD_POLICYDB_VERSION_BASE, 199 .sym_num = SYM_NUM, 200 .ocon_num = OCON_NODE6 + 1, 201 .target_platform = SEPOL_TARGET_SELINUX, 202 }, 203 { 204 .type = POLICY_BASE, 205 .version = MOD_POLICYDB_VERSION_MLS, 206 .sym_num = SYM_NUM, 207 .ocon_num = OCON_NODE6 + 1, 208 .target_platform = SEPOL_TARGET_SELINUX, 209 }, 210 { 211 .type = POLICY_BASE, 212 .version = MOD_POLICYDB_VERSION_MLS_USERS, 213 .sym_num = SYM_NUM, 214 .ocon_num = OCON_NODE6 + 1, 215 .target_platform = SEPOL_TARGET_SELINUX, 216 }, 217 { 218 .type = POLICY_BASE, 219 .version = MOD_POLICYDB_VERSION_POLCAP, 220 .sym_num = SYM_NUM, 221 .ocon_num = OCON_NODE6 + 1, 222 .target_platform = SEPOL_TARGET_SELINUX, 223 }, 224 { 225 .type = POLICY_BASE, 226 .version = MOD_POLICYDB_VERSION_PERMISSIVE, 227 .sym_num = SYM_NUM, 228 .ocon_num = OCON_NODE6 + 1, 229 .target_platform = SEPOL_TARGET_SELINUX, 230 }, 231 { 232 .type = POLICY_BASE, 233 .version = MOD_POLICYDB_VERSION_BOUNDARY, 234 .sym_num = SYM_NUM, 235 .ocon_num = OCON_NODE6 + 1, 236 .target_platform = SEPOL_TARGET_SELINUX, 237 }, 238 { 239 .type = POLICY_BASE, 240 .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS, 241 .sym_num = SYM_NUM, 242 .ocon_num = OCON_NODE6 + 1, 243 .target_platform = SEPOL_TARGET_SELINUX, 244 }, 245 { 246 .type = POLICY_BASE, 247 .version = MOD_POLICYDB_VERSION_FILENAME_TRANS, 248 .sym_num = SYM_NUM, 249 .ocon_num = OCON_NODE6 + 1, 250 .target_platform = SEPOL_TARGET_SELINUX, 251 }, 252 { 253 .type = POLICY_BASE, 254 .version = MOD_POLICYDB_VERSION_ROLETRANS, 255 .sym_num = SYM_NUM, 256 .ocon_num = OCON_NODE6 + 1, 257 .target_platform = SEPOL_TARGET_SELINUX, 258 }, 259 { 260 .type = POLICY_BASE, 261 .version = MOD_POLICYDB_VERSION_ROLEATTRIB, 262 .sym_num = SYM_NUM, 263 .ocon_num = OCON_NODE6 + 1, 264 .target_platform = SEPOL_TARGET_SELINUX, 265 }, 266 { 267 .type = POLICY_BASE, 268 .version = MOD_POLICYDB_VERSION_TUNABLE_SEP, 269 .sym_num = SYM_NUM, 270 .ocon_num = OCON_NODE6 + 1, 271 .target_platform = SEPOL_TARGET_SELINUX, 272 }, 273 { 274 .type = POLICY_BASE, 275 .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, 276 .sym_num = SYM_NUM, 277 .ocon_num = OCON_NODE6 + 1, 278 .target_platform = SEPOL_TARGET_SELINUX, 279 }, 280 { 281 .type = POLICY_BASE, 282 .version = MOD_POLICYDB_VERSION_DEFAULT_TYPE, 283 .sym_num = SYM_NUM, 284 .ocon_num = OCON_NODE6 + 1, 285 .target_platform = SEPOL_TARGET_SELINUX, 286 }, 287 { 288 .type = POLICY_BASE, 289 .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES, 290 .sym_num = SYM_NUM, 291 .ocon_num = OCON_NODE6 + 1, 292 .target_platform = SEPOL_TARGET_SELINUX, 293 }, 294 { 295 .type = POLICY_BASE, 296 .version = MOD_POLICYDB_VERSION_XPERMS_IOCTL, 297 .sym_num = SYM_NUM, 298 .ocon_num = OCON_NODE6 + 1, 299 .target_platform = SEPOL_TARGET_SELINUX, 300 }, 301 { 302 .type = POLICY_BASE, 303 .version = MOD_POLICYDB_VERSION_INFINIBAND, 304 .sym_num = SYM_NUM, 305 .ocon_num = OCON_IBENDPORT + 1, 306 .target_platform = SEPOL_TARGET_SELINUX, 307 }, 308 { 309 .type = POLICY_MOD, 310 .version = MOD_POLICYDB_VERSION_BASE, 311 .sym_num = SYM_NUM, 312 .ocon_num = 0, 313 .target_platform = SEPOL_TARGET_SELINUX, 314 }, 315 { 316 .type = POLICY_MOD, 317 .version = MOD_POLICYDB_VERSION_MLS, 318 .sym_num = SYM_NUM, 319 .ocon_num = 0, 320 .target_platform = SEPOL_TARGET_SELINUX, 321 }, 322 { 323 .type = POLICY_MOD, 324 .version = MOD_POLICYDB_VERSION_MLS_USERS, 325 .sym_num = SYM_NUM, 326 .ocon_num = 0, 327 .target_platform = SEPOL_TARGET_SELINUX, 328 }, 329 { 330 .type = POLICY_MOD, 331 .version = MOD_POLICYDB_VERSION_POLCAP, 332 .sym_num = SYM_NUM, 333 .ocon_num = 0, 334 .target_platform = SEPOL_TARGET_SELINUX, 335 }, 336 { 337 .type = POLICY_MOD, 338 .version = MOD_POLICYDB_VERSION_PERMISSIVE, 339 .sym_num = SYM_NUM, 340 .ocon_num = 0, 341 .target_platform = SEPOL_TARGET_SELINUX, 342 }, 343 { 344 .type = POLICY_MOD, 345 .version = MOD_POLICYDB_VERSION_BOUNDARY, 346 .sym_num = SYM_NUM, 347 .ocon_num = 0, 348 .target_platform = SEPOL_TARGET_SELINUX, 349 }, 350 { 351 .type = POLICY_MOD, 352 .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS, 353 .sym_num = SYM_NUM, 354 .ocon_num = 0, 355 .target_platform = SEPOL_TARGET_SELINUX, 356 }, 357 { 358 .type = POLICY_MOD, 359 .version = MOD_POLICYDB_VERSION_FILENAME_TRANS, 360 .sym_num = SYM_NUM, 361 .ocon_num = 0, 362 .target_platform = SEPOL_TARGET_SELINUX, 363 }, 364 { 365 .type = POLICY_MOD, 366 .version = MOD_POLICYDB_VERSION_ROLETRANS, 367 .sym_num = SYM_NUM, 368 .ocon_num = 0, 369 .target_platform = SEPOL_TARGET_SELINUX, 370 }, 371 { 372 .type = POLICY_MOD, 373 .version = MOD_POLICYDB_VERSION_ROLEATTRIB, 374 .sym_num = SYM_NUM, 375 .ocon_num = 0, 376 .target_platform = SEPOL_TARGET_SELINUX, 377 }, 378 { 379 .type = POLICY_MOD, 380 .version = MOD_POLICYDB_VERSION_TUNABLE_SEP, 381 .sym_num = SYM_NUM, 382 .ocon_num = 0, 383 .target_platform = SEPOL_TARGET_SELINUX, 384 }, 385 { 386 .type = POLICY_MOD, 387 .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS, 388 .sym_num = SYM_NUM, 389 .ocon_num = 0, 390 .target_platform = SEPOL_TARGET_SELINUX, 391 }, 392 { 393 .type = POLICY_MOD, 394 .version = MOD_POLICYDB_VERSION_DEFAULT_TYPE, 395 .sym_num = SYM_NUM, 396 .ocon_num = 0, 397 .target_platform = SEPOL_TARGET_SELINUX, 398 }, 399 { 400 .type = POLICY_MOD, 401 .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES, 402 .sym_num = SYM_NUM, 403 .ocon_num = 0, 404 .target_platform = SEPOL_TARGET_SELINUX, 405 }, 406 { 407 .type = POLICY_MOD, 408 .version = MOD_POLICYDB_VERSION_XPERMS_IOCTL, 409 .sym_num = SYM_NUM, 410 .ocon_num = 0, 411 .target_platform = SEPOL_TARGET_SELINUX, 412 }, 413 { 414 .type = POLICY_MOD, 415 .version = MOD_POLICYDB_VERSION_INFINIBAND, 416 .sym_num = SYM_NUM, 417 .ocon_num = 0, 418 .target_platform = SEPOL_TARGET_SELINUX, 419 }, 420 }; 421 422 #if 0 423 static char *symtab_name[SYM_NUM] = { 424 "common prefixes", 425 "classes", 426 "roles", 427 "types", 428 "users", 429 "bools" mls_symtab_names cond_symtab_names 430 }; 431 #endif 432 433 static unsigned int symtab_sizes[SYM_NUM] = { 434 2, 435 32, 436 16, 437 512, 438 128, 439 16, 440 16, 441 16, 442 }; 443 444 struct policydb_compat_info *policydb_lookup_compat(unsigned int version, 445 unsigned int type, 446 unsigned int target_platform) 447 { 448 unsigned int i; 449 struct policydb_compat_info *info = NULL; 450 451 for (i = 0; i < sizeof(policydb_compat) / sizeof(*info); i++) { 452 if (policydb_compat[i].version == version && 453 policydb_compat[i].type == type && 454 policydb_compat[i].target_platform == target_platform) { 455 info = &policydb_compat[i]; 456 break; 457 } 458 } 459 return info; 460 } 461 462 void type_set_init(type_set_t * x) 463 { 464 memset(x, 0, sizeof(type_set_t)); 465 ebitmap_init(&x->types); 466 ebitmap_init(&x->negset); 467 } 468 469 void type_set_destroy(type_set_t * x) 470 { 471 if (x != NULL) { 472 ebitmap_destroy(&x->types); 473 ebitmap_destroy(&x->negset); 474 } 475 } 476 477 void role_set_init(role_set_t * x) 478 { 479 memset(x, 0, sizeof(role_set_t)); 480 ebitmap_init(&x->roles); 481 } 482 483 void role_set_destroy(role_set_t * x) 484 { 485 ebitmap_destroy(&x->roles); 486 } 487 488 void role_datum_init(role_datum_t * x) 489 { 490 memset(x, 0, sizeof(role_datum_t)); 491 ebitmap_init(&x->dominates); 492 type_set_init(&x->types); 493 ebitmap_init(&x->cache); 494 ebitmap_init(&x->roles); 495 } 496 497 void role_datum_destroy(role_datum_t * x) 498 { 499 if (x != NULL) { 500 ebitmap_destroy(&x->dominates); 501 type_set_destroy(&x->types); 502 ebitmap_destroy(&x->cache); 503 ebitmap_destroy(&x->roles); 504 } 505 } 506 507 void type_datum_init(type_datum_t * x) 508 { 509 memset(x, 0, sizeof(*x)); 510 ebitmap_init(&x->types); 511 } 512 513 void type_datum_destroy(type_datum_t * x) 514 { 515 if (x != NULL) { 516 ebitmap_destroy(&x->types); 517 } 518 } 519 520 void user_datum_init(user_datum_t * x) 521 { 522 memset(x, 0, sizeof(user_datum_t)); 523 role_set_init(&x->roles); 524 mls_semantic_range_init(&x->range); 525 mls_semantic_level_init(&x->dfltlevel); 526 ebitmap_init(&x->cache); 527 mls_range_init(&x->exp_range); 528 mls_level_init(&x->exp_dfltlevel); 529 } 530 531 void user_datum_destroy(user_datum_t * x) 532 { 533 if (x != NULL) { 534 role_set_destroy(&x->roles); 535 mls_semantic_range_destroy(&x->range); 536 mls_semantic_level_destroy(&x->dfltlevel); 537 ebitmap_destroy(&x->cache); 538 mls_range_destroy(&x->exp_range); 539 mls_level_destroy(&x->exp_dfltlevel); 540 } 541 } 542 543 void level_datum_init(level_datum_t * x) 544 { 545 memset(x, 0, sizeof(level_datum_t)); 546 } 547 548 void level_datum_destroy(level_datum_t * x __attribute__ ((unused))) 549 { 550 /* the mls_level_t referenced by the level_datum is managed 551 * separately for now, so there is nothing to destroy */ 552 return; 553 } 554 555 void cat_datum_init(cat_datum_t * x) 556 { 557 memset(x, 0, sizeof(cat_datum_t)); 558 } 559 560 void cat_datum_destroy(cat_datum_t * x __attribute__ ((unused))) 561 { 562 /* it's currently a simple struct - really nothing to destroy */ 563 return; 564 } 565 566 void class_perm_node_init(class_perm_node_t * x) 567 { 568 memset(x, 0, sizeof(class_perm_node_t)); 569 } 570 571 void avrule_init(avrule_t * x) 572 { 573 memset(x, 0, sizeof(avrule_t)); 574 type_set_init(&x->stypes); 575 type_set_init(&x->ttypes); 576 } 577 578 void avrule_destroy(avrule_t * x) 579 { 580 class_perm_node_t *cur, *next; 581 582 if (x == NULL) { 583 return; 584 } 585 type_set_destroy(&x->stypes); 586 type_set_destroy(&x->ttypes); 587 588 free(x->source_filename); 589 590 next = x->perms; 591 while (next) { 592 cur = next; 593 next = cur->next; 594 free(cur); 595 } 596 597 free(x->xperms); 598 } 599 600 void role_trans_rule_init(role_trans_rule_t * x) 601 { 602 memset(x, 0, sizeof(*x)); 603 role_set_init(&x->roles); 604 type_set_init(&x->types); 605 ebitmap_init(&x->classes); 606 } 607 608 void role_trans_rule_destroy(role_trans_rule_t * x) 609 { 610 if (x != NULL) { 611 role_set_destroy(&x->roles); 612 type_set_destroy(&x->types); 613 ebitmap_destroy(&x->classes); 614 } 615 } 616 617 void role_trans_rule_list_destroy(role_trans_rule_t * x) 618 { 619 while (x != NULL) { 620 role_trans_rule_t *next = x->next; 621 role_trans_rule_destroy(x); 622 free(x); 623 x = next; 624 } 625 } 626 627 void filename_trans_rule_init(filename_trans_rule_t * x) 628 { 629 memset(x, 0, sizeof(*x)); 630 type_set_init(&x->stypes); 631 type_set_init(&x->ttypes); 632 } 633 634 static void filename_trans_rule_destroy(filename_trans_rule_t * x) 635 { 636 if (!x) 637 return; 638 type_set_destroy(&x->stypes); 639 type_set_destroy(&x->ttypes); 640 free(x->name); 641 } 642 643 void filename_trans_rule_list_destroy(filename_trans_rule_t * x) 644 { 645 filename_trans_rule_t *next; 646 while (x) { 647 next = x->next; 648 filename_trans_rule_destroy(x); 649 free(x); 650 x = next; 651 } 652 } 653 654 void role_allow_rule_init(role_allow_rule_t * x) 655 { 656 memset(x, 0, sizeof(role_allow_rule_t)); 657 role_set_init(&x->roles); 658 role_set_init(&x->new_roles); 659 } 660 661 void role_allow_rule_destroy(role_allow_rule_t * x) 662 { 663 role_set_destroy(&x->roles); 664 role_set_destroy(&x->new_roles); 665 } 666 667 void role_allow_rule_list_destroy(role_allow_rule_t * x) 668 { 669 while (x != NULL) { 670 role_allow_rule_t *next = x->next; 671 role_allow_rule_destroy(x); 672 free(x); 673 x = next; 674 } 675 } 676 677 void range_trans_rule_init(range_trans_rule_t * x) 678 { 679 type_set_init(&x->stypes); 680 type_set_init(&x->ttypes); 681 ebitmap_init(&x->tclasses); 682 mls_semantic_range_init(&x->trange); 683 x->next = NULL; 684 } 685 686 void range_trans_rule_destroy(range_trans_rule_t * x) 687 { 688 type_set_destroy(&x->stypes); 689 type_set_destroy(&x->ttypes); 690 ebitmap_destroy(&x->tclasses); 691 mls_semantic_range_destroy(&x->trange); 692 } 693 694 void range_trans_rule_list_destroy(range_trans_rule_t * x) 695 { 696 while (x != NULL) { 697 range_trans_rule_t *next = x->next; 698 range_trans_rule_destroy(x); 699 free(x); 700 x = next; 701 } 702 } 703 704 void avrule_list_destroy(avrule_t * x) 705 { 706 avrule_t *next, *cur; 707 708 if (!x) 709 return; 710 711 next = x; 712 while (next) { 713 cur = next; 714 next = next->next; 715 avrule_destroy(cur); 716 free(cur); 717 } 718 } 719 720 /* 721 * Initialize the role table by implicitly adding role 'object_r'. If 722 * the policy is a module, set object_r's scope to be SCOPE_REQ, 723 * otherwise set it to SCOPE_DECL. 724 */ 725 static int roles_init(policydb_t * p) 726 { 727 char *key = 0; 728 int rc; 729 role_datum_t *role; 730 731 role = calloc(1, sizeof(role_datum_t)); 732 if (!role) { 733 rc = -ENOMEM; 734 goto out; 735 } 736 key = malloc(strlen(OBJECT_R) + 1); 737 if (!key) { 738 rc = -ENOMEM; 739 goto out_free_role; 740 } 741 strcpy(key, OBJECT_R); 742 rc = symtab_insert(p, SYM_ROLES, key, role, 743 (p->policy_type == 744 POLICY_MOD ? SCOPE_REQ : SCOPE_DECL), 1, 745 &role->s.value); 746 if (rc) 747 goto out_free_key; 748 if (role->s.value != OBJECT_R_VAL) { 749 rc = -EINVAL; 750 goto out_free_role; 751 } 752 out: 753 return rc; 754 755 out_free_key: 756 free(key); 757 out_free_role: 758 free(role); 759 goto out; 760 } 761 762 static inline unsigned long 763 partial_name_hash(unsigned long c, unsigned long prevhash) 764 { 765 return (prevhash + (c << 4) + (c >> 4)) * 11; 766 } 767 768 static unsigned int filenametr_hash(hashtab_t h, const_hashtab_key_t k) 769 { 770 const struct filename_trans *ft = (const struct filename_trans *)k; 771 unsigned long hash; 772 unsigned int byte_num; 773 unsigned char focus; 774 775 hash = ft->stype ^ ft->ttype ^ ft->tclass; 776 777 byte_num = 0; 778 while ((focus = ft->name[byte_num++])) 779 hash = partial_name_hash(focus, hash); 780 return hash & (h->size - 1); 781 } 782 783 static int filenametr_cmp(hashtab_t h __attribute__ ((unused)), 784 const_hashtab_key_t k1, const_hashtab_key_t k2) 785 { 786 const struct filename_trans *ft1 = (const struct filename_trans *)k1; 787 const struct filename_trans *ft2 = (const struct filename_trans *)k2; 788 int v; 789 790 v = ft1->stype - ft2->stype; 791 if (v) 792 return v; 793 794 v = ft1->ttype - ft2->ttype; 795 if (v) 796 return v; 797 798 v = ft1->tclass - ft2->tclass; 799 if (v) 800 return v; 801 802 return strcmp(ft1->name, ft2->name); 803 804 } 805 806 static unsigned int rangetr_hash(hashtab_t h, const_hashtab_key_t k) 807 { 808 const struct range_trans *key = (const struct range_trans *)k; 809 return (key->source_type + (key->target_type << 3) + 810 (key->target_class << 5)) & (h->size - 1); 811 } 812 813 static int rangetr_cmp(hashtab_t h __attribute__ ((unused)), 814 const_hashtab_key_t k1, const_hashtab_key_t k2) 815 { 816 const struct range_trans *key1 = (const struct range_trans *)k1; 817 const struct range_trans *key2 = (const struct range_trans *)k2; 818 int v; 819 820 v = key1->source_type - key2->source_type; 821 if (v) 822 return v; 823 824 v = key1->target_type - key2->target_type; 825 if (v) 826 return v; 827 828 v = key1->target_class - key2->target_class; 829 830 return v; 831 } 832 833 /* 834 * Initialize a policy database structure. 835 */ 836 int policydb_init(policydb_t * p) 837 { 838 int i, rc; 839 840 memset(p, 0, sizeof(policydb_t)); 841 842 for (i = 0; i < SYM_NUM; i++) { 843 p->sym_val_to_name[i] = NULL; 844 rc = symtab_init(&p->symtab[i], symtab_sizes[i]); 845 if (rc) 846 goto err; 847 } 848 849 /* initialize the module stuff */ 850 for (i = 0; i < SYM_NUM; i++) { 851 if (symtab_init(&p->scope[i], symtab_sizes[i])) { 852 goto err; 853 } 854 } 855 if ((p->global = avrule_block_create()) == NULL || 856 (p->global->branch_list = avrule_decl_create(1)) == NULL) { 857 goto err; 858 } 859 p->decl_val_to_struct = NULL; 860 861 rc = avtab_init(&p->te_avtab); 862 if (rc) 863 goto err; 864 865 rc = roles_init(p); 866 if (rc) 867 goto err; 868 869 rc = cond_policydb_init(p); 870 if (rc) 871 goto err; 872 873 p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10)); 874 if (!p->filename_trans) { 875 rc = -ENOMEM; 876 goto err; 877 } 878 879 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); 880 if (!p->range_tr) { 881 rc = -ENOMEM; 882 goto err; 883 } 884 885 ebitmap_init(&p->policycaps); 886 ebitmap_init(&p->permissive_map); 887 888 return 0; 889 err: 890 hashtab_destroy(p->filename_trans); 891 hashtab_destroy(p->range_tr); 892 for (i = 0; i < SYM_NUM; i++) { 893 hashtab_destroy(p->symtab[i].table); 894 hashtab_destroy(p->scope[i].table); 895 } 896 avrule_block_list_destroy(p->global); 897 return rc; 898 } 899 900 int policydb_role_cache(hashtab_key_t key 901 __attribute__ ((unused)), hashtab_datum_t datum, 902 void *arg) 903 { 904 policydb_t *p; 905 role_datum_t *role; 906 907 role = (role_datum_t *) datum; 908 p = (policydb_t *) arg; 909 910 ebitmap_destroy(&role->cache); 911 if (type_set_expand(&role->types, &role->cache, p, 1)) { 912 return -1; 913 } 914 915 return 0; 916 } 917 918 int policydb_user_cache(hashtab_key_t key 919 __attribute__ ((unused)), hashtab_datum_t datum, 920 void *arg) 921 { 922 policydb_t *p; 923 user_datum_t *user; 924 925 user = (user_datum_t *) datum; 926 p = (policydb_t *) arg; 927 928 ebitmap_destroy(&user->cache); 929 if (role_set_expand(&user->roles, &user->cache, p, NULL, NULL)) { 930 return -1; 931 } 932 933 /* we do not expand user's MLS info in kernel policies because the 934 * semantic representation is not present and we do not expand user's 935 * MLS info in module policies because all of the necessary mls 936 * information is not present */ 937 if (p->policy_type != POLICY_KERN && p->policy_type != POLICY_MOD) { 938 mls_range_destroy(&user->exp_range); 939 if (mls_semantic_range_expand(&user->range, 940 &user->exp_range, p, NULL)) { 941 return -1; 942 } 943 944 mls_level_destroy(&user->exp_dfltlevel); 945 if (mls_semantic_level_expand(&user->dfltlevel, 946 &user->exp_dfltlevel, p, NULL)) { 947 return -1; 948 } 949 } 950 951 return 0; 952 } 953 954 /* 955 * The following *_index functions are used to 956 * define the val_to_name and val_to_struct arrays 957 * in a policy database structure. The val_to_name 958 * arrays are used when converting security context 959 * structures into string representations. The 960 * val_to_struct arrays are used when the attributes 961 * of a class, role, or user are needed. 962 */ 963 964 static int common_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 965 { 966 policydb_t *p; 967 common_datum_t *comdatum; 968 969 comdatum = (common_datum_t *) datum; 970 p = (policydb_t *) datap; 971 if (!comdatum->s.value || comdatum->s.value > p->p_commons.nprim) 972 return -EINVAL; 973 if (p->p_common_val_to_name[comdatum->s.value - 1] != NULL) 974 return -EINVAL; 975 p->p_common_val_to_name[comdatum->s.value - 1] = (char *)key; 976 977 return 0; 978 } 979 980 static int class_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 981 { 982 policydb_t *p; 983 class_datum_t *cladatum; 984 985 cladatum = (class_datum_t *) datum; 986 p = (policydb_t *) datap; 987 if (!cladatum->s.value || cladatum->s.value > p->p_classes.nprim) 988 return -EINVAL; 989 if (p->p_class_val_to_name[cladatum->s.value - 1] != NULL) 990 return -EINVAL; 991 p->p_class_val_to_name[cladatum->s.value - 1] = (char *)key; 992 p->class_val_to_struct[cladatum->s.value - 1] = cladatum; 993 994 return 0; 995 } 996 997 static int role_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 998 { 999 policydb_t *p; 1000 role_datum_t *role; 1001 1002 role = (role_datum_t *) datum; 1003 p = (policydb_t *) datap; 1004 if (!role->s.value || role->s.value > p->p_roles.nprim) 1005 return -EINVAL; 1006 if (p->p_role_val_to_name[role->s.value - 1] != NULL) 1007 return -EINVAL; 1008 p->p_role_val_to_name[role->s.value - 1] = (char *)key; 1009 p->role_val_to_struct[role->s.value - 1] = role; 1010 1011 return 0; 1012 } 1013 1014 static int type_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 1015 { 1016 policydb_t *p; 1017 type_datum_t *typdatum; 1018 1019 typdatum = (type_datum_t *) datum; 1020 p = (policydb_t *) datap; 1021 1022 if (typdatum->primary) { 1023 if (!typdatum->s.value || typdatum->s.value > p->p_types.nprim) 1024 return -EINVAL; 1025 if (p->p_type_val_to_name[typdatum->s.value - 1] != NULL) 1026 return -EINVAL; 1027 p->p_type_val_to_name[typdatum->s.value - 1] = (char *)key; 1028 p->type_val_to_struct[typdatum->s.value - 1] = typdatum; 1029 } 1030 1031 return 0; 1032 } 1033 1034 static int user_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 1035 { 1036 policydb_t *p; 1037 user_datum_t *usrdatum; 1038 1039 usrdatum = (user_datum_t *) datum; 1040 p = (policydb_t *) datap; 1041 1042 if (!usrdatum->s.value || usrdatum->s.value > p->p_users.nprim) 1043 return -EINVAL; 1044 if (p->p_user_val_to_name[usrdatum->s.value - 1] != NULL) 1045 return -EINVAL; 1046 p->p_user_val_to_name[usrdatum->s.value - 1] = (char *)key; 1047 p->user_val_to_struct[usrdatum->s.value - 1] = usrdatum; 1048 1049 return 0; 1050 } 1051 1052 static int sens_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 1053 { 1054 policydb_t *p; 1055 level_datum_t *levdatum; 1056 1057 levdatum = (level_datum_t *) datum; 1058 p = (policydb_t *) datap; 1059 1060 if (!levdatum->isalias) { 1061 if (!levdatum->level->sens || 1062 levdatum->level->sens > p->p_levels.nprim) 1063 return -EINVAL; 1064 if (p->p_sens_val_to_name[levdatum->level->sens - 1] != NULL) 1065 return -EINVAL; 1066 p->p_sens_val_to_name[levdatum->level->sens - 1] = (char *)key; 1067 } 1068 1069 return 0; 1070 } 1071 1072 static int cat_index(hashtab_key_t key, hashtab_datum_t datum, void *datap) 1073 { 1074 policydb_t *p; 1075 cat_datum_t *catdatum; 1076 1077 catdatum = (cat_datum_t *) datum; 1078 p = (policydb_t *) datap; 1079 1080 if (!catdatum->isalias) { 1081 if (!catdatum->s.value || catdatum->s.value > p->p_cats.nprim) 1082 return -EINVAL; 1083 if (p->p_cat_val_to_name[catdatum->s.value - 1] != NULL) 1084 return -EINVAL; 1085 p->p_cat_val_to_name[catdatum->s.value - 1] = (char *)key; 1086 } 1087 1088 return 0; 1089 } 1090 1091 static int (*index_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, 1092 void *datap) = { 1093 common_index, class_index, role_index, type_index, user_index, 1094 cond_index_bool, sens_index, cat_index,}; 1095 1096 /* 1097 * Define the common val_to_name array and the class 1098 * val_to_name and val_to_struct arrays in a policy 1099 * database structure. 1100 */ 1101 int policydb_index_classes(policydb_t * p) 1102 { 1103 free(p->p_common_val_to_name); 1104 p->p_common_val_to_name = (char **) 1105 calloc(p->p_commons.nprim, sizeof(char *)); 1106 if (!p->p_common_val_to_name) 1107 return -1; 1108 1109 if (hashtab_map(p->p_commons.table, common_index, p)) 1110 return -1; 1111 1112 free(p->class_val_to_struct); 1113 p->class_val_to_struct = (class_datum_t **) 1114 calloc(p->p_classes.nprim, sizeof(class_datum_t *)); 1115 if (!p->class_val_to_struct) 1116 return -1; 1117 1118 free(p->p_class_val_to_name); 1119 p->p_class_val_to_name = (char **) 1120 calloc(p->p_classes.nprim, sizeof(char *)); 1121 if (!p->p_class_val_to_name) 1122 return -1; 1123 1124 if (hashtab_map(p->p_classes.table, class_index, p)) 1125 return -1; 1126 1127 return 0; 1128 } 1129 1130 int policydb_index_bools(policydb_t * p) 1131 { 1132 1133 if (cond_init_bool_indexes(p) == -1) 1134 return -1; 1135 p->p_bool_val_to_name = (char **) 1136 calloc(p->p_bools.nprim, sizeof(char *)); 1137 if (!p->p_bool_val_to_name) 1138 return -1; 1139 if (hashtab_map(p->p_bools.table, cond_index_bool, p)) 1140 return -1; 1141 return 0; 1142 } 1143 1144 int policydb_index_decls(sepol_handle_t * handle, policydb_t * p) 1145 { 1146 avrule_block_t *curblock; 1147 avrule_decl_t *decl; 1148 unsigned int num_decls = 0; 1149 1150 free(p->decl_val_to_struct); 1151 1152 for (curblock = p->global; curblock != NULL; curblock = curblock->next) { 1153 for (decl = curblock->branch_list; decl != NULL; 1154 decl = decl->next) { 1155 num_decls++; 1156 } 1157 } 1158 1159 p->decl_val_to_struct = 1160 calloc(num_decls, sizeof(*(p->decl_val_to_struct))); 1161 if (!p->decl_val_to_struct) { 1162 return -1; 1163 } 1164 1165 for (curblock = p->global; curblock != NULL; curblock = curblock->next) { 1166 for (decl = curblock->branch_list; decl != NULL; 1167 decl = decl->next) { 1168 if (decl->decl_id < 1 || decl->decl_id > num_decls) { 1169 ERR(handle, "invalid decl ID %u", decl->decl_id); 1170 return -1; 1171 } 1172 if (p->decl_val_to_struct[decl->decl_id - 1] != NULL) { 1173 ERR(handle, "duplicated decl ID %u", decl->decl_id); 1174 return -1; 1175 } 1176 p->decl_val_to_struct[decl->decl_id - 1] = decl; 1177 } 1178 } 1179 1180 return 0; 1181 } 1182 1183 /* 1184 * Define the other val_to_name and val_to_struct arrays 1185 * in a policy database structure. 1186 */ 1187 int policydb_index_others(sepol_handle_t * handle, 1188 policydb_t * p, unsigned verbose) 1189 { 1190 int i; 1191 1192 if (verbose) { 1193 INFO(handle, 1194 "security: %d users, %d roles, %d types, %d bools", 1195 p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, 1196 p->p_bools.nprim); 1197 1198 if (p->mls) 1199 INFO(handle, "security: %d sens, %d cats", 1200 p->p_levels.nprim, p->p_cats.nprim); 1201 1202 INFO(handle, "security: %d classes, %d rules, %d cond rules", 1203 p->p_classes.nprim, p->te_avtab.nel, p->te_cond_avtab.nel); 1204 } 1205 #if 0 1206 avtab_hash_eval(&p->te_avtab, "rules"); 1207 for (i = 0; i < SYM_NUM; i++) 1208 hashtab_hash_eval(p->symtab[i].table, symtab_name[i]); 1209 #endif 1210 1211 free(p->role_val_to_struct); 1212 p->role_val_to_struct = (role_datum_t **) 1213 calloc(p->p_roles.nprim, sizeof(role_datum_t *)); 1214 if (!p->role_val_to_struct) 1215 return -1; 1216 1217 free(p->user_val_to_struct); 1218 p->user_val_to_struct = (user_datum_t **) 1219 calloc(p->p_users.nprim, sizeof(user_datum_t *)); 1220 if (!p->user_val_to_struct) 1221 return -1; 1222 1223 free(p->type_val_to_struct); 1224 p->type_val_to_struct = (type_datum_t **) 1225 calloc(p->p_types.nprim, sizeof(type_datum_t *)); 1226 if (!p->type_val_to_struct) 1227 return -1; 1228 1229 cond_init_bool_indexes(p); 1230 1231 for (i = SYM_ROLES; i < SYM_NUM; i++) { 1232 free(p->sym_val_to_name[i]); 1233 p->sym_val_to_name[i] = NULL; 1234 if (p->symtab[i].nprim) { 1235 p->sym_val_to_name[i] = (char **) 1236 calloc(p->symtab[i].nprim, sizeof(char *)); 1237 if (!p->sym_val_to_name[i]) 1238 return -1; 1239 if (hashtab_map(p->symtab[i].table, index_f[i], p)) 1240 return -1; 1241 } 1242 } 1243 1244 /* This pre-expands the roles and users for context validity checking */ 1245 if (hashtab_map(p->p_roles.table, policydb_role_cache, p)) 1246 return -1; 1247 1248 if (hashtab_map(p->p_users.table, policydb_user_cache, p)) 1249 return -1; 1250 1251 return 0; 1252 } 1253 1254 /* 1255 * The following *_destroy functions are used to 1256 * free any memory allocated for each kind of 1257 * symbol data in the policy database. 1258 */ 1259 1260 static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1261 __attribute__ ((unused))) 1262 { 1263 if (key) 1264 free(key); 1265 free(datum); 1266 return 0; 1267 } 1268 1269 static int common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1270 __attribute__ ((unused))) 1271 { 1272 common_datum_t *comdatum; 1273 1274 if (key) 1275 free(key); 1276 comdatum = (common_datum_t *) datum; 1277 (void)hashtab_map(comdatum->permissions.table, perm_destroy, 0); 1278 hashtab_destroy(comdatum->permissions.table); 1279 free(datum); 1280 return 0; 1281 } 1282 1283 static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1284 __attribute__ ((unused))) 1285 { 1286 class_datum_t *cladatum; 1287 constraint_node_t *constraint, *ctemp; 1288 constraint_expr_t *e, *etmp; 1289 1290 if (key) 1291 free(key); 1292 cladatum = (class_datum_t *) datum; 1293 if (cladatum == NULL) { 1294 return 0; 1295 } 1296 (void)hashtab_map(cladatum->permissions.table, perm_destroy, 0); 1297 hashtab_destroy(cladatum->permissions.table); 1298 constraint = cladatum->constraints; 1299 while (constraint) { 1300 e = constraint->expr; 1301 while (e) { 1302 etmp = e; 1303 e = e->next; 1304 constraint_expr_destroy(etmp); 1305 } 1306 ctemp = constraint; 1307 constraint = constraint->next; 1308 free(ctemp); 1309 } 1310 1311 constraint = cladatum->validatetrans; 1312 while (constraint) { 1313 e = constraint->expr; 1314 while (e) { 1315 etmp = e; 1316 e = e->next; 1317 constraint_expr_destroy(etmp); 1318 } 1319 ctemp = constraint; 1320 constraint = constraint->next; 1321 free(ctemp); 1322 } 1323 1324 if (cladatum->comkey) 1325 free(cladatum->comkey); 1326 free(datum); 1327 return 0; 1328 } 1329 1330 static int role_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1331 __attribute__ ((unused))) 1332 { 1333 free(key); 1334 role_datum_destroy((role_datum_t *) datum); 1335 free(datum); 1336 return 0; 1337 } 1338 1339 static int type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1340 __attribute__ ((unused))) 1341 { 1342 free(key); 1343 type_datum_destroy((type_datum_t *) datum); 1344 free(datum); 1345 return 0; 1346 } 1347 1348 static int user_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1349 __attribute__ ((unused))) 1350 { 1351 free(key); 1352 user_datum_destroy((user_datum_t *) datum); 1353 free(datum); 1354 return 0; 1355 } 1356 1357 static int sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1358 __attribute__ ((unused))) 1359 { 1360 level_datum_t *levdatum; 1361 1362 if (key) 1363 free(key); 1364 levdatum = (level_datum_t *) datum; 1365 mls_level_destroy(levdatum->level); 1366 free(levdatum->level); 1367 level_datum_destroy(levdatum); 1368 free(levdatum); 1369 return 0; 1370 } 1371 1372 static int cat_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1373 __attribute__ ((unused))) 1374 { 1375 if (key) 1376 free(key); 1377 cat_datum_destroy((cat_datum_t *) datum); 1378 free(datum); 1379 return 0; 1380 } 1381 1382 static int (*destroy_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum, 1383 void *datap) = { 1384 common_destroy, class_destroy, role_destroy, type_destroy, user_destroy, 1385 cond_destroy_bool, sens_destroy, cat_destroy,}; 1386 1387 static int filenametr_destroy(hashtab_key_t key, hashtab_datum_t datum, 1388 void *p __attribute__ ((unused))) 1389 { 1390 struct filename_trans *ft = (struct filename_trans *)key; 1391 free(ft->name); 1392 free(key); 1393 free(datum); 1394 return 0; 1395 } 1396 1397 static int range_tr_destroy(hashtab_key_t key, hashtab_datum_t datum, 1398 void *p __attribute__ ((unused))) 1399 { 1400 struct mls_range *rt = (struct mls_range *)datum; 1401 free(key); 1402 ebitmap_destroy(&rt->level[0].cat); 1403 ebitmap_destroy(&rt->level[1].cat); 1404 free(datum); 1405 return 0; 1406 } 1407 1408 void ocontext_selinux_free(ocontext_t **ocontexts) 1409 { 1410 ocontext_t *c, *ctmp; 1411 int i; 1412 1413 for (i = 0; i < OCON_NUM; i++) { 1414 c = ocontexts[i]; 1415 while (c) { 1416 ctmp = c; 1417 c = c->next; 1418 context_destroy(&ctmp->context[0]); 1419 context_destroy(&ctmp->context[1]); 1420 if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF 1421 || i == OCON_FSUSE) 1422 free(ctmp->u.name); 1423 else if (i == OCON_IBENDPORT) 1424 free(ctmp->u.ibendport.dev_name); 1425 free(ctmp); 1426 } 1427 } 1428 } 1429 1430 void ocontext_xen_free(ocontext_t **ocontexts) 1431 { 1432 ocontext_t *c, *ctmp; 1433 int i; 1434 1435 for (i = 0; i < OCON_NUM; i++) { 1436 c = ocontexts[i]; 1437 while (c) { 1438 ctmp = c; 1439 c = c->next; 1440 context_destroy(&ctmp->context[0]); 1441 context_destroy(&ctmp->context[1]); 1442 if (i == OCON_ISID || i == OCON_XEN_DEVICETREE) 1443 free(ctmp->u.name); 1444 free(ctmp); 1445 } 1446 } 1447 } 1448 1449 /* 1450 * Free any memory allocated by a policy database structure. 1451 */ 1452 void policydb_destroy(policydb_t * p) 1453 { 1454 ocontext_t *c, *ctmp; 1455 genfs_t *g, *gtmp; 1456 unsigned int i; 1457 role_allow_t *ra, *lra = NULL; 1458 role_trans_t *tr, *ltr = NULL; 1459 1460 if (!p) 1461 return; 1462 1463 ebitmap_destroy(&p->policycaps); 1464 1465 ebitmap_destroy(&p->permissive_map); 1466 1467 symtabs_destroy(p->symtab); 1468 1469 for (i = 0; i < SYM_NUM; i++) { 1470 if (p->sym_val_to_name[i]) 1471 free(p->sym_val_to_name[i]); 1472 } 1473 1474 if (p->class_val_to_struct) 1475 free(p->class_val_to_struct); 1476 if (p->role_val_to_struct) 1477 free(p->role_val_to_struct); 1478 if (p->user_val_to_struct) 1479 free(p->user_val_to_struct); 1480 if (p->type_val_to_struct) 1481 free(p->type_val_to_struct); 1482 free(p->decl_val_to_struct); 1483 1484 for (i = 0; i < SYM_NUM; i++) { 1485 (void)hashtab_map(p->scope[i].table, scope_destroy, 0); 1486 hashtab_destroy(p->scope[i].table); 1487 } 1488 avrule_block_list_destroy(p->global); 1489 free(p->name); 1490 free(p->version); 1491 1492 avtab_destroy(&p->te_avtab); 1493 1494 if (p->target_platform == SEPOL_TARGET_SELINUX) 1495 ocontext_selinux_free(p->ocontexts); 1496 else if (p->target_platform == SEPOL_TARGET_XEN) 1497 ocontext_xen_free(p->ocontexts); 1498 1499 g = p->genfs; 1500 while (g) { 1501 free(g->fstype); 1502 c = g->head; 1503 while (c) { 1504 ctmp = c; 1505 c = c->next; 1506 context_destroy(&ctmp->context[0]); 1507 free(ctmp->u.name); 1508 free(ctmp); 1509 } 1510 gtmp = g; 1511 g = g->next; 1512 free(gtmp); 1513 } 1514 cond_policydb_destroy(p); 1515 1516 for (tr = p->role_tr; tr; tr = tr->next) { 1517 if (ltr) 1518 free(ltr); 1519 ltr = tr; 1520 } 1521 if (ltr) 1522 free(ltr); 1523 1524 for (ra = p->role_allow; ra; ra = ra->next) { 1525 if (lra) 1526 free(lra); 1527 lra = ra; 1528 } 1529 if (lra) 1530 free(lra); 1531 1532 hashtab_map(p->filename_trans, filenametr_destroy, NULL); 1533 hashtab_destroy(p->filename_trans); 1534 1535 hashtab_map(p->range_tr, range_tr_destroy, NULL); 1536 hashtab_destroy(p->range_tr); 1537 1538 if (p->type_attr_map) { 1539 for (i = 0; i < p->p_types.nprim; i++) { 1540 ebitmap_destroy(&p->type_attr_map[i]); 1541 } 1542 free(p->type_attr_map); 1543 } 1544 1545 if (p->attr_type_map) { 1546 for (i = 0; i < p->p_types.nprim; i++) { 1547 ebitmap_destroy(&p->attr_type_map[i]); 1548 } 1549 free(p->attr_type_map); 1550 } 1551 1552 return; 1553 } 1554 1555 void symtabs_destroy(symtab_t * symtab) 1556 { 1557 int i; 1558 for (i = 0; i < SYM_NUM; i++) { 1559 (void)hashtab_map(symtab[i].table, destroy_f[i], 0); 1560 hashtab_destroy(symtab[i].table); 1561 } 1562 } 1563 1564 int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p 1565 __attribute__ ((unused))) 1566 { 1567 scope_datum_t *cur = (scope_datum_t *) datum; 1568 free(key); 1569 if (cur != NULL) { 1570 free(cur->decl_ids); 1571 } 1572 free(cur); 1573 return 0; 1574 } 1575 1576 hashtab_destroy_func_t get_symtab_destroy_func(int sym_num) 1577 { 1578 if (sym_num < 0 || sym_num >= SYM_NUM) { 1579 return NULL; 1580 } 1581 return (hashtab_destroy_func_t) destroy_f[sym_num]; 1582 } 1583 1584 /* 1585 * Load the initial SIDs specified in a policy database 1586 * structure into a SID table. 1587 */ 1588 int policydb_load_isids(policydb_t * p, sidtab_t * s) 1589 { 1590 ocontext_t *head, *c; 1591 1592 if (sepol_sidtab_init(s)) { 1593 ERR(NULL, "out of memory on SID table init"); 1594 return -1; 1595 } 1596 1597 head = p->ocontexts[OCON_ISID]; 1598 for (c = head; c; c = c->next) { 1599 if (!c->context[0].user) { 1600 ERR(NULL, "SID %s was never defined", c->u.name); 1601 return -1; 1602 } 1603 if (sepol_sidtab_insert(s, c->sid[0], &c->context[0])) { 1604 ERR(NULL, "unable to load initial SID %s", c->u.name); 1605 return -1; 1606 } 1607 } 1608 1609 return 0; 1610 } 1611 1612 /* Declare a symbol for a certain avrule_block context. Insert it 1613 * into a symbol table for a policy. This function will handle 1614 * inserting the appropriate scope information in addition to 1615 * inserting the symbol into the hash table. 1616 * 1617 * arguments: 1618 * policydb_t *pol module policy to modify 1619 * uint32_t sym the symbole table for insertion (SYM_*) 1620 * hashtab_key_t key the key for the symbol - not cloned 1621 * hashtab_datum_t data the data for the symbol - not cloned 1622 * scope scope of this symbol, either SCOPE_REQ or SCOPE_DECL 1623 * avrule_decl_id identifier for this symbol's encapsulating declaration 1624 * value (out) assigned value to the symbol (if value is not NULL) 1625 * 1626 * returns: 1627 * 0 success 1628 * 1 success, but symbol already existed as a requirement 1629 * (datum was not inserted and needs to be free()d) 1630 * -1 general error 1631 * -2 scope conflicted 1632 * -ENOMEM memory error 1633 * error codes from hashtab_insert 1634 */ 1635 int symtab_insert(policydb_t * pol, uint32_t sym, 1636 hashtab_key_t key, hashtab_datum_t datum, 1637 uint32_t scope, uint32_t avrule_decl_id, uint32_t * value) 1638 { 1639 int rc, retval = 0; 1640 unsigned int i; 1641 scope_datum_t *scope_datum; 1642 1643 /* check if the symbol is already there. multiple 1644 * declarations of non-roles/non-users are illegal, but 1645 * multiple requires are allowed. */ 1646 1647 /* FIX ME - the failures after the hashtab_insert will leave 1648 * the policy in a inconsistent state. */ 1649 rc = hashtab_insert(pol->symtab[sym].table, key, datum); 1650 if (rc == SEPOL_OK) { 1651 /* if no value is passed in the symbol is not primary 1652 * (i.e. aliases) */ 1653 if (value) 1654 *value = ++pol->symtab[sym].nprim; 1655 } else if (rc == SEPOL_EEXIST) { 1656 retval = 1; /* symbol not added -- need to free() later */ 1657 } else { 1658 return rc; 1659 } 1660 1661 /* get existing scope information; if there is not one then 1662 * create it */ 1663 scope_datum = 1664 (scope_datum_t *) hashtab_search(pol->scope[sym].table, key); 1665 if (scope_datum == NULL) { 1666 hashtab_key_t key2 = strdup((char *)key); 1667 if (!key2) 1668 return -ENOMEM; 1669 if ((scope_datum = malloc(sizeof(*scope_datum))) == NULL) { 1670 free(key2); 1671 return -ENOMEM; 1672 } 1673 scope_datum->scope = scope; 1674 scope_datum->decl_ids = NULL; 1675 scope_datum->decl_ids_len = 0; 1676 if ((rc = 1677 hashtab_insert(pol->scope[sym].table, key2, 1678 scope_datum)) != 0) { 1679 free(key2); 1680 free(scope_datum); 1681 return rc; 1682 } 1683 } else if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_DECL) { 1684 /* disallow multiple declarations for non-roles/users */ 1685 if (sym != SYM_ROLES && sym != SYM_USERS) { 1686 return -2; 1687 } 1688 /* Further confine that a role attribute can't have the same 1689 * name as another regular role, and a role attribute can't 1690 * be declared more than once. */ 1691 if (sym == SYM_ROLES) { 1692 role_datum_t *base_role; 1693 role_datum_t *cur_role = (role_datum_t *)datum; 1694 1695 base_role = (role_datum_t *) 1696 hashtab_search(pol->symtab[sym].table, 1697 key); 1698 assert(base_role != NULL); 1699 1700 if (!((base_role->flavor == ROLE_ROLE) && 1701 (cur_role->flavor == ROLE_ROLE))) { 1702 /* Only regular roles are allowed to have 1703 * multiple declarations. */ 1704 return -2; 1705 } 1706 } 1707 } else if (scope_datum->scope == SCOPE_REQ && scope == SCOPE_DECL) { 1708 scope_datum->scope = SCOPE_DECL; 1709 } 1710 1711 /* search through the pre-existing list to avoid adding duplicates */ 1712 for (i = 0; i < scope_datum->decl_ids_len; i++) { 1713 if (scope_datum->decl_ids[i] == avrule_decl_id) { 1714 /* already there, so don't modify its scope */ 1715 return retval; 1716 } 1717 } 1718 1719 if (add_i_to_a(avrule_decl_id, 1720 &scope_datum->decl_ids_len, 1721 &scope_datum->decl_ids) == -1) { 1722 return -ENOMEM; 1723 } 1724 1725 if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_REQ) { 1726 /* Need to keep the decl at the end of the list */ 1727 uint32_t len, tmp; 1728 len = scope_datum->decl_ids_len; 1729 if (len < 2) { 1730 /* This should be impossible here */ 1731 return -1; 1732 } 1733 tmp = scope_datum->decl_ids[len-2]; 1734 scope_datum->decl_ids[len-2] = scope_datum->decl_ids[len-1]; 1735 scope_datum->decl_ids[len-1] = tmp; 1736 } 1737 1738 return retval; 1739 } 1740 1741 int type_set_or(type_set_t * dst, type_set_t * a, type_set_t * b) 1742 { 1743 type_set_init(dst); 1744 1745 if (ebitmap_or(&dst->types, &a->types, &b->types)) { 1746 return -1; 1747 } 1748 if (ebitmap_or(&dst->negset, &a->negset, &b->negset)) { 1749 return -1; 1750 } 1751 1752 dst->flags |= a->flags; 1753 dst->flags |= b->flags; 1754 1755 return 0; 1756 } 1757 1758 int type_set_cpy(type_set_t * dst, type_set_t * src) 1759 { 1760 type_set_init(dst); 1761 1762 dst->flags = src->flags; 1763 if (ebitmap_cpy(&dst->types, &src->types)) 1764 return -1; 1765 if (ebitmap_cpy(&dst->negset, &src->negset)) 1766 return -1; 1767 1768 return 0; 1769 } 1770 1771 int type_set_or_eq(type_set_t * dst, type_set_t * other) 1772 { 1773 int ret; 1774 type_set_t tmp; 1775 1776 if (type_set_or(&tmp, dst, other)) 1777 return -1; 1778 type_set_destroy(dst); 1779 ret = type_set_cpy(dst, &tmp); 1780 type_set_destroy(&tmp); 1781 1782 return ret; 1783 } 1784 1785 int role_set_get_role(role_set_t * x, uint32_t role) 1786 { 1787 if (x->flags & ROLE_STAR) 1788 return 1; 1789 1790 if (ebitmap_get_bit(&x->roles, role - 1)) { 1791 if (x->flags & ROLE_COMP) 1792 return 0; 1793 else 1794 return 1; 1795 } else { 1796 if (x->flags & ROLE_COMP) 1797 return 1; 1798 else 1799 return 0; 1800 } 1801 } 1802 1803 /***********************************************************************/ 1804 /* everything below is for policy reads */ 1805 1806 /* The following are read functions for module structures */ 1807 1808 static int role_set_read(role_set_t * r, struct policy_file *fp) 1809 { 1810 uint32_t buf[1]; 1811 int rc; 1812 1813 if (ebitmap_read(&r->roles, fp)) 1814 return -1; 1815 rc = next_entry(buf, fp, sizeof(uint32_t)); 1816 if (rc < 0) 1817 return -1; 1818 r->flags = le32_to_cpu(buf[0]); 1819 1820 return 0; 1821 } 1822 1823 static int type_set_read(type_set_t * t, struct policy_file *fp) 1824 { 1825 uint32_t buf[1]; 1826 int rc; 1827 1828 if (ebitmap_read(&t->types, fp)) 1829 return -1; 1830 if (ebitmap_read(&t->negset, fp)) 1831 return -1; 1832 1833 rc = next_entry(buf, fp, sizeof(uint32_t)); 1834 if (rc < 0) 1835 return -1; 1836 t->flags = le32_to_cpu(buf[0]); 1837 1838 return 0; 1839 } 1840 1841 /* 1842 * Read a MLS range structure from a policydb binary 1843 * representation file. 1844 */ 1845 static int mls_read_range_helper(mls_range_t * r, struct policy_file *fp) 1846 { 1847 uint32_t buf[2], items; 1848 int rc; 1849 1850 rc = next_entry(buf, fp, sizeof(uint32_t)); 1851 if (rc < 0) 1852 goto out; 1853 1854 items = le32_to_cpu(buf[0]); 1855 if (items > ARRAY_SIZE(buf)) { 1856 ERR(fp->handle, "range overflow"); 1857 rc = -EINVAL; 1858 goto out; 1859 } 1860 rc = next_entry(buf, fp, sizeof(uint32_t) * items); 1861 if (rc < 0) { 1862 ERR(fp->handle, "truncated range"); 1863 goto out; 1864 } 1865 r->level[0].sens = le32_to_cpu(buf[0]); 1866 if (items > 1) 1867 r->level[1].sens = le32_to_cpu(buf[1]); 1868 else 1869 r->level[1].sens = r->level[0].sens; 1870 1871 rc = ebitmap_read(&r->level[0].cat, fp); 1872 if (rc) { 1873 ERR(fp->handle, "error reading low categories"); 1874 goto out; 1875 } 1876 if (items > 1) { 1877 rc = ebitmap_read(&r->level[1].cat, fp); 1878 if (rc) { 1879 ERR(fp->handle, "error reading high categories"); 1880 goto bad_high; 1881 } 1882 } else { 1883 rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat); 1884 if (rc) { 1885 ERR(fp->handle, "out of memory"); 1886 goto bad_high; 1887 } 1888 } 1889 1890 rc = 0; 1891 out: 1892 return rc; 1893 bad_high: 1894 ebitmap_destroy(&r->level[0].cat); 1895 goto out; 1896 } 1897 1898 /* 1899 * Read a semantic MLS level structure from a policydb binary 1900 * representation file. 1901 */ 1902 static int mls_read_semantic_level_helper(mls_semantic_level_t * l, 1903 struct policy_file *fp) 1904 { 1905 uint32_t buf[2], ncat; 1906 unsigned int i; 1907 mls_semantic_cat_t *cat; 1908 int rc; 1909 1910 mls_semantic_level_init(l); 1911 1912 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 1913 if (rc < 0) { 1914 ERR(fp->handle, "truncated level"); 1915 goto bad; 1916 } 1917 l->sens = le32_to_cpu(buf[0]); 1918 1919 ncat = le32_to_cpu(buf[1]); 1920 for (i = 0; i < ncat; i++) { 1921 cat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t)); 1922 if (!cat) { 1923 ERR(fp->handle, "out of memory"); 1924 goto bad; 1925 } 1926 1927 mls_semantic_cat_init(cat); 1928 cat->next = l->cat; 1929 l->cat = cat; 1930 1931 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 1932 if (rc < 0) { 1933 ERR(fp->handle, "error reading level categories"); 1934 goto bad; 1935 } 1936 cat->low = le32_to_cpu(buf[0]); 1937 cat->high = le32_to_cpu(buf[1]); 1938 } 1939 1940 return 0; 1941 1942 bad: 1943 return -EINVAL; 1944 } 1945 1946 /* 1947 * Read a semantic MLS range structure from a policydb binary 1948 * representation file. 1949 */ 1950 static int mls_read_semantic_range_helper(mls_semantic_range_t * r, 1951 struct policy_file *fp) 1952 { 1953 int rc; 1954 1955 rc = mls_read_semantic_level_helper(&r->level[0], fp); 1956 if (rc) 1957 return rc; 1958 1959 rc = mls_read_semantic_level_helper(&r->level[1], fp); 1960 1961 return rc; 1962 } 1963 1964 static int mls_level_to_semantic(mls_level_t * l, mls_semantic_level_t * sl) 1965 { 1966 unsigned int i; 1967 ebitmap_node_t *cnode; 1968 mls_semantic_cat_t *open_cat = NULL; 1969 1970 mls_semantic_level_init(sl); 1971 sl->sens = l->sens; 1972 ebitmap_for_each_bit(&l->cat, cnode, i) { 1973 if (ebitmap_node_get_bit(cnode, i)) { 1974 if (open_cat) 1975 continue; 1976 open_cat = (mls_semantic_cat_t *) 1977 malloc(sizeof(mls_semantic_cat_t)); 1978 if (!open_cat) 1979 return -1; 1980 1981 mls_semantic_cat_init(open_cat); 1982 open_cat->low = i + 1; 1983 open_cat->next = sl->cat; 1984 sl->cat = open_cat; 1985 } else { 1986 if (!open_cat) 1987 continue; 1988 open_cat->high = i; 1989 open_cat = NULL; 1990 } 1991 } 1992 if (open_cat) 1993 open_cat->high = i; 1994 1995 return 0; 1996 } 1997 1998 static int mls_range_to_semantic(mls_range_t * r, mls_semantic_range_t * sr) 1999 { 2000 if (mls_level_to_semantic(&r->level[0], &sr->level[0])) 2001 return -1; 2002 2003 if (mls_level_to_semantic(&r->level[1], &sr->level[1])) 2004 return -1; 2005 2006 return 0; 2007 } 2008 2009 /* 2010 * Read and validate a security context structure 2011 * from a policydb binary representation file. 2012 */ 2013 static int context_read_and_validate(context_struct_t * c, 2014 policydb_t * p, struct policy_file *fp) 2015 { 2016 uint32_t buf[3]; 2017 int rc; 2018 2019 rc = next_entry(buf, fp, sizeof(uint32_t) * 3); 2020 if (rc < 0) { 2021 ERR(fp->handle, "context truncated"); 2022 return -1; 2023 } 2024 c->user = le32_to_cpu(buf[0]); 2025 c->role = le32_to_cpu(buf[1]); 2026 c->type = le32_to_cpu(buf[2]); 2027 if ((p->policy_type == POLICY_KERN 2028 && p->policyvers >= POLICYDB_VERSION_MLS) 2029 || (p->policy_type == POLICY_BASE 2030 && p->policyvers >= MOD_POLICYDB_VERSION_MLS)) { 2031 if (mls_read_range_helper(&c->range, fp)) { 2032 ERR(fp->handle, "error reading MLS range " 2033 "of context"); 2034 return -1; 2035 } 2036 } 2037 2038 if (!policydb_context_isvalid(p, c)) { 2039 ERR(fp->handle, "invalid security context"); 2040 context_destroy(c); 2041 return -1; 2042 } 2043 return 0; 2044 } 2045 2046 /* 2047 * The following *_read functions are used to 2048 * read the symbol data from a policy database 2049 * binary representation file. 2050 */ 2051 2052 static int perm_read(policydb_t * p 2053 __attribute__ ((unused)), hashtab_t h, 2054 struct policy_file *fp) 2055 { 2056 char *key = 0; 2057 perm_datum_t *perdatum; 2058 uint32_t buf[2]; 2059 size_t len; 2060 int rc; 2061 2062 perdatum = calloc(1, sizeof(perm_datum_t)); 2063 if (!perdatum) 2064 return -1; 2065 2066 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2067 if (rc < 0) 2068 goto bad; 2069 2070 len = le32_to_cpu(buf[0]); 2071 if(str_read(&key, fp, len)) 2072 goto bad; 2073 2074 perdatum->s.value = le32_to_cpu(buf[1]); 2075 2076 if (hashtab_insert(h, key, perdatum)) 2077 goto bad; 2078 2079 return 0; 2080 2081 bad: 2082 perm_destroy(key, perdatum, NULL); 2083 return -1; 2084 } 2085 2086 static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp) 2087 { 2088 char *key = 0; 2089 common_datum_t *comdatum; 2090 uint32_t buf[4]; 2091 size_t len, nel; 2092 unsigned int i; 2093 int rc; 2094 2095 comdatum = calloc(1, sizeof(common_datum_t)); 2096 if (!comdatum) 2097 return -1; 2098 2099 rc = next_entry(buf, fp, sizeof(uint32_t) * 4); 2100 if (rc < 0) 2101 goto bad; 2102 2103 len = le32_to_cpu(buf[0]); 2104 if (zero_or_saturated(len)) 2105 goto bad; 2106 2107 comdatum->s.value = le32_to_cpu(buf[1]); 2108 2109 if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) 2110 goto bad; 2111 comdatum->permissions.nprim = le32_to_cpu(buf[2]); 2112 nel = le32_to_cpu(buf[3]); 2113 2114 key = malloc(len + 1); 2115 if (!key) 2116 goto bad; 2117 rc = next_entry(key, fp, len); 2118 if (rc < 0) 2119 goto bad; 2120 key[len] = 0; 2121 2122 for (i = 0; i < nel; i++) { 2123 if (perm_read(p, comdatum->permissions.table, fp)) 2124 goto bad; 2125 } 2126 2127 if (hashtab_insert(h, key, comdatum)) 2128 goto bad; 2129 2130 return 0; 2131 2132 bad: 2133 common_destroy(key, comdatum, NULL); 2134 return -1; 2135 } 2136 2137 static int read_cons_helper(policydb_t * p, constraint_node_t ** nodep, 2138 unsigned int ncons, 2139 int allowxtarget, struct policy_file *fp) 2140 { 2141 constraint_node_t *c, *lc; 2142 constraint_expr_t *e, *le; 2143 uint32_t buf[3]; 2144 size_t nexpr; 2145 unsigned int i, j; 2146 int rc, depth; 2147 2148 lc = NULL; 2149 for (i = 0; i < ncons; i++) { 2150 c = calloc(1, sizeof(constraint_node_t)); 2151 if (!c) 2152 return -1; 2153 2154 if (lc) 2155 lc->next = c; 2156 else 2157 *nodep = c; 2158 2159 rc = next_entry(buf, fp, (sizeof(uint32_t) * 2)); 2160 if (rc < 0) 2161 return -1; 2162 c->permissions = le32_to_cpu(buf[0]); 2163 nexpr = le32_to_cpu(buf[1]); 2164 le = NULL; 2165 depth = -1; 2166 for (j = 0; j < nexpr; j++) { 2167 e = malloc(sizeof(constraint_expr_t)); 2168 if (!e) 2169 return -1; 2170 if (constraint_expr_init(e) == -1) { 2171 free(e); 2172 return -1; 2173 } 2174 if (le) { 2175 le->next = e; 2176 } else { 2177 c->expr = e; 2178 } 2179 2180 rc = next_entry(buf, fp, (sizeof(uint32_t) * 3)); 2181 if (rc < 0) 2182 return -1; 2183 e->expr_type = le32_to_cpu(buf[0]); 2184 e->attr = le32_to_cpu(buf[1]); 2185 e->op = le32_to_cpu(buf[2]); 2186 2187 switch (e->expr_type) { 2188 case CEXPR_NOT: 2189 if (depth < 0) 2190 return -1; 2191 break; 2192 case CEXPR_AND: 2193 case CEXPR_OR: 2194 if (depth < 1) 2195 return -1; 2196 depth--; 2197 break; 2198 case CEXPR_ATTR: 2199 if (depth == (CEXPR_MAXDEPTH - 1)) 2200 return -1; 2201 depth++; 2202 break; 2203 case CEXPR_NAMES: 2204 if (!allowxtarget && (e->attr & CEXPR_XTARGET)) 2205 return -1; 2206 if (depth == (CEXPR_MAXDEPTH - 1)) 2207 return -1; 2208 depth++; 2209 if (ebitmap_read(&e->names, fp)) 2210 return -1; 2211 if (p->policy_type != POLICY_KERN && 2212 type_set_read(e->type_names, fp)) 2213 return -1; 2214 else if (p->policy_type == POLICY_KERN && 2215 p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES && 2216 type_set_read(e->type_names, fp)) 2217 return -1; 2218 break; 2219 default: 2220 return -1; 2221 } 2222 le = e; 2223 } 2224 if (depth != 0) 2225 return -1; 2226 lc = c; 2227 } 2228 2229 return 0; 2230 } 2231 2232 static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp) 2233 { 2234 char *key = 0; 2235 class_datum_t *cladatum; 2236 uint32_t buf[6]; 2237 size_t len, len2, ncons, nel; 2238 unsigned int i; 2239 int rc; 2240 2241 cladatum = (class_datum_t *) calloc(1, sizeof(class_datum_t)); 2242 if (!cladatum) 2243 return -1; 2244 2245 rc = next_entry(buf, fp, sizeof(uint32_t) * 6); 2246 if (rc < 0) 2247 goto bad; 2248 2249 len = le32_to_cpu(buf[0]); 2250 if (zero_or_saturated(len)) 2251 goto bad; 2252 len2 = le32_to_cpu(buf[1]); 2253 if (is_saturated(len2)) 2254 goto bad; 2255 cladatum->s.value = le32_to_cpu(buf[2]); 2256 2257 if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) 2258 goto bad; 2259 cladatum->permissions.nprim = le32_to_cpu(buf[3]); 2260 nel = le32_to_cpu(buf[4]); 2261 2262 ncons = le32_to_cpu(buf[5]); 2263 2264 key = malloc(len + 1); 2265 if (!key) 2266 goto bad; 2267 rc = next_entry(key, fp, len); 2268 if (rc < 0) 2269 goto bad; 2270 key[len] = 0; 2271 2272 if (len2) { 2273 cladatum->comkey = malloc(len2 + 1); 2274 if (!cladatum->comkey) 2275 goto bad; 2276 rc = next_entry(cladatum->comkey, fp, len2); 2277 if (rc < 0) 2278 goto bad; 2279 cladatum->comkey[len2] = 0; 2280 2281 cladatum->comdatum = hashtab_search(p->p_commons.table, 2282 cladatum->comkey); 2283 if (!cladatum->comdatum) { 2284 ERR(fp->handle, "unknown common %s", cladatum->comkey); 2285 goto bad; 2286 } 2287 } 2288 for (i = 0; i < nel; i++) { 2289 if (perm_read(p, cladatum->permissions.table, fp)) 2290 goto bad; 2291 } 2292 2293 if (read_cons_helper(p, &cladatum->constraints, ncons, 0, fp)) 2294 goto bad; 2295 2296 if ((p->policy_type == POLICY_KERN 2297 && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) 2298 || (p->policy_type == POLICY_BASE 2299 && p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) { 2300 /* grab the validatetrans rules */ 2301 rc = next_entry(buf, fp, sizeof(uint32_t)); 2302 if (rc < 0) 2303 goto bad; 2304 ncons = le32_to_cpu(buf[0]); 2305 if (read_cons_helper(p, &cladatum->validatetrans, ncons, 1, fp)) 2306 goto bad; 2307 } 2308 2309 if ((p->policy_type == POLICY_KERN && 2310 p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) || 2311 (p->policy_type == POLICY_BASE && 2312 p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) { 2313 rc = next_entry(buf, fp, sizeof(uint32_t) * 3); 2314 if (rc < 0) 2315 goto bad; 2316 cladatum->default_user = le32_to_cpu(buf[0]); 2317 cladatum->default_role = le32_to_cpu(buf[1]); 2318 cladatum->default_range = le32_to_cpu(buf[2]); 2319 } 2320 2321 if ((p->policy_type == POLICY_KERN && 2322 p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) || 2323 (p->policy_type == POLICY_BASE && 2324 p->policyvers >= MOD_POLICYDB_VERSION_DEFAULT_TYPE)) { 2325 rc = next_entry(buf, fp, sizeof(uint32_t)); 2326 if (rc < 0) 2327 goto bad; 2328 cladatum->default_type = le32_to_cpu(buf[0]); 2329 } 2330 2331 if (hashtab_insert(h, key, cladatum)) 2332 goto bad; 2333 2334 return 0; 2335 2336 bad: 2337 class_destroy(key, cladatum, NULL); 2338 return -1; 2339 } 2340 2341 static int role_read(policydb_t * p, hashtab_t h, struct policy_file *fp) 2342 { 2343 char *key = 0; 2344 role_datum_t *role; 2345 uint32_t buf[3]; 2346 size_t len; 2347 int rc, to_read = 2; 2348 2349 role = calloc(1, sizeof(role_datum_t)); 2350 if (!role) 2351 return -1; 2352 2353 if (policydb_has_boundary_feature(p)) 2354 to_read = 3; 2355 2356 rc = next_entry(buf, fp, sizeof(uint32_t) * to_read); 2357 if (rc < 0) 2358 goto bad; 2359 2360 len = le32_to_cpu(buf[0]); 2361 if (zero_or_saturated(len)) 2362 goto bad; 2363 2364 role->s.value = le32_to_cpu(buf[1]); 2365 if (policydb_has_boundary_feature(p)) 2366 role->bounds = le32_to_cpu(buf[2]); 2367 2368 key = malloc(len + 1); 2369 if (!key) 2370 goto bad; 2371 rc = next_entry(key, fp, len); 2372 if (rc < 0) 2373 goto bad; 2374 key[len] = 0; 2375 2376 if (ebitmap_read(&role->dominates, fp)) 2377 goto bad; 2378 2379 if (p->policy_type == POLICY_KERN) { 2380 if (ebitmap_read(&role->types.types, fp)) 2381 goto bad; 2382 } else { 2383 if (type_set_read(&role->types, fp)) 2384 goto bad; 2385 } 2386 2387 if (p->policy_type != POLICY_KERN && 2388 p->policyvers >= MOD_POLICYDB_VERSION_ROLEATTRIB) { 2389 rc = next_entry(buf, fp, sizeof(uint32_t)); 2390 if (rc < 0) 2391 goto bad; 2392 2393 role->flavor = le32_to_cpu(buf[0]); 2394 2395 if (ebitmap_read(&role->roles, fp)) 2396 goto bad; 2397 } 2398 2399 if (strcmp(key, OBJECT_R) == 0) { 2400 if (role->s.value != OBJECT_R_VAL) { 2401 ERR(fp->handle, "role %s has wrong value %d", 2402 OBJECT_R, role->s.value); 2403 role_destroy(key, role, NULL); 2404 return -1; 2405 } 2406 role_destroy(key, role, NULL); 2407 return 0; 2408 } 2409 2410 if (hashtab_insert(h, key, role)) 2411 goto bad; 2412 2413 return 0; 2414 2415 bad: 2416 role_destroy(key, role, NULL); 2417 return -1; 2418 } 2419 2420 static int type_read(policydb_t * p, hashtab_t h, struct policy_file *fp) 2421 { 2422 char *key = 0; 2423 type_datum_t *typdatum; 2424 uint32_t buf[5]; 2425 size_t len; 2426 int rc, to_read; 2427 int pos = 0; 2428 2429 typdatum = calloc(1, sizeof(type_datum_t)); 2430 if (!typdatum) 2431 return -1; 2432 2433 if (policydb_has_boundary_feature(p)) { 2434 if (p->policy_type != POLICY_KERN 2435 && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) 2436 to_read = 5; 2437 else 2438 to_read = 4; 2439 } 2440 else if (p->policy_type == POLICY_KERN) 2441 to_read = 3; 2442 else if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE) 2443 to_read = 5; 2444 else 2445 to_read = 4; 2446 2447 rc = next_entry(buf, fp, sizeof(uint32_t) * to_read); 2448 if (rc < 0) 2449 goto bad; 2450 2451 len = le32_to_cpu(buf[pos]); 2452 if (zero_or_saturated(len)) 2453 goto bad; 2454 2455 typdatum->s.value = le32_to_cpu(buf[++pos]); 2456 if (policydb_has_boundary_feature(p)) { 2457 uint32_t properties; 2458 2459 if (p->policy_type != POLICY_KERN 2460 && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) { 2461 typdatum->primary = le32_to_cpu(buf[++pos]); 2462 properties = le32_to_cpu(buf[++pos]); 2463 } 2464 else { 2465 properties = le32_to_cpu(buf[++pos]); 2466 2467 if (properties & TYPEDATUM_PROPERTY_PRIMARY) 2468 typdatum->primary = 1; 2469 } 2470 2471 if (properties & TYPEDATUM_PROPERTY_ATTRIBUTE) 2472 typdatum->flavor = TYPE_ATTRIB; 2473 if (properties & TYPEDATUM_PROPERTY_ALIAS 2474 && p->policy_type != POLICY_KERN) 2475 typdatum->flavor = TYPE_ALIAS; 2476 if (properties & TYPEDATUM_PROPERTY_PERMISSIVE 2477 && p->policy_type != POLICY_KERN) 2478 typdatum->flags |= TYPE_FLAGS_PERMISSIVE; 2479 2480 typdatum->bounds = le32_to_cpu(buf[++pos]); 2481 } else { 2482 typdatum->primary = le32_to_cpu(buf[++pos]); 2483 if (p->policy_type != POLICY_KERN) { 2484 typdatum->flavor = le32_to_cpu(buf[++pos]); 2485 if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE) 2486 typdatum->flags = le32_to_cpu(buf[++pos]); 2487 } 2488 } 2489 2490 if (p->policy_type != POLICY_KERN) { 2491 if (ebitmap_read(&typdatum->types, fp)) 2492 goto bad; 2493 } 2494 2495 key = malloc(len + 1); 2496 if (!key) 2497 goto bad; 2498 rc = next_entry(key, fp, len); 2499 if (rc < 0) 2500 goto bad; 2501 key[len] = 0; 2502 2503 if (hashtab_insert(h, key, typdatum)) 2504 goto bad; 2505 2506 return 0; 2507 2508 bad: 2509 type_destroy(key, typdatum, NULL); 2510 return -1; 2511 } 2512 2513 int role_trans_read(policydb_t *p, struct policy_file *fp) 2514 { 2515 role_trans_t **t = &p->role_tr; 2516 unsigned int i; 2517 uint32_t buf[3], nel; 2518 role_trans_t *tr, *ltr; 2519 int rc; 2520 int new_roletr = (p->policy_type == POLICY_KERN && 2521 p->policyvers >= POLICYDB_VERSION_ROLETRANS); 2522 2523 rc = next_entry(buf, fp, sizeof(uint32_t)); 2524 if (rc < 0) 2525 return -1; 2526 nel = le32_to_cpu(buf[0]); 2527 ltr = NULL; 2528 for (i = 0; i < nel; i++) { 2529 tr = calloc(1, sizeof(struct role_trans)); 2530 if (!tr) { 2531 return -1; 2532 } 2533 if (ltr) { 2534 ltr->next = tr; 2535 } else { 2536 *t = tr; 2537 } 2538 rc = next_entry(buf, fp, sizeof(uint32_t) * 3); 2539 if (rc < 0) 2540 return -1; 2541 tr->role = le32_to_cpu(buf[0]); 2542 tr->type = le32_to_cpu(buf[1]); 2543 tr->new_role = le32_to_cpu(buf[2]); 2544 if (new_roletr) { 2545 rc = next_entry(buf, fp, sizeof(uint32_t)); 2546 if (rc < 0) 2547 return -1; 2548 tr->tclass = le32_to_cpu(buf[0]); 2549 } else 2550 tr->tclass = SECCLASS_PROCESS; 2551 ltr = tr; 2552 } 2553 return 0; 2554 } 2555 2556 int role_allow_read(role_allow_t ** r, struct policy_file *fp) 2557 { 2558 unsigned int i; 2559 uint32_t buf[2], nel; 2560 role_allow_t *ra, *lra; 2561 int rc; 2562 2563 rc = next_entry(buf, fp, sizeof(uint32_t)); 2564 if (rc < 0) 2565 return -1; 2566 nel = le32_to_cpu(buf[0]); 2567 lra = NULL; 2568 for (i = 0; i < nel; i++) { 2569 ra = calloc(1, sizeof(struct role_allow)); 2570 if (!ra) { 2571 return -1; 2572 } 2573 if (lra) { 2574 lra->next = ra; 2575 } else { 2576 *r = ra; 2577 } 2578 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2579 if (rc < 0) 2580 return -1; 2581 ra->role = le32_to_cpu(buf[0]); 2582 ra->new_role = le32_to_cpu(buf[1]); 2583 lra = ra; 2584 } 2585 return 0; 2586 } 2587 2588 int filename_trans_read(policydb_t *p, struct policy_file *fp) 2589 { 2590 unsigned int i; 2591 uint32_t buf[4], nel, len; 2592 filename_trans_t *ft; 2593 filename_trans_datum_t *otype; 2594 int rc; 2595 char *name; 2596 2597 rc = next_entry(buf, fp, sizeof(uint32_t)); 2598 if (rc < 0) 2599 return -1; 2600 nel = le32_to_cpu(buf[0]); 2601 2602 for (i = 0; i < nel; i++) { 2603 ft = NULL; 2604 otype = NULL; 2605 name = NULL; 2606 2607 ft = calloc(1, sizeof(*ft)); 2608 if (!ft) 2609 goto err; 2610 otype = calloc(1, sizeof(*otype)); 2611 if (!otype) 2612 goto err; 2613 rc = next_entry(buf, fp, sizeof(uint32_t)); 2614 if (rc < 0) 2615 goto err; 2616 len = le32_to_cpu(buf[0]); 2617 if (zero_or_saturated(len)) 2618 goto err; 2619 2620 name = calloc(len + 1, sizeof(*name)); 2621 if (!name) 2622 goto err; 2623 2624 ft->name = name; 2625 2626 rc = next_entry(name, fp, len); 2627 if (rc < 0) 2628 goto err; 2629 2630 rc = next_entry(buf, fp, sizeof(uint32_t) * 4); 2631 if (rc < 0) 2632 goto err; 2633 2634 ft->stype = le32_to_cpu(buf[0]); 2635 ft->ttype = le32_to_cpu(buf[1]); 2636 ft->tclass = le32_to_cpu(buf[2]); 2637 otype->otype = le32_to_cpu(buf[3]); 2638 2639 rc = hashtab_insert(p->filename_trans, (hashtab_key_t) ft, 2640 otype); 2641 if (rc) { 2642 if (rc != SEPOL_EEXIST) 2643 goto err; 2644 /* 2645 * Some old policies were wrongly generated with 2646 * duplicate filename transition rules. For backward 2647 * compatibility, do not reject such policies, just 2648 * issue a warning and ignore the duplicate. 2649 */ 2650 WARN(fp->handle, 2651 "Duplicate name-based type_transition %s %s:%s \"%s\": %s, ignoring", 2652 p->p_type_val_to_name[ft->stype - 1], 2653 p->p_type_val_to_name[ft->ttype - 1], 2654 p->p_class_val_to_name[ft->tclass - 1], 2655 ft->name, 2656 p->p_type_val_to_name[otype->otype - 1]); 2657 free(ft); 2658 free(name); 2659 free(otype); 2660 /* continue, ignoring this one */ 2661 } 2662 } 2663 return 0; 2664 err: 2665 free(ft); 2666 free(otype); 2667 free(name); 2668 return -1; 2669 } 2670 2671 static int ocontext_read_xen(struct policydb_compat_info *info, 2672 policydb_t *p, struct policy_file *fp) 2673 { 2674 unsigned int i, j; 2675 size_t nel, len; 2676 ocontext_t *l, *c; 2677 uint32_t buf[8]; 2678 int rc; 2679 2680 for (i = 0; i < info->ocon_num; i++) { 2681 rc = next_entry(buf, fp, sizeof(uint32_t)); 2682 if (rc < 0) 2683 return -1; 2684 nel = le32_to_cpu(buf[0]); 2685 l = NULL; 2686 for (j = 0; j < nel; j++) { 2687 c = calloc(1, sizeof(ocontext_t)); 2688 if (!c) 2689 return -1; 2690 if (l) 2691 l->next = c; 2692 else 2693 p->ocontexts[i] = c; 2694 l = c; 2695 switch (i) { 2696 case OCON_XEN_ISID: 2697 rc = next_entry(buf, fp, sizeof(uint32_t)); 2698 if (rc < 0) 2699 return -1; 2700 c->sid[0] = le32_to_cpu(buf[0]); 2701 if (context_read_and_validate 2702 (&c->context[0], p, fp)) 2703 return -1; 2704 break; 2705 case OCON_XEN_PIRQ: 2706 rc = next_entry(buf, fp, sizeof(uint32_t)); 2707 if (rc < 0) 2708 return -1; 2709 c->u.pirq = le32_to_cpu(buf[0]); 2710 if (context_read_and_validate 2711 (&c->context[0], p, fp)) 2712 return -1; 2713 break; 2714 case OCON_XEN_IOPORT: 2715 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2716 if (rc < 0) 2717 return -1; 2718 c->u.ioport.low_ioport = le32_to_cpu(buf[0]); 2719 c->u.ioport.high_ioport = le32_to_cpu(buf[1]); 2720 if (context_read_and_validate 2721 (&c->context[0], p, fp)) 2722 return -1; 2723 break; 2724 case OCON_XEN_IOMEM: 2725 if (p->policyvers >= POLICYDB_VERSION_XEN_DEVICETREE) { 2726 uint64_t b64[2]; 2727 rc = next_entry(b64, fp, sizeof(uint64_t) * 2); 2728 if (rc < 0) 2729 return -1; 2730 c->u.iomem.low_iomem = le64_to_cpu(b64[0]); 2731 c->u.iomem.high_iomem = le64_to_cpu(b64[1]); 2732 } else { 2733 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2734 if (rc < 0) 2735 return -1; 2736 c->u.iomem.low_iomem = le32_to_cpu(buf[0]); 2737 c->u.iomem.high_iomem = le32_to_cpu(buf[1]); 2738 } 2739 if (context_read_and_validate 2740 (&c->context[0], p, fp)) 2741 return -1; 2742 break; 2743 case OCON_XEN_PCIDEVICE: 2744 rc = next_entry(buf, fp, sizeof(uint32_t)); 2745 if (rc < 0) 2746 return -1; 2747 c->u.device = le32_to_cpu(buf[0]); 2748 if (context_read_and_validate 2749 (&c->context[0], p, fp)) 2750 return -1; 2751 break; 2752 case OCON_XEN_DEVICETREE: 2753 rc = next_entry(buf, fp, sizeof(uint32_t)); 2754 if (rc < 0) 2755 return -1; 2756 len = le32_to_cpu(buf[0]); 2757 if (zero_or_saturated(len)) 2758 return -1; 2759 2760 c->u.name = malloc(len + 1); 2761 if (!c->u.name) 2762 return -1; 2763 rc = next_entry(c->u.name, fp, len); 2764 if (rc < 0) 2765 return -1; 2766 c->u.name[len] = 0; 2767 if (context_read_and_validate 2768 (&c->context[0], p, fp)) 2769 return -1; 2770 break; 2771 default: 2772 /* should never get here */ 2773 ERR(fp->handle, "Unknown Xen ocontext"); 2774 return -1; 2775 } 2776 } 2777 } 2778 return 0; 2779 } 2780 static int ocontext_read_selinux(struct policydb_compat_info *info, 2781 policydb_t * p, struct policy_file *fp) 2782 { 2783 unsigned int i, j; 2784 size_t nel, len; 2785 ocontext_t *l, *c; 2786 uint32_t buf[8]; 2787 int rc; 2788 2789 for (i = 0; i < info->ocon_num; i++) { 2790 rc = next_entry(buf, fp, sizeof(uint32_t)); 2791 if (rc < 0) 2792 return -1; 2793 nel = le32_to_cpu(buf[0]); 2794 l = NULL; 2795 for (j = 0; j < nel; j++) { 2796 c = calloc(1, sizeof(ocontext_t)); 2797 if (!c) { 2798 return -1; 2799 } 2800 if (l) { 2801 l->next = c; 2802 } else { 2803 p->ocontexts[i] = c; 2804 } 2805 l = c; 2806 switch (i) { 2807 case OCON_ISID: 2808 rc = next_entry(buf, fp, sizeof(uint32_t)); 2809 if (rc < 0) 2810 return -1; 2811 c->sid[0] = le32_to_cpu(buf[0]); 2812 if (context_read_and_validate 2813 (&c->context[0], p, fp)) 2814 return -1; 2815 break; 2816 case OCON_FS: 2817 case OCON_NETIF: 2818 rc = next_entry(buf, fp, sizeof(uint32_t)); 2819 if (rc < 0) 2820 return -1; 2821 len = le32_to_cpu(buf[0]); 2822 if (zero_or_saturated(len) || len > 63) 2823 return -1; 2824 c->u.name = malloc(len + 1); 2825 if (!c->u.name) 2826 return -1; 2827 rc = next_entry(c->u.name, fp, len); 2828 if (rc < 0) 2829 return -1; 2830 c->u.name[len] = 0; 2831 if (context_read_and_validate 2832 (&c->context[0], p, fp)) 2833 return -1; 2834 if (context_read_and_validate 2835 (&c->context[1], p, fp)) 2836 return -1; 2837 break; 2838 case OCON_IBPKEY: 2839 rc = next_entry(buf, fp, sizeof(uint32_t) * 4); 2840 if (rc < 0 || buf[2] > 0xffff || buf[3] > 0xffff) 2841 return -1; 2842 2843 memcpy(&c->u.ibpkey.subnet_prefix, buf, 2844 sizeof(c->u.ibpkey.subnet_prefix)); 2845 2846 c->u.ibpkey.low_pkey = le32_to_cpu(buf[2]); 2847 c->u.ibpkey.high_pkey = le32_to_cpu(buf[3]); 2848 2849 if (context_read_and_validate 2850 (&c->context[0], p, fp)) 2851 return -1; 2852 break; 2853 case OCON_IBENDPORT: 2854 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2855 if (rc < 0) 2856 return -1; 2857 len = le32_to_cpu(buf[0]); 2858 if (len == 0 || len > IB_DEVICE_NAME_MAX - 1) 2859 return -1; 2860 2861 c->u.ibendport.dev_name = malloc(len + 1); 2862 if (!c->u.ibendport.dev_name) 2863 return -1; 2864 rc = next_entry(c->u.ibendport.dev_name, fp, len); 2865 if (rc < 0) 2866 return -1; 2867 c->u.ibendport.dev_name[len] = 0; 2868 c->u.ibendport.port = le32_to_cpu(buf[1]); 2869 if (context_read_and_validate 2870 (&c->context[0], p, fp)) 2871 return -1; 2872 break; 2873 case OCON_PORT: 2874 rc = next_entry(buf, fp, sizeof(uint32_t) * 3); 2875 if (rc < 0) 2876 return -1; 2877 c->u.port.protocol = le32_to_cpu(buf[0]); 2878 c->u.port.low_port = le32_to_cpu(buf[1]); 2879 c->u.port.high_port = le32_to_cpu(buf[2]); 2880 if (context_read_and_validate 2881 (&c->context[0], p, fp)) 2882 return -1; 2883 break; 2884 case OCON_NODE: 2885 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2886 if (rc < 0) 2887 return -1; 2888 c->u.node.addr = buf[0]; /* network order */ 2889 c->u.node.mask = buf[1]; /* network order */ 2890 if (context_read_and_validate 2891 (&c->context[0], p, fp)) 2892 return -1; 2893 break; 2894 case OCON_FSUSE: 2895 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 2896 if (rc < 0) 2897 return -1; 2898 c->v.behavior = le32_to_cpu(buf[0]); 2899 len = le32_to_cpu(buf[1]); 2900 if (zero_or_saturated(len)) 2901 return -1; 2902 c->u.name = malloc(len + 1); 2903 if (!c->u.name) 2904 return -1; 2905 rc = next_entry(c->u.name, fp, len); 2906 if (rc < 0) 2907 return -1; 2908 c->u.name[len] = 0; 2909 if (context_read_and_validate 2910 (&c->context[0], p, fp)) 2911 return -1; 2912 break; 2913 case OCON_NODE6:{ 2914 int k; 2915 2916 rc = next_entry(buf, fp, sizeof(uint32_t) * 8); 2917 if (rc < 0) 2918 return -1; 2919 for (k = 0; k < 4; k++) 2920 /* network order */ 2921 c->u.node6.addr[k] = buf[k]; 2922 for (k = 0; k < 4; k++) 2923 /* network order */ 2924 c->u.node6.mask[k] = buf[k + 4]; 2925 if (context_read_and_validate 2926 (&c->context[0], p, fp)) 2927 return -1; 2928 break; 2929 } 2930 default:{ 2931 ERR(fp->handle, "Unknown SELinux ocontext"); 2932 return -1; 2933 } 2934 } 2935 } 2936 } 2937 return 0; 2938 } 2939 2940 static int ocontext_read(struct policydb_compat_info *info, 2941 policydb_t *p, struct policy_file *fp) 2942 { 2943 int rc = -1; 2944 switch (p->target_platform) { 2945 case SEPOL_TARGET_SELINUX: 2946 rc = ocontext_read_selinux(info, p, fp); 2947 break; 2948 case SEPOL_TARGET_XEN: 2949 rc = ocontext_read_xen(info, p, fp); 2950 break; 2951 default: 2952 ERR(fp->handle, "Unknown target"); 2953 } 2954 return rc; 2955 } 2956 2957 static int genfs_read(policydb_t * p, struct policy_file *fp) 2958 { 2959 uint32_t buf[1]; 2960 size_t nel, nel2, len, len2; 2961 genfs_t *genfs_p, *newgenfs, *genfs; 2962 size_t i, j; 2963 ocontext_t *l, *c, *newc = NULL; 2964 int rc; 2965 2966 rc = next_entry(buf, fp, sizeof(uint32_t)); 2967 if (rc < 0) 2968 goto bad; 2969 nel = le32_to_cpu(buf[0]); 2970 genfs_p = NULL; 2971 for (i = 0; i < nel; i++) { 2972 rc = next_entry(buf, fp, sizeof(uint32_t)); 2973 if (rc < 0) 2974 goto bad; 2975 len = le32_to_cpu(buf[0]); 2976 if (zero_or_saturated(len)) 2977 goto bad; 2978 newgenfs = calloc(1, sizeof(genfs_t)); 2979 if (!newgenfs) 2980 goto bad; 2981 newgenfs->fstype = malloc(len + 1); 2982 if (!newgenfs->fstype) { 2983 free(newgenfs); 2984 goto bad; 2985 } 2986 rc = next_entry(newgenfs->fstype, fp, len); 2987 if (rc < 0) { 2988 free(newgenfs->fstype); 2989 free(newgenfs); 2990 goto bad; 2991 } 2992 newgenfs->fstype[len] = 0; 2993 for (genfs_p = NULL, genfs = p->genfs; genfs; 2994 genfs_p = genfs, genfs = genfs->next) { 2995 if (strcmp(newgenfs->fstype, genfs->fstype) == 0) { 2996 ERR(fp->handle, "dup genfs fstype %s", 2997 newgenfs->fstype); 2998 free(newgenfs->fstype); 2999 free(newgenfs); 3000 goto bad; 3001 } 3002 if (strcmp(newgenfs->fstype, genfs->fstype) < 0) 3003 break; 3004 } 3005 newgenfs->next = genfs; 3006 if (genfs_p) 3007 genfs_p->next = newgenfs; 3008 else 3009 p->genfs = newgenfs; 3010 rc = next_entry(buf, fp, sizeof(uint32_t)); 3011 if (rc < 0) 3012 goto bad; 3013 nel2 = le32_to_cpu(buf[0]); 3014 for (j = 0; j < nel2; j++) { 3015 newc = calloc(1, sizeof(ocontext_t)); 3016 if (!newc) { 3017 goto bad; 3018 } 3019 rc = next_entry(buf, fp, sizeof(uint32_t)); 3020 if (rc < 0) 3021 goto bad; 3022 len = le32_to_cpu(buf[0]); 3023 if (zero_or_saturated(len)) 3024 goto bad; 3025 newc->u.name = malloc(len + 1); 3026 if (!newc->u.name) { 3027 goto bad; 3028 } 3029 rc = next_entry(newc->u.name, fp, len); 3030 if (rc < 0) 3031 goto bad; 3032 newc->u.name[len] = 0; 3033 rc = next_entry(buf, fp, sizeof(uint32_t)); 3034 if (rc < 0) 3035 goto bad; 3036 newc->v.sclass = le32_to_cpu(buf[0]); 3037 if (context_read_and_validate(&newc->context[0], p, fp)) 3038 goto bad; 3039 for (l = NULL, c = newgenfs->head; c; 3040 l = c, c = c->next) { 3041 if (!strcmp(newc->u.name, c->u.name) && 3042 (!c->v.sclass || !newc->v.sclass || 3043 newc->v.sclass == c->v.sclass)) { 3044 ERR(fp->handle, "dup genfs entry " 3045 "(%s,%s)", newgenfs->fstype, 3046 c->u.name); 3047 goto bad; 3048 } 3049 len = strlen(newc->u.name); 3050 len2 = strlen(c->u.name); 3051 if (len > len2) 3052 break; 3053 } 3054 newc->next = c; 3055 if (l) 3056 l->next = newc; 3057 else 3058 newgenfs->head = newc; 3059 /* clear newc after a new owner has the pointer */ 3060 newc = NULL; 3061 } 3062 } 3063 3064 return 0; 3065 3066 bad: 3067 if (newc) { 3068 context_destroy(&newc->context[0]); 3069 context_destroy(&newc->context[1]); 3070 free(newc->u.name); 3071 free(newc); 3072 } 3073 return -1; 3074 } 3075 3076 /* 3077 * Read a MLS level structure from a policydb binary 3078 * representation file. 3079 */ 3080 static int mls_read_level(mls_level_t * lp, struct policy_file *fp) 3081 { 3082 uint32_t buf[1]; 3083 int rc; 3084 3085 mls_level_init(lp); 3086 3087 rc = next_entry(buf, fp, sizeof(uint32_t)); 3088 if (rc < 0) { 3089 ERR(fp->handle, "truncated level"); 3090 goto bad; 3091 } 3092 lp->sens = le32_to_cpu(buf[0]); 3093 3094 if (ebitmap_read(&lp->cat, fp)) { 3095 ERR(fp->handle, "error reading level categories"); 3096 goto bad; 3097 } 3098 return 0; 3099 3100 bad: 3101 return -EINVAL; 3102 } 3103 3104 static int user_read(policydb_t * p, hashtab_t h, struct policy_file *fp) 3105 { 3106 char *key = 0; 3107 user_datum_t *usrdatum; 3108 uint32_t buf[3]; 3109 size_t len; 3110 int rc, to_read = 2; 3111 3112 usrdatum = calloc(1, sizeof(user_datum_t)); 3113 if (!usrdatum) 3114 return -1; 3115 3116 if (policydb_has_boundary_feature(p)) 3117 to_read = 3; 3118 3119 rc = next_entry(buf, fp, sizeof(uint32_t) * to_read); 3120 if (rc < 0) 3121 goto bad; 3122 3123 len = le32_to_cpu(buf[0]); 3124 if (zero_or_saturated(len)) 3125 goto bad; 3126 3127 usrdatum->s.value = le32_to_cpu(buf[1]); 3128 if (policydb_has_boundary_feature(p)) 3129 usrdatum->bounds = le32_to_cpu(buf[2]); 3130 3131 key = malloc(len + 1); 3132 if (!key) 3133 goto bad; 3134 rc = next_entry(key, fp, len); 3135 if (rc < 0) 3136 goto bad; 3137 key[len] = 0; 3138 3139 if (p->policy_type == POLICY_KERN) { 3140 if (ebitmap_read(&usrdatum->roles.roles, fp)) 3141 goto bad; 3142 } else { 3143 if (role_set_read(&usrdatum->roles, fp)) 3144 goto bad; 3145 } 3146 3147 /* users were not allowed in mls modules before version 3148 * MOD_POLICYDB_VERSION_MLS_USERS, but they could have been 3149 * required - the mls fields will be empty. user declarations in 3150 * non-mls modules will also have empty mls fields */ 3151 if ((p->policy_type == POLICY_KERN 3152 && p->policyvers >= POLICYDB_VERSION_MLS) 3153 || (p->policy_type == POLICY_MOD 3154 && p->policyvers >= MOD_POLICYDB_VERSION_MLS 3155 && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS) 3156 || (p->policy_type == POLICY_BASE 3157 && p->policyvers >= MOD_POLICYDB_VERSION_MLS 3158 && p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)) { 3159 if (mls_read_range_helper(&usrdatum->exp_range, fp)) 3160 goto bad; 3161 if (mls_read_level(&usrdatum->exp_dfltlevel, fp)) 3162 goto bad; 3163 if (p->policy_type != POLICY_KERN) { 3164 if (mls_range_to_semantic(&usrdatum->exp_range, 3165 &usrdatum->range)) 3166 goto bad; 3167 if (mls_level_to_semantic(&usrdatum->exp_dfltlevel, 3168 &usrdatum->dfltlevel)) 3169 goto bad; 3170 } 3171 } else if ((p->policy_type == POLICY_MOD 3172 && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS) 3173 || (p->policy_type == POLICY_BASE 3174 && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)) { 3175 if (mls_read_semantic_range_helper(&usrdatum->range, fp)) 3176 goto bad; 3177 if (mls_read_semantic_level_helper(&usrdatum->dfltlevel, fp)) 3178 goto bad; 3179 } 3180 3181 if (hashtab_insert(h, key, usrdatum)) 3182 goto bad; 3183 3184 return 0; 3185 3186 bad: 3187 user_destroy(key, usrdatum, NULL); 3188 return -1; 3189 } 3190 3191 static int sens_read(policydb_t * p 3192 __attribute__ ((unused)), hashtab_t h, 3193 struct policy_file *fp) 3194 { 3195 char *key = 0; 3196 level_datum_t *levdatum; 3197 uint32_t buf[2], len; 3198 int rc; 3199 3200 levdatum = malloc(sizeof(level_datum_t)); 3201 if (!levdatum) 3202 return -1; 3203 level_datum_init(levdatum); 3204 3205 rc = next_entry(buf, fp, (sizeof(uint32_t) * 2)); 3206 if (rc < 0) 3207 goto bad; 3208 3209 len = le32_to_cpu(buf[0]); 3210 if (zero_or_saturated(len)) 3211 goto bad; 3212 3213 levdatum->isalias = le32_to_cpu(buf[1]); 3214 3215 key = malloc(len + 1); 3216 if (!key) 3217 goto bad; 3218 rc = next_entry(key, fp, len); 3219 if (rc < 0) 3220 goto bad; 3221 key[len] = 0; 3222 3223 levdatum->level = malloc(sizeof(mls_level_t)); 3224 if (!levdatum->level || mls_read_level(levdatum->level, fp)) 3225 goto bad; 3226 3227 if (hashtab_insert(h, key, levdatum)) 3228 goto bad; 3229 3230 return 0; 3231 3232 bad: 3233 sens_destroy(key, levdatum, NULL); 3234 return -1; 3235 } 3236 3237 static int cat_read(policydb_t * p 3238 __attribute__ ((unused)), hashtab_t h, 3239 struct policy_file *fp) 3240 { 3241 char *key = 0; 3242 cat_datum_t *catdatum; 3243 uint32_t buf[3], len; 3244 int rc; 3245 3246 catdatum = malloc(sizeof(cat_datum_t)); 3247 if (!catdatum) 3248 return -1; 3249 cat_datum_init(catdatum); 3250 3251 rc = next_entry(buf, fp, (sizeof(uint32_t) * 3)); 3252 if (rc < 0) 3253 goto bad; 3254 3255 len = le32_to_cpu(buf[0]); 3256 if(zero_or_saturated(len)) 3257 goto bad; 3258 3259 catdatum->s.value = le32_to_cpu(buf[1]); 3260 catdatum->isalias = le32_to_cpu(buf[2]); 3261 3262 key = malloc(len + 1); 3263 if (!key) 3264 goto bad; 3265 rc = next_entry(key, fp, len); 3266 if (rc < 0) 3267 goto bad; 3268 key[len] = 0; 3269 3270 if (hashtab_insert(h, key, catdatum)) 3271 goto bad; 3272 3273 return 0; 3274 3275 bad: 3276 cat_destroy(key, catdatum, NULL); 3277 return -1; 3278 } 3279 3280 static int (*read_f[SYM_NUM]) (policydb_t * p, hashtab_t h, 3281 struct policy_file * fp) = { 3282 common_read, class_read, role_read, type_read, user_read, 3283 cond_read_bool, sens_read, cat_read,}; 3284 3285 /************** module reading functions below **************/ 3286 3287 static avrule_t *avrule_read(policydb_t * p, struct policy_file *fp) 3288 { 3289 unsigned int i; 3290 uint32_t buf[2], len; 3291 class_perm_node_t *cur, *tail = NULL; 3292 avrule_t *avrule; 3293 int rc; 3294 3295 avrule = (avrule_t *) malloc(sizeof(avrule_t)); 3296 if (!avrule) 3297 return NULL; 3298 3299 avrule_init(avrule); 3300 3301 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3302 if (rc < 0) 3303 goto bad; 3304 3305 avrule->specified = le32_to_cpu(buf[0]); 3306 avrule->flags = le32_to_cpu(buf[1]); 3307 3308 if (type_set_read(&avrule->stypes, fp)) 3309 goto bad; 3310 3311 if (type_set_read(&avrule->ttypes, fp)) 3312 goto bad; 3313 3314 rc = next_entry(buf, fp, sizeof(uint32_t)); 3315 if (rc < 0) 3316 goto bad; 3317 len = le32_to_cpu(buf[0]); 3318 3319 for (i = 0; i < len; i++) { 3320 cur = (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); 3321 if (!cur) 3322 goto bad; 3323 class_perm_node_init(cur); 3324 3325 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3326 if (rc < 0) { 3327 free(cur); 3328 goto bad; 3329 } 3330 3331 cur->tclass = le32_to_cpu(buf[0]); 3332 cur->data = le32_to_cpu(buf[1]); 3333 3334 if (!tail) { 3335 avrule->perms = cur; 3336 } else { 3337 tail->next = cur; 3338 } 3339 tail = cur; 3340 } 3341 3342 if (avrule->specified & AVRULE_XPERMS) { 3343 uint8_t buf8; 3344 size_t nel = ARRAY_SIZE(avrule->xperms->perms); 3345 uint32_t buf32[nel]; 3346 3347 if (p->policyvers < MOD_POLICYDB_VERSION_XPERMS_IOCTL) { 3348 ERR(fp->handle, 3349 "module policy version %u does not support ioctl" 3350 " extended permissions rules and one was specified", 3351 p->policyvers); 3352 goto bad; 3353 } 3354 3355 if (p->target_platform != SEPOL_TARGET_SELINUX) { 3356 ERR(fp->handle, 3357 "Target platform %s does not support ioctl" 3358 " extended permissions rules and one was specified", 3359 policydb_target_strings[p->target_platform]); 3360 goto bad; 3361 } 3362 3363 avrule->xperms = calloc(1, sizeof(*avrule->xperms)); 3364 if (!avrule->xperms) 3365 goto bad; 3366 3367 rc = next_entry(&buf8, fp, sizeof(uint8_t)); 3368 if (rc < 0) { 3369 ERR(fp->handle, "truncated entry"); 3370 goto bad; 3371 } 3372 avrule->xperms->specified = buf8; 3373 rc = next_entry(&buf8, fp, sizeof(uint8_t)); 3374 if (rc < 0) { 3375 ERR(fp->handle, "truncated entry"); 3376 goto bad; 3377 } 3378 avrule->xperms->driver = buf8; 3379 rc = next_entry(buf32, fp, sizeof(uint32_t)*nel); 3380 if (rc < 0) { 3381 ERR(fp->handle, "truncated entry"); 3382 goto bad; 3383 } 3384 for (i = 0; i < nel; i++) 3385 avrule->xperms->perms[i] = le32_to_cpu(buf32[i]); 3386 } 3387 3388 return avrule; 3389 bad: 3390 if (avrule) { 3391 avrule_destroy(avrule); 3392 free(avrule); 3393 } 3394 return NULL; 3395 } 3396 3397 static int range_read(policydb_t * p, struct policy_file *fp) 3398 { 3399 uint32_t buf[2], nel; 3400 range_trans_t *rt = NULL; 3401 struct mls_range *r = NULL; 3402 range_trans_rule_t *rtr = NULL, *lrtr = NULL; 3403 unsigned int i; 3404 int new_rangetr = (p->policy_type == POLICY_KERN && 3405 p->policyvers >= POLICYDB_VERSION_RANGETRANS); 3406 int rc; 3407 3408 rc = next_entry(buf, fp, sizeof(uint32_t)); 3409 if (rc < 0) 3410 return -1; 3411 nel = le32_to_cpu(buf[0]); 3412 for (i = 0; i < nel; i++) { 3413 rt = calloc(1, sizeof(range_trans_t)); 3414 if (!rt) 3415 return -1; 3416 rc = next_entry(buf, fp, (sizeof(uint32_t) * 2)); 3417 if (rc < 0) 3418 goto err; 3419 rt->source_type = le32_to_cpu(buf[0]); 3420 rt->target_type = le32_to_cpu(buf[1]); 3421 if (new_rangetr) { 3422 rc = next_entry(buf, fp, (sizeof(uint32_t))); 3423 if (rc < 0) 3424 goto err; 3425 rt->target_class = le32_to_cpu(buf[0]); 3426 } else 3427 rt->target_class = SECCLASS_PROCESS; 3428 r = calloc(1, sizeof(*r)); 3429 if (!r) 3430 goto err; 3431 if (mls_read_range_helper(r, fp)) 3432 goto err; 3433 3434 if (p->policy_type == POLICY_KERN) { 3435 rc = hashtab_insert(p->range_tr, (hashtab_key_t)rt, r); 3436 if (rc) 3437 goto err; 3438 rt = NULL; 3439 r = NULL; 3440 continue; 3441 } 3442 3443 /* Module policy: convert to range_trans_rule and discard. */ 3444 rtr = malloc(sizeof(range_trans_rule_t)); 3445 if (!rtr) 3446 goto err; 3447 range_trans_rule_init(rtr); 3448 3449 if (ebitmap_set_bit(&rtr->stypes.types, rt->source_type - 1, 1)) 3450 goto err; 3451 3452 if (ebitmap_set_bit(&rtr->ttypes.types, rt->target_type - 1, 1)) 3453 goto err; 3454 3455 if (ebitmap_set_bit(&rtr->tclasses, rt->target_class - 1, 1)) 3456 goto err; 3457 3458 if (mls_range_to_semantic(r, &rtr->trange)) 3459 goto err; 3460 3461 if (lrtr) 3462 lrtr->next = rtr; 3463 else 3464 p->global->enabled->range_tr_rules = rtr; 3465 3466 free(rt); 3467 rt = NULL; 3468 free(r); 3469 r = NULL; 3470 lrtr = rtr; 3471 } 3472 3473 return 0; 3474 err: 3475 free(rt); 3476 if (r) { 3477 mls_range_destroy(r); 3478 free(r); 3479 } 3480 if (rtr) { 3481 range_trans_rule_destroy(rtr); 3482 free(rtr); 3483 } 3484 return -1; 3485 } 3486 3487 int avrule_read_list(policydb_t * p, avrule_t ** avrules, 3488 struct policy_file *fp) 3489 { 3490 unsigned int i; 3491 avrule_t *cur, *tail; 3492 uint32_t buf[1], len; 3493 int rc; 3494 3495 *avrules = tail = NULL; 3496 3497 rc = next_entry(buf, fp, sizeof(uint32_t)); 3498 if (rc < 0) { 3499 return -1; 3500 } 3501 len = le32_to_cpu(buf[0]); 3502 3503 for (i = 0; i < len; i++) { 3504 cur = avrule_read(p, fp); 3505 if (!cur) { 3506 return -1; 3507 } 3508 3509 if (!tail) { 3510 *avrules = cur; 3511 } else { 3512 tail->next = cur; 3513 } 3514 tail = cur; 3515 } 3516 3517 return 0; 3518 } 3519 3520 static int role_trans_rule_read(policydb_t *p, role_trans_rule_t ** r, 3521 struct policy_file *fp) 3522 { 3523 uint32_t buf[1], nel; 3524 unsigned int i; 3525 role_trans_rule_t *tr, *ltr; 3526 int rc; 3527 3528 rc = next_entry(buf, fp, sizeof(uint32_t)); 3529 if (rc < 0) 3530 return -1; 3531 nel = le32_to_cpu(buf[0]); 3532 ltr = NULL; 3533 for (i = 0; i < nel; i++) { 3534 tr = malloc(sizeof(role_trans_rule_t)); 3535 if (!tr) { 3536 return -1; 3537 } 3538 role_trans_rule_init(tr); 3539 3540 if (ltr) { 3541 ltr->next = tr; 3542 } else { 3543 *r = tr; 3544 } 3545 3546 if (role_set_read(&tr->roles, fp)) 3547 return -1; 3548 3549 if (type_set_read(&tr->types, fp)) 3550 return -1; 3551 3552 if (p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS) { 3553 if (ebitmap_read(&tr->classes, fp)) 3554 return -1; 3555 } else { 3556 if (ebitmap_set_bit(&tr->classes, SECCLASS_PROCESS - 1, 1)) 3557 return -1; 3558 } 3559 3560 rc = next_entry(buf, fp, sizeof(uint32_t)); 3561 if (rc < 0) 3562 return -1; 3563 tr->new_role = le32_to_cpu(buf[0]); 3564 ltr = tr; 3565 } 3566 3567 return 0; 3568 } 3569 3570 static int role_allow_rule_read(role_allow_rule_t ** r, struct policy_file *fp) 3571 { 3572 unsigned int i; 3573 uint32_t buf[1], nel; 3574 role_allow_rule_t *ra, *lra; 3575 int rc; 3576 3577 rc = next_entry(buf, fp, sizeof(uint32_t)); 3578 if (rc < 0) 3579 return -1; 3580 nel = le32_to_cpu(buf[0]); 3581 lra = NULL; 3582 for (i = 0; i < nel; i++) { 3583 ra = malloc(sizeof(role_allow_rule_t)); 3584 if (!ra) { 3585 return -1; 3586 } 3587 role_allow_rule_init(ra); 3588 3589 if (lra) { 3590 lra->next = ra; 3591 } else { 3592 *r = ra; 3593 } 3594 3595 if (role_set_read(&ra->roles, fp)) 3596 return -1; 3597 3598 if (role_set_read(&ra->new_roles, fp)) 3599 return -1; 3600 3601 lra = ra; 3602 } 3603 return 0; 3604 } 3605 3606 static int filename_trans_rule_read(filename_trans_rule_t ** r, struct policy_file *fp) 3607 { 3608 uint32_t buf[2], nel; 3609 unsigned int i, len; 3610 filename_trans_rule_t *ftr, *lftr; 3611 int rc; 3612 3613 rc = next_entry(buf, fp, sizeof(uint32_t)); 3614 if (rc < 0) 3615 return -1; 3616 nel = le32_to_cpu(buf[0]); 3617 lftr = NULL; 3618 for (i = 0; i < nel; i++) { 3619 ftr = malloc(sizeof(*ftr)); 3620 if (!ftr) 3621 return -1; 3622 3623 filename_trans_rule_init(ftr); 3624 3625 if (lftr) 3626 lftr->next = ftr; 3627 else 3628 *r = ftr; 3629 lftr = ftr; 3630 3631 rc = next_entry(buf, fp, sizeof(uint32_t)); 3632 if (rc < 0) 3633 return -1; 3634 3635 len = le32_to_cpu(buf[0]); 3636 if (zero_or_saturated(len)) 3637 return -1; 3638 3639 ftr->name = malloc(len + 1); 3640 if (!ftr->name) 3641 return -1; 3642 3643 rc = next_entry(ftr->name, fp, len); 3644 if (rc) 3645 return -1; 3646 ftr->name[len] = 0; 3647 3648 if (type_set_read(&ftr->stypes, fp)) 3649 return -1; 3650 3651 if (type_set_read(&ftr->ttypes, fp)) 3652 return -1; 3653 3654 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3655 if (rc < 0) 3656 return -1; 3657 ftr->tclass = le32_to_cpu(buf[0]); 3658 ftr->otype = le32_to_cpu(buf[1]); 3659 } 3660 3661 return 0; 3662 } 3663 3664 static int range_trans_rule_read(range_trans_rule_t ** r, 3665 struct policy_file *fp) 3666 { 3667 uint32_t buf[1], nel; 3668 unsigned int i; 3669 range_trans_rule_t *rt, *lrt = NULL; 3670 int rc; 3671 3672 rc = next_entry(buf, fp, sizeof(uint32_t)); 3673 if (rc < 0) 3674 return -1; 3675 nel = le32_to_cpu(buf[0]); 3676 for (i = 0; i < nel; i++) { 3677 rt = malloc(sizeof(range_trans_rule_t)); 3678 if (!rt) { 3679 return -1; 3680 } 3681 range_trans_rule_init(rt); 3682 3683 if (lrt) 3684 lrt->next = rt; 3685 else 3686 *r = rt; 3687 3688 if (type_set_read(&rt->stypes, fp)) 3689 return -1; 3690 3691 if (type_set_read(&rt->ttypes, fp)) 3692 return -1; 3693 3694 if (ebitmap_read(&rt->tclasses, fp)) 3695 return -1; 3696 3697 if (mls_read_semantic_range_helper(&rt->trange, fp)) 3698 return -1; 3699 3700 lrt = rt; 3701 } 3702 3703 return 0; 3704 } 3705 3706 static int scope_index_read(scope_index_t * scope_index, 3707 unsigned int num_scope_syms, struct policy_file *fp) 3708 { 3709 unsigned int i; 3710 uint32_t buf[1]; 3711 int rc; 3712 3713 for (i = 0; i < num_scope_syms; i++) { 3714 if (ebitmap_read(scope_index->scope + i, fp) < 0) { 3715 return -1; 3716 } 3717 } 3718 rc = next_entry(buf, fp, sizeof(uint32_t)); 3719 if (rc < 0) 3720 return -1; 3721 scope_index->class_perms_len = le32_to_cpu(buf[0]); 3722 if (scope_index->class_perms_len == 0) { 3723 scope_index->class_perms_map = NULL; 3724 return 0; 3725 } 3726 if ((scope_index->class_perms_map = 3727 calloc(scope_index->class_perms_len, 3728 sizeof(*scope_index->class_perms_map))) == NULL) { 3729 return -1; 3730 } 3731 for (i = 0; i < scope_index->class_perms_len; i++) { 3732 if (ebitmap_read(scope_index->class_perms_map + i, fp) < 0) { 3733 return -1; 3734 } 3735 } 3736 return 0; 3737 } 3738 3739 static int avrule_decl_read(policydb_t * p, avrule_decl_t * decl, 3740 unsigned int num_scope_syms, struct policy_file *fp) 3741 { 3742 uint32_t buf[2], nprim, nel; 3743 unsigned int i, j; 3744 int rc; 3745 3746 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3747 if (rc < 0) 3748 return -1; 3749 decl->decl_id = le32_to_cpu(buf[0]); 3750 decl->enabled = le32_to_cpu(buf[1]); 3751 if (cond_read_list(p, &decl->cond_list, fp) == -1 || 3752 avrule_read_list(p, &decl->avrules, fp) == -1 || 3753 role_trans_rule_read(p, &decl->role_tr_rules, fp) == -1 || 3754 role_allow_rule_read(&decl->role_allow_rules, fp) == -1) { 3755 return -1; 3756 } 3757 3758 if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS && 3759 filename_trans_rule_read(&decl->filename_trans_rules, fp)) 3760 return -1; 3761 3762 if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS && 3763 range_trans_rule_read(&decl->range_tr_rules, fp) == -1) { 3764 return -1; 3765 } 3766 if (scope_index_read(&decl->required, num_scope_syms, fp) == -1 || 3767 scope_index_read(&decl->declared, num_scope_syms, fp) == -1) { 3768 return -1; 3769 } 3770 3771 for (i = 0; i < num_scope_syms; i++) { 3772 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3773 if (rc < 0) 3774 return -1; 3775 nprim = le32_to_cpu(buf[0]); 3776 nel = le32_to_cpu(buf[1]); 3777 for (j = 0; j < nel; j++) { 3778 if (read_f[i] (p, decl->symtab[i].table, fp)) { 3779 return -1; 3780 } 3781 } 3782 decl->symtab[i].nprim = nprim; 3783 } 3784 return 0; 3785 } 3786 3787 static int avrule_block_read(policydb_t * p, 3788 avrule_block_t ** block, 3789 unsigned int num_scope_syms, 3790 struct policy_file *fp) 3791 { 3792 avrule_block_t *last_block = NULL, *curblock; 3793 uint32_t buf[1], num_blocks, nel; 3794 int rc; 3795 3796 assert(*block == NULL); 3797 3798 rc = next_entry(buf, fp, sizeof(uint32_t)); 3799 if (rc < 0) 3800 return -1; 3801 num_blocks = le32_to_cpu(buf[0]); 3802 nel = num_blocks; 3803 while (num_blocks > 0) { 3804 avrule_decl_t *last_decl = NULL, *curdecl; 3805 uint32_t num_decls; 3806 if ((curblock = calloc(1, sizeof(*curblock))) == NULL) { 3807 return -1; 3808 } 3809 rc = next_entry(buf, fp, sizeof(uint32_t)); 3810 if (rc < 0) { 3811 free(curblock); 3812 return -1; 3813 } 3814 /* if this is the first block its non-optional, else its optional */ 3815 if (num_blocks != nel) 3816 curblock->flags |= AVRULE_OPTIONAL; 3817 3818 num_decls = le32_to_cpu(buf[0]); 3819 while (num_decls > 0) { 3820 if ((curdecl = avrule_decl_create(0)) == NULL) { 3821 avrule_block_destroy(curblock); 3822 return -1; 3823 } 3824 if (avrule_decl_read(p, curdecl, num_scope_syms, fp) == 3825 -1) { 3826 avrule_decl_destroy(curdecl); 3827 avrule_block_destroy(curblock); 3828 return -1; 3829 } 3830 if (curdecl->enabled) { 3831 if (curblock->enabled != NULL) { 3832 /* probably a corrupt file */ 3833 avrule_decl_destroy(curdecl); 3834 avrule_block_destroy(curblock); 3835 return -1; 3836 } 3837 curblock->enabled = curdecl; 3838 } 3839 /* one must be careful to reconstruct the 3840 * decl chain in its correct order */ 3841 if (curblock->branch_list == NULL) { 3842 curblock->branch_list = curdecl; 3843 } else { 3844 assert(last_decl); 3845 last_decl->next = curdecl; 3846 } 3847 last_decl = curdecl; 3848 num_decls--; 3849 } 3850 3851 if (*block == NULL) { 3852 *block = curblock; 3853 } else { 3854 assert(last_block); 3855 last_block->next = curblock; 3856 } 3857 last_block = curblock; 3858 3859 num_blocks--; 3860 } 3861 3862 return 0; 3863 } 3864 3865 static int scope_read(policydb_t * p, int symnum, struct policy_file *fp) 3866 { 3867 scope_datum_t *scope = NULL; 3868 uint32_t buf[2]; 3869 char *key = NULL; 3870 size_t key_len; 3871 unsigned int i; 3872 hashtab_t h = p->scope[symnum].table; 3873 int rc; 3874 3875 rc = next_entry(buf, fp, sizeof(uint32_t)); 3876 if (rc < 0) 3877 goto cleanup; 3878 key_len = le32_to_cpu(buf[0]); 3879 if (zero_or_saturated(key_len)) 3880 goto cleanup; 3881 key = malloc(key_len + 1); 3882 if (!key) 3883 goto cleanup; 3884 rc = next_entry(key, fp, key_len); 3885 if (rc < 0) 3886 goto cleanup; 3887 key[key_len] = '\0'; 3888 3889 /* ensure that there already exists a symbol with this key */ 3890 if (hashtab_search(p->symtab[symnum].table, key) == NULL) { 3891 goto cleanup; 3892 } 3893 3894 if ((scope = calloc(1, sizeof(*scope))) == NULL) { 3895 goto cleanup; 3896 } 3897 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3898 if (rc < 0) 3899 goto cleanup; 3900 scope->scope = le32_to_cpu(buf[0]); 3901 scope->decl_ids_len = le32_to_cpu(buf[1]); 3902 if (scope->decl_ids_len == 0) { 3903 ERR(fp->handle, "invalid scope with no declaration"); 3904 goto cleanup; 3905 } 3906 if ((scope->decl_ids = 3907 malloc(scope->decl_ids_len * sizeof(uint32_t))) == NULL) { 3908 goto cleanup; 3909 } 3910 rc = next_entry(scope->decl_ids, fp, sizeof(uint32_t) * scope->decl_ids_len); 3911 if (rc < 0) 3912 goto cleanup; 3913 for (i = 0; i < scope->decl_ids_len; i++) { 3914 scope->decl_ids[i] = le32_to_cpu(scope->decl_ids[i]); 3915 } 3916 3917 if (strcmp(key, "object_r") == 0 && h == p->p_roles_scope.table) { 3918 /* object_r was already added to this table in roles_init() */ 3919 scope_destroy(key, scope, NULL); 3920 } else { 3921 if (hashtab_insert(h, key, scope)) { 3922 goto cleanup; 3923 } 3924 } 3925 3926 return 0; 3927 3928 cleanup: 3929 scope_destroy(key, scope, NULL); 3930 return -1; 3931 } 3932 3933 /* 3934 * Read the configuration data from a policy database binary 3935 * representation file into a policy database structure. 3936 */ 3937 int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) 3938 { 3939 3940 unsigned int i, j, r_policyvers; 3941 uint32_t buf[5]; 3942 size_t len, nprim, nel; 3943 char *policydb_str; 3944 struct policydb_compat_info *info; 3945 unsigned int policy_type, bufindex; 3946 ebitmap_node_t *tnode; 3947 int rc; 3948 3949 /* Read the magic number and string length. */ 3950 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 3951 if (rc < 0) 3952 return POLICYDB_ERROR; 3953 for (i = 0; i < 2; i++) 3954 buf[i] = le32_to_cpu(buf[i]); 3955 3956 if (buf[0] == POLICYDB_MAGIC) { 3957 policy_type = POLICY_KERN; 3958 } else if (buf[0] == POLICYDB_MOD_MAGIC) { 3959 policy_type = POLICY_MOD; 3960 } else { 3961 ERR(fp->handle, "policydb magic number %#08x does not " 3962 "match expected magic number %#08x or %#08x", 3963 buf[0], POLICYDB_MAGIC, POLICYDB_MOD_MAGIC); 3964 return POLICYDB_ERROR; 3965 } 3966 3967 len = buf[1]; 3968 if (len == 0 || len > POLICYDB_STRING_MAX_LENGTH) { 3969 ERR(fp->handle, "policydb string length %s ", len ? "too long" : "zero"); 3970 return POLICYDB_ERROR; 3971 } 3972 3973 policydb_str = malloc(len + 1); 3974 if (!policydb_str) { 3975 ERR(fp->handle, "unable to allocate memory for policydb " 3976 "string of length %zu", len); 3977 return POLICYDB_ERROR; 3978 } 3979 rc = next_entry(policydb_str, fp, len); 3980 if (rc < 0) { 3981 ERR(fp->handle, "truncated policydb string identifier"); 3982 free(policydb_str); 3983 return POLICYDB_ERROR; 3984 } 3985 policydb_str[len] = 0; 3986 3987 if (policy_type == POLICY_KERN) { 3988 for (i = 0; i < POLICYDB_TARGET_SZ; i++) { 3989 if ((strcmp(policydb_str, policydb_target_strings[i]) 3990 == 0)) { 3991 policydb_set_target_platform(p, i); 3992 break; 3993 } 3994 } 3995 3996 if (i == POLICYDB_TARGET_SZ) { 3997 ERR(fp->handle, "cannot find a valid target for policy " 3998 "string %s", policydb_str); 3999 free(policydb_str); 4000 return POLICYDB_ERROR; 4001 } 4002 } else { 4003 if (strcmp(policydb_str, POLICYDB_MOD_STRING)) { 4004 ERR(fp->handle, "invalid string identifier %s", 4005 policydb_str); 4006 free(policydb_str); 4007 return POLICYDB_ERROR; 4008 } 4009 } 4010 4011 /* Done with policydb_str. */ 4012 free(policydb_str); 4013 policydb_str = NULL; 4014 4015 /* Read the version, config, and table sizes (and policy type if it's a module). */ 4016 if (policy_type == POLICY_KERN) 4017 nel = 4; 4018 else 4019 nel = 5; 4020 4021 rc = next_entry(buf, fp, sizeof(uint32_t) * nel); 4022 if (rc < 0) 4023 return POLICYDB_ERROR; 4024 for (i = 0; i < nel; i++) 4025 buf[i] = le32_to_cpu(buf[i]); 4026 4027 bufindex = 0; 4028 4029 if (policy_type == POLICY_MOD) { 4030 /* We know it's a module but not whether it's a base 4031 module or regular binary policy module. buf[0] 4032 tells us which. */ 4033 policy_type = buf[bufindex]; 4034 if (policy_type != POLICY_MOD && policy_type != POLICY_BASE) { 4035 ERR(fp->handle, "unknown module type: %#08x", 4036 policy_type); 4037 return POLICYDB_ERROR; 4038 } 4039 bufindex++; 4040 } 4041 4042 r_policyvers = buf[bufindex]; 4043 if (policy_type == POLICY_KERN) { 4044 if (r_policyvers < POLICYDB_VERSION_MIN || 4045 r_policyvers > POLICYDB_VERSION_MAX) { 4046 ERR(fp->handle, "policydb version %d does not match " 4047 "my version range %d-%d", buf[bufindex], 4048 POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX); 4049 return POLICYDB_ERROR; 4050 } 4051 } else if (policy_type == POLICY_BASE || policy_type == POLICY_MOD) { 4052 if (r_policyvers < MOD_POLICYDB_VERSION_MIN || 4053 r_policyvers > MOD_POLICYDB_VERSION_MAX) { 4054 ERR(fp->handle, "policydb module version %d does " 4055 "not match my version range %d-%d", 4056 buf[bufindex], MOD_POLICYDB_VERSION_MIN, 4057 MOD_POLICYDB_VERSION_MAX); 4058 return POLICYDB_ERROR; 4059 } 4060 } else { 4061 assert(0); 4062 } 4063 bufindex++; 4064 4065 /* Set the policy type and version from the read values. */ 4066 p->policy_type = policy_type; 4067 p->policyvers = r_policyvers; 4068 4069 if (buf[bufindex] & POLICYDB_CONFIG_MLS) { 4070 p->mls = 1; 4071 } else { 4072 p->mls = 0; 4073 } 4074 4075 p->handle_unknown = buf[bufindex] & POLICYDB_CONFIG_UNKNOWN_MASK; 4076 4077 bufindex++; 4078 4079 info = policydb_lookup_compat(r_policyvers, policy_type, 4080 p->target_platform); 4081 if (!info) { 4082 ERR(fp->handle, "unable to find policy compat info " 4083 "for version %d", r_policyvers); 4084 goto bad; 4085 } 4086 4087 if (buf[bufindex] != info->sym_num 4088 || buf[bufindex + 1] != info->ocon_num) { 4089 ERR(fp->handle, 4090 "policydb table sizes (%d,%d) do not " "match mine (%d,%d)", 4091 buf[bufindex], buf[bufindex + 1], info->sym_num, 4092 info->ocon_num); 4093 goto bad; 4094 } 4095 4096 if (p->policy_type == POLICY_MOD) { 4097 /* Get the module name and version */ 4098 if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) { 4099 goto bad; 4100 } 4101 len = le32_to_cpu(buf[0]); 4102 if (zero_or_saturated(len)) 4103 goto bad; 4104 if ((p->name = malloc(len + 1)) == NULL) { 4105 goto bad; 4106 } 4107 if ((rc = next_entry(p->name, fp, len)) < 0) { 4108 goto bad; 4109 } 4110 p->name[len] = '\0'; 4111 if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) { 4112 goto bad; 4113 } 4114 len = le32_to_cpu(buf[0]); 4115 if (zero_or_saturated(len)) 4116 goto bad; 4117 if ((p->version = malloc(len + 1)) == NULL) { 4118 goto bad; 4119 } 4120 if ((rc = next_entry(p->version, fp, len)) < 0) { 4121 goto bad; 4122 } 4123 p->version[len] = '\0'; 4124 } 4125 4126 if ((p->policyvers >= POLICYDB_VERSION_POLCAP && 4127 p->policy_type == POLICY_KERN) || 4128 (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && 4129 p->policy_type == POLICY_BASE) || 4130 (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP && 4131 p->policy_type == POLICY_MOD)) { 4132 if (ebitmap_read(&p->policycaps, fp)) 4133 goto bad; 4134 } 4135 4136 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && 4137 p->policy_type == POLICY_KERN) { 4138 if (ebitmap_read(&p->permissive_map, fp)) 4139 goto bad; 4140 } 4141 4142 for (i = 0; i < info->sym_num; i++) { 4143 rc = next_entry(buf, fp, sizeof(uint32_t) * 2); 4144 if (rc < 0) 4145 goto bad; 4146 nprim = le32_to_cpu(buf[0]); 4147 nel = le32_to_cpu(buf[1]); 4148 if (nel && !nprim) { 4149 ERR(fp->handle, "unexpected items in symbol table with no symbol"); 4150 goto bad; 4151 } 4152 for (j = 0; j < nel; j++) { 4153 if (read_f[i] (p, p->symtab[i].table, fp)) 4154 goto bad; 4155 } 4156 4157 p->symtab[i].nprim = nprim; 4158 } 4159 4160 if (policy_type == POLICY_KERN) { 4161 if (avtab_read(&p->te_avtab, fp, r_policyvers)) 4162 goto bad; 4163 if (r_policyvers >= POLICYDB_VERSION_BOOL) 4164 if (cond_read_list(p, &p->cond_list, fp)) 4165 goto bad; 4166 if (role_trans_read(p, fp)) 4167 goto bad; 4168 if (role_allow_read(&p->role_allow, fp)) 4169 goto bad; 4170 if (r_policyvers >= POLICYDB_VERSION_FILENAME_TRANS && 4171 filename_trans_read(p, fp)) 4172 goto bad; 4173 } else { 4174 /* first read the AV rule blocks, then the scope tables */ 4175 avrule_block_destroy(p->global); 4176 p->global = NULL; 4177 if (avrule_block_read(p, &p->global, info->sym_num, fp) == -1) { 4178 goto bad; 4179 } 4180 if (p->global == NULL) { 4181 ERR(fp->handle, "no avrule block in policy"); 4182 goto bad; 4183 } 4184 for (i = 0; i < info->sym_num; i++) { 4185 if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) { 4186 goto bad; 4187 } 4188 nel = le32_to_cpu(buf[0]); 4189 for (j = 0; j < nel; j++) { 4190 if (scope_read(p, i, fp)) 4191 goto bad; 4192 } 4193 } 4194 4195 } 4196 4197 if (policydb_index_decls(fp->handle, p)) 4198 goto bad; 4199 4200 if (policydb_index_classes(p)) 4201 goto bad; 4202 4203 if (policydb_index_others(fp->handle, p, verbose)) 4204 goto bad; 4205 4206 if (ocontext_read(info, p, fp) == -1) { 4207 goto bad; 4208 } 4209 4210 if (genfs_read(p, fp) == -1) { 4211 goto bad; 4212 } 4213 4214 if ((p->policy_type == POLICY_KERN 4215 && p->policyvers >= POLICYDB_VERSION_MLS) 4216 || (p->policy_type == POLICY_BASE 4217 && p->policyvers >= MOD_POLICYDB_VERSION_MLS 4218 && p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS)) { 4219 if (range_read(p, fp)) { 4220 goto bad; 4221 } 4222 } 4223 4224 if (policy_type == POLICY_KERN) { 4225 p->type_attr_map = malloc(p->p_types.nprim * sizeof(ebitmap_t)); 4226 p->attr_type_map = malloc(p->p_types.nprim * sizeof(ebitmap_t)); 4227 if (!p->type_attr_map || !p->attr_type_map) 4228 goto bad; 4229 for (i = 0; i < p->p_types.nprim; i++) { 4230 ebitmap_init(&p->type_attr_map[i]); 4231 ebitmap_init(&p->attr_type_map[i]); 4232 } 4233 for (i = 0; i < p->p_types.nprim; i++) { 4234 if (r_policyvers >= POLICYDB_VERSION_AVTAB) { 4235 if (ebitmap_read(&p->type_attr_map[i], fp)) 4236 goto bad; 4237 ebitmap_for_each_bit(&p->type_attr_map[i], 4238 tnode, j) { 4239 if (!ebitmap_node_get_bit(tnode, j) 4240 || i == j) 4241 continue; 4242 4243 if (j >= p->p_types.nprim) 4244 goto bad; 4245 4246 if (ebitmap_set_bit 4247 (&p->attr_type_map[j], i, 1)) 4248 goto bad; 4249 } 4250 } 4251 /* add the type itself as the degenerate case */ 4252 if (ebitmap_set_bit(&p->type_attr_map[i], i, 1)) 4253 goto bad; 4254 if (p->type_val_to_struct[i] && p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) { 4255 if (ebitmap_set_bit(&p->attr_type_map[i], i, 1)) 4256 goto bad; 4257 } 4258 } 4259 } 4260 4261 return POLICYDB_SUCCESS; 4262 bad: 4263 return POLICYDB_ERROR; 4264 } 4265 4266 int policydb_reindex_users(policydb_t * p) 4267 { 4268 unsigned int i = SYM_USERS; 4269 4270 if (p->user_val_to_struct) 4271 free(p->user_val_to_struct); 4272 if (p->sym_val_to_name[i]) 4273 free(p->sym_val_to_name[i]); 4274 4275 p->user_val_to_struct = (user_datum_t **) 4276 calloc(p->p_users.nprim, sizeof(user_datum_t *)); 4277 if (!p->user_val_to_struct) 4278 return -1; 4279 4280 p->sym_val_to_name[i] = (char **) 4281 calloc(p->symtab[i].nprim, sizeof(char *)); 4282 if (!p->sym_val_to_name[i]) 4283 return -1; 4284 4285 if (hashtab_map(p->symtab[i].table, index_f[i], p)) 4286 return -1; 4287 4288 /* Expand user roles for context validity checking */ 4289 if (hashtab_map(p->p_users.table, policydb_user_cache, p)) 4290 return -1; 4291 4292 return 0; 4293 } 4294 4295 void policy_file_init(policy_file_t *pf) 4296 { 4297 memset(pf, 0, sizeof(policy_file_t)); 4298 } 4299 4300 int policydb_set_target_platform(policydb_t *p, int platform) 4301 { 4302 if (platform == SEPOL_TARGET_SELINUX) 4303 p->target_platform = SEPOL_TARGET_SELINUX; 4304 else if (platform == SEPOL_TARGET_XEN) 4305 p->target_platform = SEPOL_TARGET_XEN; 4306 else 4307 return -1; 4308 4309 return 0; 4310 } 4311 4312