1 /* Authors: Karl MacMillan <kmacmillan (at) mentalrootkit.com> 2 * Jason Tang <jtang (at) tresys.com> 3 * Joshua Brindle <jbrindle (at) tresys.com> 4 * 5 * Copyright (C) 2004-2005 Tresys Technology, LLC 6 * Copyright (C) 2007 Red Hat, Inc. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23 #include "context.h" 24 #include <sepol/policydb/policydb.h> 25 #include <sepol/policydb/conditional.h> 26 #include <sepol/policydb/hashtab.h> 27 #include <sepol/policydb/expand.h> 28 #include <sepol/policydb/hierarchy.h> 29 #include <sepol/policydb/avrule_block.h> 30 31 #include <stdlib.h> 32 #include <stdarg.h> 33 #include <stdio.h> 34 #include <string.h> 35 #include <assert.h> 36 37 #include "debug.h" 38 #include "private.h" 39 40 typedef struct expand_state { 41 int verbose; 42 uint32_t *typemap; 43 uint32_t *boolmap; 44 uint32_t *rolemap; 45 uint32_t *usermap; 46 policydb_t *base; 47 policydb_t *out; 48 sepol_handle_t *handle; 49 int expand_neverallow; 50 } expand_state_t; 51 52 static void expand_state_init(expand_state_t * state) 53 { 54 memset(state, 0, sizeof(expand_state_t)); 55 } 56 57 static int map_ebitmap(ebitmap_t * src, ebitmap_t * dst, uint32_t * map) 58 { 59 unsigned int i; 60 ebitmap_node_t *tnode; 61 ebitmap_init(dst); 62 63 ebitmap_for_each_bit(src, tnode, i) { 64 if (!ebitmap_node_get_bit(tnode, i)) 65 continue; 66 if (!map[i]) 67 continue; 68 if (ebitmap_set_bit(dst, map[i] - 1, 1)) 69 return -1; 70 } 71 return 0; 72 } 73 74 static int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 75 void *data) 76 { 77 int ret; 78 char *id, *new_id; 79 type_datum_t *type, *new_type; 80 expand_state_t *state; 81 82 id = (char *)key; 83 type = (type_datum_t *) datum; 84 state = (expand_state_t *) data; 85 86 if ((type->flavor == TYPE_TYPE && !type->primary) 87 || type->flavor == TYPE_ALIAS) { 88 /* aliases are handled later */ 89 return 0; 90 } 91 if (!is_id_enabled(id, state->base, SYM_TYPES)) { 92 /* identifier's scope is not enabled */ 93 return 0; 94 } 95 96 if (state->verbose) 97 INFO(state->handle, "copying type or attribute %s", id); 98 99 new_id = strdup(id); 100 if (new_id == NULL) { 101 ERR(state->handle, "Out of memory!"); 102 return -1; 103 } 104 105 new_type = (type_datum_t *) malloc(sizeof(type_datum_t)); 106 if (!new_type) { 107 ERR(state->handle, "Out of memory!"); 108 free(new_id); 109 return SEPOL_ENOMEM; 110 } 111 memset(new_type, 0, sizeof(type_datum_t)); 112 113 new_type->flavor = type->flavor; 114 new_type->flags = type->flags; 115 new_type->s.value = ++state->out->p_types.nprim; 116 if (new_type->s.value > UINT16_MAX) { 117 free(new_id); 118 free(new_type); 119 ERR(state->handle, "type space overflow"); 120 return -1; 121 } 122 new_type->primary = 1; 123 state->typemap[type->s.value - 1] = new_type->s.value; 124 125 ret = hashtab_insert(state->out->p_types.table, 126 (hashtab_key_t) new_id, 127 (hashtab_datum_t) new_type); 128 if (ret) { 129 free(new_id); 130 free(new_type); 131 ERR(state->handle, "hashtab overflow"); 132 return -1; 133 } 134 135 if (new_type->flags & TYPE_FLAGS_PERMISSIVE) 136 if (ebitmap_set_bit(&state->out->permissive_map, new_type->s.value, 1)) { 137 ERR(state->handle, "Out of memory!\n"); 138 return -1; 139 } 140 141 return 0; 142 } 143 144 static int attr_convert_callback(hashtab_key_t key, hashtab_datum_t datum, 145 void *data) 146 { 147 char *id; 148 type_datum_t *type, *new_type; 149 expand_state_t *state; 150 ebitmap_t tmp_union; 151 152 id = (char *)key; 153 type = (type_datum_t *) datum; 154 state = (expand_state_t *) data; 155 156 if (type->flavor != TYPE_ATTRIB) 157 return 0; 158 159 if (!is_id_enabled(id, state->base, SYM_TYPES)) { 160 /* identifier's scope is not enabled */ 161 return 0; 162 } 163 164 if (state->verbose) 165 INFO(state->handle, "converting attribute %s", id); 166 167 new_type = hashtab_search(state->out->p_types.table, id); 168 if (!new_type) { 169 ERR(state->handle, "attribute %s vanished!", id); 170 return -1; 171 } 172 if (map_ebitmap(&type->types, &tmp_union, state->typemap)) { 173 ERR(state->handle, "out of memory"); 174 return -1; 175 } 176 177 /* then union tmp_union onto &new_type->types */ 178 if (ebitmap_union(&new_type->types, &tmp_union)) { 179 ERR(state->handle, "Out of memory!"); 180 return -1; 181 } 182 ebitmap_destroy(&tmp_union); 183 184 return 0; 185 } 186 187 static int perm_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 188 void *data) 189 { 190 int ret; 191 char *id, *new_id; 192 symtab_t *s; 193 perm_datum_t *perm, *new_perm; 194 195 id = key; 196 perm = (perm_datum_t *) datum; 197 s = (symtab_t *) data; 198 199 new_perm = (perm_datum_t *) malloc(sizeof(perm_datum_t)); 200 if (!new_perm) { 201 return -1; 202 } 203 memset(new_perm, 0, sizeof(perm_datum_t)); 204 205 new_id = strdup(id); 206 if (!new_id) { 207 free(new_perm); 208 return -1; 209 } 210 211 new_perm->s.value = perm->s.value; 212 s->nprim++; 213 214 ret = hashtab_insert(s->table, new_id, (hashtab_datum_t *) new_perm); 215 if (ret) { 216 free(new_id); 217 free(new_perm); 218 return -1; 219 } 220 221 return 0; 222 } 223 224 static int common_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 225 void *data) 226 { 227 int ret; 228 char *id, *new_id; 229 common_datum_t *common, *new_common; 230 expand_state_t *state; 231 232 id = (char *)key; 233 common = (common_datum_t *) datum; 234 state = (expand_state_t *) data; 235 236 if (state->verbose) 237 INFO(state->handle, "copying common %s", id); 238 239 new_common = (common_datum_t *) malloc(sizeof(common_datum_t)); 240 if (!new_common) { 241 ERR(state->handle, "Out of memory!"); 242 return -1; 243 } 244 memset(new_common, 0, sizeof(common_datum_t)); 245 if (symtab_init(&new_common->permissions, PERM_SYMTAB_SIZE)) { 246 ERR(state->handle, "Out of memory!"); 247 free(new_common); 248 return -1; 249 } 250 251 new_id = strdup(id); 252 if (!new_id) { 253 ERR(state->handle, "Out of memory!"); 254 symtab_destroy(&new_common->permissions); 255 free(new_common); 256 return -1; 257 } 258 259 new_common->s.value = common->s.value; 260 state->out->p_commons.nprim++; 261 262 ret = 263 hashtab_insert(state->out->p_commons.table, new_id, 264 (hashtab_datum_t *) new_common); 265 if (ret) { 266 ERR(state->handle, "hashtab overflow"); 267 symtab_destroy(&new_common->permissions); 268 free(new_common); 269 free(new_id); 270 return -1; 271 } 272 273 if (hashtab_map 274 (common->permissions.table, perm_copy_callback, 275 &new_common->permissions)) { 276 ERR(state->handle, "Out of memory!"); 277 return -1; 278 } 279 280 return 0; 281 } 282 283 static int constraint_node_clone(constraint_node_t ** dst, 284 constraint_node_t * src, 285 expand_state_t * state) 286 { 287 constraint_node_t *new_con = NULL, *last_new_con = NULL; 288 constraint_expr_t *new_expr = NULL; 289 *dst = NULL; 290 while (src != NULL) { 291 constraint_expr_t *expr, *expr_l = NULL; 292 new_con = 293 (constraint_node_t *) malloc(sizeof(constraint_node_t)); 294 if (!new_con) { 295 goto out_of_mem; 296 } 297 memset(new_con, 0, sizeof(constraint_node_t)); 298 new_con->permissions = src->permissions; 299 for (expr = src->expr; expr; expr = expr->next) { 300 if ((new_expr = calloc(1, sizeof(*new_expr))) == NULL) { 301 goto out_of_mem; 302 } 303 if (constraint_expr_init(new_expr) == -1) { 304 goto out_of_mem; 305 } 306 new_expr->expr_type = expr->expr_type; 307 new_expr->attr = expr->attr; 308 new_expr->op = expr->op; 309 if (new_expr->expr_type == CEXPR_NAMES) { 310 if (new_expr->attr & CEXPR_TYPE) { 311 /* Type sets require expansion and conversion. */ 312 if (expand_convert_type_set(state->out, 313 state-> 314 typemap, 315 expr-> 316 type_names, 317 &new_expr-> 318 names, 1)) { 319 goto out_of_mem; 320 } 321 } else if (new_expr->attr & CEXPR_ROLE) { 322 if (map_ebitmap(&expr->names, &new_expr->names, state->rolemap)) { 323 goto out_of_mem; 324 } 325 } else if (new_expr->attr & CEXPR_USER) { 326 if (map_ebitmap(&expr->names, &new_expr->names, state->usermap)) { 327 goto out_of_mem; 328 } 329 } else { 330 /* Other kinds of sets do not. */ 331 if (ebitmap_cpy(&new_expr->names, 332 &expr->names)) { 333 goto out_of_mem; 334 } 335 } 336 } 337 if (expr_l) { 338 expr_l->next = new_expr; 339 } else { 340 new_con->expr = new_expr; 341 } 342 expr_l = new_expr; 343 new_expr = NULL; 344 } 345 if (last_new_con == NULL) { 346 *dst = new_con; 347 } else { 348 last_new_con->next = new_con; 349 } 350 last_new_con = new_con; 351 src = src->next; 352 } 353 354 return 0; 355 out_of_mem: 356 ERR(state->handle, "Out of memory!"); 357 if (new_con) 358 free(new_con); 359 constraint_expr_destroy(new_expr); 360 return -1; 361 } 362 363 static int class_copy_default_new_object(expand_state_t *state, 364 class_datum_t *olddatum, 365 class_datum_t *newdatum) 366 { 367 if (olddatum->default_user) { 368 if (newdatum->default_user && olddatum->default_user != newdatum->default_user) { 369 ERR(state->handle, "Found conflicting default user definitions"); 370 return SEPOL_ENOTSUP; 371 } 372 newdatum->default_user = olddatum->default_user; 373 374 } 375 if (olddatum->default_role) { 376 if (newdatum->default_role && olddatum->default_role != newdatum->default_role) { 377 ERR(state->handle, "Found conflicting default role definitions"); 378 return SEPOL_ENOTSUP; 379 } 380 newdatum->default_role = olddatum->default_role; 381 } 382 if (olddatum->default_range) { 383 if (newdatum->default_range && olddatum->default_range != newdatum->default_range) { 384 ERR(state->handle, "Found conflicting default range definitions"); 385 return SEPOL_ENOTSUP; 386 } 387 newdatum->default_range = olddatum->default_range; 388 } 389 return 0; 390 } 391 392 static int class_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 393 void *data) 394 { 395 int ret; 396 char *id, *new_id; 397 class_datum_t *class, *new_class; 398 expand_state_t *state; 399 400 id = (char *)key; 401 class = (class_datum_t *) datum; 402 state = (expand_state_t *) data; 403 404 if (!is_id_enabled(id, state->base, SYM_CLASSES)) { 405 /* identifier's scope is not enabled */ 406 return 0; 407 } 408 409 if (state->verbose) 410 INFO(state->handle, "copying class %s", id); 411 412 new_class = (class_datum_t *) malloc(sizeof(class_datum_t)); 413 if (!new_class) { 414 ERR(state->handle, "Out of memory!"); 415 return -1; 416 } 417 memset(new_class, 0, sizeof(class_datum_t)); 418 if (symtab_init(&new_class->permissions, PERM_SYMTAB_SIZE)) { 419 ERR(state->handle, "Out of memory!"); 420 free(new_class); 421 return -1; 422 } 423 424 new_class->s.value = class->s.value; 425 state->out->p_classes.nprim++; 426 427 ret = class_copy_default_new_object(state, class, new_class); 428 if (ret) { 429 free(new_class); 430 return ret; 431 } 432 433 new_id = strdup(id); 434 if (!new_id) { 435 ERR(state->handle, "Out of memory!"); 436 free(new_class); 437 return -1; 438 } 439 440 ret = 441 hashtab_insert(state->out->p_classes.table, new_id, 442 (hashtab_datum_t *) new_class); 443 if (ret) { 444 ERR(state->handle, "hashtab overflow"); 445 free(new_class); 446 free(new_id); 447 return -1; 448 } 449 450 if (hashtab_map 451 (class->permissions.table, perm_copy_callback, 452 &new_class->permissions)) { 453 ERR(state->handle, "hashtab overflow"); 454 return -1; 455 } 456 457 if (class->comkey) { 458 new_class->comkey = strdup(class->comkey); 459 if (!new_class->comkey) { 460 ERR(state->handle, "Out of memory!"); 461 return -1; 462 } 463 464 new_class->comdatum = 465 hashtab_search(state->out->p_commons.table, 466 new_class->comkey); 467 if (!new_class->comdatum) { 468 ERR(state->handle, "could not find common datum %s", 469 new_class->comkey); 470 return -1; 471 } 472 new_class->permissions.nprim += 473 new_class->comdatum->permissions.nprim; 474 } 475 476 return 0; 477 } 478 479 static int constraint_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 480 void *data) 481 { 482 char *id; 483 class_datum_t *class, *new_class; 484 expand_state_t *state; 485 486 id = (char *)key; 487 class = (class_datum_t *) datum; 488 state = (expand_state_t *) data; 489 490 new_class = hashtab_search(state->out->p_classes.table, id); 491 if (!new_class) { 492 ERR(state->handle, "class %s vanished", id); 493 return -1; 494 } 495 496 /* constraints */ 497 if (constraint_node_clone 498 (&new_class->constraints, class->constraints, state) == -1 499 || constraint_node_clone(&new_class->validatetrans, 500 class->validatetrans, state) == -1) { 501 return -1; 502 } 503 return 0; 504 } 505 506 /* 507 * The boundaries have to be copied after the types/roles/users are copied, 508 * because it refers hashtab to lookup destinated objects. 509 */ 510 static int type_bounds_copy_callback(hashtab_key_t key, 511 hashtab_datum_t datum, void *data) 512 { 513 expand_state_t *state = (expand_state_t *) data; 514 type_datum_t *type = (type_datum_t *) datum; 515 type_datum_t *dest; 516 uint32_t bounds_val; 517 518 if (!type->bounds) 519 return 0; 520 521 if (!is_id_enabled((char *)key, state->base, SYM_TYPES)) 522 return 0; 523 524 bounds_val = state->typemap[type->bounds - 1]; 525 526 dest = hashtab_search(state->out->p_types.table, (char *)key); 527 if (!dest) { 528 ERR(state->handle, "Type lookup failed for %s", (char *)key); 529 return -1; 530 } 531 if (dest->bounds != 0 && dest->bounds != bounds_val) { 532 ERR(state->handle, "Inconsistent boundary for %s", (char *)key); 533 return -1; 534 } 535 dest->bounds = bounds_val; 536 537 return 0; 538 } 539 540 static int role_bounds_copy_callback(hashtab_key_t key, 541 hashtab_datum_t datum, void *data) 542 { 543 expand_state_t *state = (expand_state_t *) data; 544 role_datum_t *role = (role_datum_t *) datum; 545 role_datum_t *dest; 546 uint32_t bounds_val; 547 548 if (!role->bounds) 549 return 0; 550 551 if (!is_id_enabled((char *)key, state->base, SYM_ROLES)) 552 return 0; 553 554 bounds_val = state->rolemap[role->bounds - 1]; 555 556 dest = hashtab_search(state->out->p_roles.table, (char *)key); 557 if (!dest) { 558 ERR(state->handle, "Role lookup failed for %s", (char *)key); 559 return -1; 560 } 561 if (dest->bounds != 0 && dest->bounds != bounds_val) { 562 ERR(state->handle, "Inconsistent boundary for %s", (char *)key); 563 return -1; 564 } 565 dest->bounds = bounds_val; 566 567 return 0; 568 } 569 570 static int user_bounds_copy_callback(hashtab_key_t key, 571 hashtab_datum_t datum, void *data) 572 { 573 expand_state_t *state = (expand_state_t *) data; 574 user_datum_t *user = (user_datum_t *) datum; 575 user_datum_t *dest; 576 uint32_t bounds_val; 577 578 if (!user->bounds) 579 return 0; 580 581 if (!is_id_enabled((char *)key, state->base, SYM_USERS)) 582 return 0; 583 584 bounds_val = state->usermap[user->bounds - 1]; 585 586 dest = hashtab_search(state->out->p_users.table, (char *)key); 587 if (!dest) { 588 ERR(state->handle, "User lookup failed for %s", (char *)key); 589 return -1; 590 } 591 if (dest->bounds != 0 && dest->bounds != bounds_val) { 592 ERR(state->handle, "Inconsistent boundary for %s", (char *)key); 593 return -1; 594 } 595 dest->bounds = bounds_val; 596 597 return 0; 598 } 599 600 /* The aliases have to be copied after the types and attributes to be certain that 601 * the out symbol table will have the type that the alias refers. Otherwise, we 602 * won't be able to find the type value for the alias. We can't depend on the 603 * declaration ordering because of the hash table. 604 */ 605 static int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 606 void *data) 607 { 608 int ret; 609 char *id, *new_id; 610 type_datum_t *alias, *new_alias; 611 expand_state_t *state; 612 uint32_t prival; 613 614 id = (char *)key; 615 alias = (type_datum_t *) datum; 616 state = (expand_state_t *) data; 617 618 /* ignore regular types */ 619 if (alias->flavor == TYPE_TYPE && alias->primary) 620 return 0; 621 622 /* ignore attributes */ 623 if (alias->flavor == TYPE_ATTRIB) 624 return 0; 625 626 if (alias->flavor == TYPE_ALIAS) 627 prival = alias->primary; 628 else 629 prival = alias->s.value; 630 631 if (!is_id_enabled(state->base->p_type_val_to_name[prival - 1], 632 state->base, SYM_TYPES)) { 633 /* The primary type for this alias is not enabled, the alias 634 * shouldn't be either */ 635 return 0; 636 } 637 638 if (state->verbose) 639 INFO(state->handle, "copying alias %s", id); 640 641 new_id = strdup(id); 642 if (!new_id) { 643 ERR(state->handle, "Out of memory!"); 644 return -1; 645 } 646 647 new_alias = (type_datum_t *) malloc(sizeof(type_datum_t)); 648 if (!new_alias) { 649 ERR(state->handle, "Out of memory!"); 650 free(new_id); 651 return SEPOL_ENOMEM; 652 } 653 memset(new_alias, 0, sizeof(type_datum_t)); 654 if (alias->flavor == TYPE_TYPE) 655 new_alias->s.value = state->typemap[alias->s.value - 1]; 656 else if (alias->flavor == TYPE_ALIAS) 657 new_alias->s.value = state->typemap[alias->primary - 1]; 658 else 659 assert(0); /* unreachable */ 660 661 new_alias->flags = alias->flags; 662 663 ret = hashtab_insert(state->out->p_types.table, 664 (hashtab_key_t) new_id, 665 (hashtab_datum_t) new_alias); 666 667 if (ret) { 668 ERR(state->handle, "hashtab overflow"); 669 free(new_alias); 670 free(new_id); 671 return -1; 672 } 673 674 state->typemap[alias->s.value - 1] = new_alias->s.value; 675 676 if (new_alias->flags & TYPE_FLAGS_PERMISSIVE) 677 if (ebitmap_set_bit(&state->out->permissive_map, new_alias->s.value, 1)) { 678 ERR(state->handle, "Out of memory!"); 679 return -1; 680 } 681 682 return 0; 683 } 684 685 static int role_remap_dominates(hashtab_key_t key __attribute__ ((unused)), hashtab_datum_t datum, void *data) 686 { 687 ebitmap_t mapped_roles; 688 role_datum_t *role = (role_datum_t *) datum; 689 expand_state_t *state = (expand_state_t *) data; 690 691 if (map_ebitmap(&role->dominates, &mapped_roles, state->rolemap)) 692 return -1; 693 694 ebitmap_destroy(&role->dominates); 695 696 if (ebitmap_cpy(&role->dominates, &mapped_roles)) 697 return -1; 698 699 ebitmap_destroy(&mapped_roles); 700 701 return 0; 702 } 703 704 /* For the role attribute in the base module, escalate its counterpart's 705 * types.types ebitmap in the out module to the counterparts of all the 706 * regular role that belongs to the current role attribute. Note, must be 707 * invoked after role_copy_callback so that state->rolemap is available. 708 */ 709 static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum, 710 void *data) 711 { 712 char *id, *base_reg_role_id; 713 role_datum_t *role, *new_role, *regular_role; 714 expand_state_t *state; 715 ebitmap_node_t *rnode; 716 unsigned int i; 717 ebitmap_t mapped_roles; 718 719 id = key; 720 role = (role_datum_t *)datum; 721 state = (expand_state_t *)data; 722 723 if (strcmp(id, OBJECT_R) == 0) { 724 /* object_r is never a role attribute by far */ 725 return 0; 726 } 727 728 if (!is_id_enabled(id, state->base, SYM_ROLES)) { 729 /* identifier's scope is not enabled */ 730 return 0; 731 } 732 733 if (role->flavor != ROLE_ATTRIB) 734 return 0; 735 736 if (state->verbose) 737 INFO(state->handle, "fixing role attribute %s", id); 738 739 new_role = 740 (role_datum_t *)hashtab_search(state->out->p_roles.table, id); 741 742 assert(new_role != NULL && new_role->flavor == ROLE_ATTRIB); 743 744 ebitmap_init(&mapped_roles); 745 if (map_ebitmap(&role->roles, &mapped_roles, state->rolemap)) 746 return -1; 747 if (ebitmap_union(&new_role->roles, &mapped_roles)) { 748 ERR(state->handle, "Out of memory!"); 749 ebitmap_destroy(&mapped_roles); 750 return -1; 751 } 752 ebitmap_destroy(&mapped_roles); 753 754 ebitmap_for_each_bit(&role->roles, rnode, i) { 755 if (ebitmap_node_get_bit(rnode, i)) { 756 /* take advantage of sym_val_to_name[] 757 * of the base module */ 758 base_reg_role_id = state->base->p_role_val_to_name[i]; 759 regular_role = (role_datum_t *)hashtab_search( 760 state->out->p_roles.table, 761 base_reg_role_id); 762 assert(regular_role != NULL && 763 regular_role->flavor == ROLE_ROLE); 764 765 if (ebitmap_union(®ular_role->types.types, 766 &new_role->types.types)) { 767 ERR(state->handle, "Out of memory!"); 768 return -1; 769 } 770 } 771 } 772 773 return 0; 774 } 775 776 static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 777 void *data) 778 { 779 int ret; 780 char *id, *new_id; 781 role_datum_t *role; 782 role_datum_t *new_role; 783 expand_state_t *state; 784 ebitmap_t tmp_union_types; 785 786 id = key; 787 role = (role_datum_t *) datum; 788 state = (expand_state_t *) data; 789 790 if (strcmp(id, OBJECT_R) == 0) { 791 /* object_r is always value 1 */ 792 state->rolemap[role->s.value - 1] = 1; 793 return 0; 794 } 795 796 if (!is_id_enabled(id, state->base, SYM_ROLES)) { 797 /* identifier's scope is not enabled */ 798 return 0; 799 } 800 801 if (state->verbose) 802 INFO(state->handle, "copying role %s", id); 803 804 new_role = 805 (role_datum_t *) hashtab_search(state->out->p_roles.table, id); 806 if (!new_role) { 807 new_role = (role_datum_t *) malloc(sizeof(role_datum_t)); 808 if (!new_role) { 809 ERR(state->handle, "Out of memory!"); 810 return -1; 811 } 812 memset(new_role, 0, sizeof(role_datum_t)); 813 814 new_id = strdup(id); 815 if (!new_id) { 816 ERR(state->handle, "Out of memory!"); 817 free(new_role); 818 return -1; 819 } 820 821 state->out->p_roles.nprim++; 822 new_role->flavor = role->flavor; 823 new_role->s.value = state->out->p_roles.nprim; 824 state->rolemap[role->s.value - 1] = new_role->s.value; 825 ret = hashtab_insert(state->out->p_roles.table, 826 (hashtab_key_t) new_id, 827 (hashtab_datum_t) new_role); 828 829 if (ret) { 830 ERR(state->handle, "hashtab overflow"); 831 free(new_role); 832 free(new_id); 833 return -1; 834 } 835 } 836 837 /* The dominates bitmap is going to be wrong for the moment, 838 * we'll come back later and remap them, after we are sure all 839 * the roles have been added */ 840 if (ebitmap_union(&new_role->dominates, &role->dominates)) { 841 ERR(state->handle, "Out of memory!"); 842 return -1; 843 } 844 845 ebitmap_init(&tmp_union_types); 846 847 /* convert types in the role datum in the global symtab */ 848 if (expand_convert_type_set 849 (state->out, state->typemap, &role->types, &tmp_union_types, 1)) { 850 ebitmap_destroy(&tmp_union_types); 851 ERR(state->handle, "Out of memory!"); 852 return -1; 853 } 854 855 if (ebitmap_union(&new_role->types.types, &tmp_union_types)) { 856 ERR(state->handle, "Out of memory!"); 857 ebitmap_destroy(&tmp_union_types); 858 return -1; 859 } 860 ebitmap_destroy(&tmp_union_types); 861 862 return 0; 863 } 864 865 int mls_semantic_level_expand(mls_semantic_level_t * sl, mls_level_t * l, 866 policydb_t * p, sepol_handle_t * h) 867 { 868 mls_semantic_cat_t *cat; 869 level_datum_t *levdatum; 870 unsigned int i; 871 872 mls_level_init(l); 873 874 if (!p->mls) 875 return 0; 876 877 /* Required not declared. */ 878 if (!sl->sens) 879 return 0; 880 881 l->sens = sl->sens; 882 levdatum = (level_datum_t *) hashtab_search(p->p_levels.table, 883 p->p_sens_val_to_name[l-> 884 sens - 885 1]); 886 for (cat = sl->cat; cat; cat = cat->next) { 887 if (cat->low > cat->high) { 888 ERR(h, "Category range is not valid %s.%s", 889 p->p_cat_val_to_name[cat->low - 1], 890 p->p_cat_val_to_name[cat->high - 1]); 891 return -1; 892 } 893 for (i = cat->low - 1; i < cat->high; i++) { 894 if (!ebitmap_get_bit(&levdatum->level->cat, i)) { 895 ERR(h, "Category %s can not be associate with " 896 "level %s", 897 p->p_cat_val_to_name[i], 898 p->p_sens_val_to_name[l->sens - 1]); 899 } 900 if (ebitmap_set_bit(&l->cat, i, 1)) { 901 ERR(h, "Out of memory!"); 902 return -1; 903 } 904 } 905 } 906 907 return 0; 908 } 909 910 int mls_semantic_range_expand(mls_semantic_range_t * sr, mls_range_t * r, 911 policydb_t * p, sepol_handle_t * h) 912 { 913 if (mls_semantic_level_expand(&sr->level[0], &r->level[0], p, h) < 0) 914 return -1; 915 916 if (mls_semantic_level_expand(&sr->level[1], &r->level[1], p, h) < 0) { 917 mls_semantic_level_destroy(&sr->level[0]); 918 return -1; 919 } 920 921 if (!mls_level_dom(&r->level[1], &r->level[0])) { 922 mls_range_destroy(r); 923 ERR(h, "MLS range high level does not dominate low level"); 924 return -1; 925 } 926 927 return 0; 928 } 929 930 static int user_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 931 void *data) 932 { 933 int ret; 934 expand_state_t *state; 935 user_datum_t *user; 936 user_datum_t *new_user; 937 char *id, *new_id; 938 ebitmap_t tmp_union; 939 940 id = key; 941 user = (user_datum_t *) datum; 942 state = (expand_state_t *) data; 943 944 if (!is_id_enabled(id, state->base, SYM_USERS)) { 945 /* identifier's scope is not enabled */ 946 return 0; 947 } 948 949 if (state->verbose) 950 INFO(state->handle, "copying user %s", id); 951 952 new_user = 953 (user_datum_t *) hashtab_search(state->out->p_users.table, id); 954 if (!new_user) { 955 new_user = (user_datum_t *) malloc(sizeof(user_datum_t)); 956 if (!new_user) { 957 ERR(state->handle, "Out of memory!"); 958 return -1; 959 } 960 memset(new_user, 0, sizeof(user_datum_t)); 961 962 state->out->p_users.nprim++; 963 new_user->s.value = state->out->p_users.nprim; 964 state->usermap[user->s.value - 1] = new_user->s.value; 965 966 new_id = strdup(id); 967 if (!new_id) { 968 ERR(state->handle, "Out of memory!"); 969 free(new_user); 970 return -1; 971 } 972 ret = hashtab_insert(state->out->p_users.table, 973 (hashtab_key_t) new_id, 974 (hashtab_datum_t) new_user); 975 if (ret) { 976 ERR(state->handle, "hashtab overflow"); 977 user_datum_destroy(new_user); 978 free(new_user); 979 free(new_id); 980 return -1; 981 } 982 983 /* expand the semantic MLS info */ 984 if (mls_semantic_range_expand(&user->range, 985 &new_user->exp_range, 986 state->out, state->handle)) { 987 return -1; 988 } 989 if (mls_semantic_level_expand(&user->dfltlevel, 990 &new_user->exp_dfltlevel, 991 state->out, state->handle)) { 992 return -1; 993 } 994 if (!mls_level_between(&new_user->exp_dfltlevel, 995 &new_user->exp_range.level[0], 996 &new_user->exp_range.level[1])) { 997 ERR(state->handle, "default level not within user " 998 "range"); 999 return -1; 1000 } 1001 } else { 1002 /* require that the MLS info match */ 1003 mls_range_t tmp_range; 1004 mls_level_t tmp_level; 1005 1006 if (mls_semantic_range_expand(&user->range, &tmp_range, 1007 state->out, state->handle)) { 1008 return -1; 1009 } 1010 if (mls_semantic_level_expand(&user->dfltlevel, &tmp_level, 1011 state->out, state->handle)) { 1012 mls_range_destroy(&tmp_range); 1013 return -1; 1014 } 1015 if (!mls_range_eq(&new_user->exp_range, &tmp_range) || 1016 !mls_level_eq(&new_user->exp_dfltlevel, &tmp_level)) { 1017 mls_range_destroy(&tmp_range); 1018 mls_level_destroy(&tmp_level); 1019 return -1; 1020 } 1021 mls_range_destroy(&tmp_range); 1022 mls_level_destroy(&tmp_level); 1023 } 1024 1025 ebitmap_init(&tmp_union); 1026 1027 /* get global roles for this user */ 1028 if (role_set_expand(&user->roles, &tmp_union, state->out, state->base, state->rolemap)) { 1029 ERR(state->handle, "Out of memory!"); 1030 ebitmap_destroy(&tmp_union); 1031 return -1; 1032 } 1033 1034 if (ebitmap_union(&new_user->roles.roles, &tmp_union)) { 1035 ERR(state->handle, "Out of memory!"); 1036 ebitmap_destroy(&tmp_union); 1037 return -1; 1038 } 1039 ebitmap_destroy(&tmp_union); 1040 1041 return 0; 1042 } 1043 1044 static int bool_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 1045 void *data) 1046 { 1047 int ret; 1048 expand_state_t *state; 1049 cond_bool_datum_t *bool, *new_bool; 1050 char *id, *new_id; 1051 1052 id = key; 1053 bool = (cond_bool_datum_t *) datum; 1054 state = (expand_state_t *) data; 1055 1056 if (!is_id_enabled(id, state->base, SYM_BOOLS)) { 1057 /* identifier's scope is not enabled */ 1058 return 0; 1059 } 1060 1061 if (bool->flags & COND_BOOL_FLAGS_TUNABLE) { 1062 /* Skip tunables */ 1063 return 0; 1064 } 1065 1066 if (state->verbose) 1067 INFO(state->handle, "copying boolean %s", id); 1068 1069 new_bool = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t)); 1070 if (!new_bool) { 1071 ERR(state->handle, "Out of memory!"); 1072 return -1; 1073 } 1074 1075 new_id = strdup(id); 1076 if (!new_id) { 1077 ERR(state->handle, "Out of memory!"); 1078 free(new_bool); 1079 return -1; 1080 } 1081 1082 state->out->p_bools.nprim++; 1083 new_bool->s.value = state->out->p_bools.nprim; 1084 1085 ret = hashtab_insert(state->out->p_bools.table, 1086 (hashtab_key_t) new_id, 1087 (hashtab_datum_t) new_bool); 1088 if (ret) { 1089 ERR(state->handle, "hashtab overflow"); 1090 free(new_bool); 1091 free(new_id); 1092 return -1; 1093 } 1094 1095 state->boolmap[bool->s.value - 1] = new_bool->s.value; 1096 1097 new_bool->state = bool->state; 1098 new_bool->flags = bool->flags; 1099 1100 return 0; 1101 } 1102 1103 static int sens_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 1104 void *data) 1105 { 1106 expand_state_t *state = (expand_state_t *) data; 1107 level_datum_t *level = (level_datum_t *) datum, *new_level = NULL; 1108 char *id = (char *)key, *new_id = NULL; 1109 1110 if (!is_id_enabled(id, state->base, SYM_LEVELS)) { 1111 /* identifier's scope is not enabled */ 1112 return 0; 1113 } 1114 1115 if (state->verbose) 1116 INFO(state->handle, "copying sensitivity level %s", id); 1117 1118 new_level = (level_datum_t *) malloc(sizeof(level_datum_t)); 1119 if (!new_level) 1120 goto out_of_mem; 1121 level_datum_init(new_level); 1122 new_level->level = (mls_level_t *) malloc(sizeof(mls_level_t)); 1123 if (!new_level->level) 1124 goto out_of_mem; 1125 mls_level_init(new_level->level); 1126 new_id = strdup(id); 1127 if (!new_id) 1128 goto out_of_mem; 1129 1130 if (mls_level_cpy(new_level->level, level->level)) { 1131 goto out_of_mem; 1132 } 1133 new_level->isalias = level->isalias; 1134 state->out->p_levels.nprim++; 1135 1136 if (hashtab_insert(state->out->p_levels.table, 1137 (hashtab_key_t) new_id, 1138 (hashtab_datum_t) new_level)) { 1139 goto out_of_mem; 1140 } 1141 return 0; 1142 1143 out_of_mem: 1144 ERR(state->handle, "Out of memory!"); 1145 if (new_level != NULL && new_level->level != NULL) { 1146 mls_level_destroy(new_level->level); 1147 free(new_level->level); 1148 } 1149 level_datum_destroy(new_level); 1150 free(new_level); 1151 free(new_id); 1152 return -1; 1153 } 1154 1155 static int cats_copy_callback(hashtab_key_t key, hashtab_datum_t datum, 1156 void *data) 1157 { 1158 expand_state_t *state = (expand_state_t *) data; 1159 cat_datum_t *cat = (cat_datum_t *) datum, *new_cat = NULL; 1160 char *id = (char *)key, *new_id = NULL; 1161 1162 if (!is_id_enabled(id, state->base, SYM_CATS)) { 1163 /* identifier's scope is not enabled */ 1164 return 0; 1165 } 1166 1167 if (state->verbose) 1168 INFO(state->handle, "copying category attribute %s", id); 1169 1170 new_cat = (cat_datum_t *) malloc(sizeof(cat_datum_t)); 1171 if (!new_cat) 1172 goto out_of_mem; 1173 cat_datum_init(new_cat); 1174 new_id = strdup(id); 1175 if (!new_id) 1176 goto out_of_mem; 1177 1178 new_cat->s.value = cat->s.value; 1179 new_cat->isalias = cat->isalias; 1180 state->out->p_cats.nprim++; 1181 if (hashtab_insert(state->out->p_cats.table, 1182 (hashtab_key_t) new_id, (hashtab_datum_t) new_cat)) { 1183 goto out_of_mem; 1184 } 1185 1186 return 0; 1187 1188 out_of_mem: 1189 ERR(state->handle, "Out of memory!"); 1190 cat_datum_destroy(new_cat); 1191 free(new_cat); 1192 free(new_id); 1193 return -1; 1194 } 1195 1196 static int copy_role_allows(expand_state_t * state, role_allow_rule_t * rules) 1197 { 1198 unsigned int i, j; 1199 role_allow_t *cur_allow, *n, *l; 1200 role_allow_rule_t *cur; 1201 ebitmap_t roles, new_roles; 1202 ebitmap_node_t *snode, *tnode; 1203 1204 /* start at the end of the list */ 1205 for (l = state->out->role_allow; l && l->next; l = l->next) ; 1206 1207 cur = rules; 1208 while (cur) { 1209 ebitmap_init(&roles); 1210 ebitmap_init(&new_roles); 1211 1212 if (role_set_expand(&cur->roles, &roles, state->out, state->base, state->rolemap)) { 1213 ERR(state->handle, "Out of memory!"); 1214 return -1; 1215 } 1216 1217 if (role_set_expand(&cur->new_roles, &new_roles, state->out, state->base, state->rolemap)) { 1218 ERR(state->handle, "Out of memory!"); 1219 return -1; 1220 } 1221 1222 ebitmap_for_each_bit(&roles, snode, i) { 1223 if (!ebitmap_node_get_bit(snode, i)) 1224 continue; 1225 ebitmap_for_each_bit(&new_roles, tnode, j) { 1226 if (!ebitmap_node_get_bit(tnode, j)) 1227 continue; 1228 /* check for duplicates */ 1229 cur_allow = state->out->role_allow; 1230 while (cur_allow) { 1231 if ((cur_allow->role == i + 1) && 1232 (cur_allow->new_role == j + 1)) 1233 break; 1234 cur_allow = cur_allow->next; 1235 } 1236 if (cur_allow) 1237 continue; 1238 n = (role_allow_t *) 1239 malloc(sizeof(role_allow_t)); 1240 if (!n) { 1241 ERR(state->handle, "Out of memory!"); 1242 return -1; 1243 } 1244 memset(n, 0, sizeof(role_allow_t)); 1245 n->role = i + 1; 1246 n->new_role = j + 1; 1247 if (l) { 1248 l->next = n; 1249 } else { 1250 state->out->role_allow = n; 1251 } 1252 l = n; 1253 } 1254 } 1255 1256 ebitmap_destroy(&roles); 1257 ebitmap_destroy(&new_roles); 1258 1259 cur = cur->next; 1260 } 1261 1262 return 0; 1263 } 1264 1265 static int copy_role_trans(expand_state_t * state, role_trans_rule_t * rules) 1266 { 1267 unsigned int i, j, k; 1268 role_trans_t *n, *l, *cur_trans; 1269 role_trans_rule_t *cur; 1270 ebitmap_t roles, types; 1271 ebitmap_node_t *rnode, *tnode, *cnode; 1272 1273 /* start at the end of the list */ 1274 for (l = state->out->role_tr; l && l->next; l = l->next) ; 1275 1276 cur = rules; 1277 while (cur) { 1278 ebitmap_init(&roles); 1279 ebitmap_init(&types); 1280 1281 if (role_set_expand(&cur->roles, &roles, state->out, state->base, state->rolemap)) { 1282 ERR(state->handle, "Out of memory!"); 1283 return -1; 1284 } 1285 if (expand_convert_type_set 1286 (state->out, state->typemap, &cur->types, &types, 1)) { 1287 ERR(state->handle, "Out of memory!"); 1288 return -1; 1289 } 1290 ebitmap_for_each_bit(&roles, rnode, i) { 1291 if (!ebitmap_node_get_bit(rnode, i)) 1292 continue; 1293 ebitmap_for_each_bit(&types, tnode, j) { 1294 if (!ebitmap_node_get_bit(tnode, j)) 1295 continue; 1296 ebitmap_for_each_bit(&cur->classes, cnode, k) { 1297 if (!ebitmap_node_get_bit(cnode, k)) 1298 continue; 1299 1300 cur_trans = state->out->role_tr; 1301 while (cur_trans) { 1302 unsigned int mapped_role; 1303 1304 mapped_role = state->rolemap[cur->new_role - 1]; 1305 1306 if ((cur_trans->role == 1307 i + 1) && 1308 (cur_trans->type == 1309 j + 1) && 1310 (cur_trans->tclass == 1311 k + 1)) { 1312 if (cur_trans->new_role == mapped_role) { 1313 break; 1314 } else { 1315 ERR(state->handle, 1316 "Conflicting role trans rule %s %s : %s { %s vs %s }", 1317 state->out->p_role_val_to_name[i], 1318 state->out->p_type_val_to_name[j], 1319 state->out->p_class_val_to_name[k], 1320 state->out->p_role_val_to_name[mapped_role - 1], 1321 state->out->p_role_val_to_name[cur_trans->new_role - 1]); 1322 return -1; 1323 } 1324 } 1325 cur_trans = cur_trans->next; 1326 } 1327 if (cur_trans) 1328 continue; 1329 1330 n = (role_trans_t *) 1331 malloc(sizeof(role_trans_t)); 1332 if (!n) { 1333 ERR(state->handle, 1334 "Out of memory!"); 1335 return -1; 1336 } 1337 memset(n, 0, sizeof(role_trans_t)); 1338 n->role = i + 1; 1339 n->type = j + 1; 1340 n->tclass = k + 1; 1341 n->new_role = state->rolemap 1342 [cur->new_role - 1]; 1343 if (l) 1344 l->next = n; 1345 else 1346 state->out->role_tr = n; 1347 1348 l = n; 1349 } 1350 } 1351 } 1352 1353 ebitmap_destroy(&roles); 1354 ebitmap_destroy(&types); 1355 1356 cur = cur->next; 1357 } 1358 return 0; 1359 } 1360 1361 static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *rules) 1362 { 1363 unsigned int i, j; 1364 filename_trans_t *new_trans, *cur_trans; 1365 filename_trans_rule_t *cur_rule; 1366 ebitmap_t stypes, ttypes; 1367 ebitmap_node_t *snode, *tnode; 1368 1369 cur_rule = rules; 1370 while (cur_rule) { 1371 uint32_t mapped_otype; 1372 1373 ebitmap_init(&stypes); 1374 ebitmap_init(&ttypes); 1375 1376 if (expand_convert_type_set(state->out, state->typemap, 1377 &cur_rule->stypes, &stypes, 1)) { 1378 ERR(state->handle, "Out of memory!"); 1379 return -1; 1380 } 1381 1382 if (expand_convert_type_set(state->out, state->typemap, 1383 &cur_rule->ttypes, &ttypes, 1)) { 1384 ERR(state->handle, "Out of memory!"); 1385 return -1; 1386 } 1387 1388 mapped_otype = state->typemap[cur_rule->otype - 1]; 1389 1390 ebitmap_for_each_bit(&stypes, snode, i) { 1391 if (!ebitmap_node_get_bit(snode, i)) 1392 continue; 1393 ebitmap_for_each_bit(&ttypes, tnode, j) { 1394 if (!ebitmap_node_get_bit(tnode, j)) 1395 continue; 1396 1397 cur_trans = state->out->filename_trans; 1398 while (cur_trans) { 1399 if ((cur_trans->stype == i + 1) && 1400 (cur_trans->ttype == j + 1) && 1401 (cur_trans->tclass == cur_rule->tclass) && 1402 (!strcmp(cur_trans->name, cur_rule->name))) { 1403 /* duplicate rule, who cares */ 1404 if (cur_trans->otype == mapped_otype) 1405 break; 1406 1407 ERR(state->handle, "Conflicting filename trans rules %s %s %s : %s otype1:%s otype2:%s", 1408 cur_trans->name, 1409 state->out->p_type_val_to_name[i], 1410 state->out->p_type_val_to_name[j], 1411 state->out->p_class_val_to_name[cur_trans->tclass - 1], 1412 state->out->p_type_val_to_name[cur_trans->otype - 1], 1413 state->out->p_type_val_to_name[mapped_otype - 1]); 1414 1415 return -1; 1416 } 1417 cur_trans = cur_trans->next; 1418 } 1419 /* duplicate rule, who cares */ 1420 if (cur_trans) 1421 continue; 1422 1423 new_trans = malloc(sizeof(*new_trans)); 1424 if (!new_trans) { 1425 ERR(state->handle, "Out of memory!"); 1426 return -1; 1427 } 1428 memset(new_trans, 0, sizeof(*new_trans)); 1429 new_trans->next = state->out->filename_trans; 1430 state->out->filename_trans = new_trans; 1431 1432 new_trans->name = strdup(cur_rule->name); 1433 if (!new_trans->name) { 1434 ERR(state->handle, "Out of memory!"); 1435 return -1; 1436 } 1437 new_trans->stype = i + 1; 1438 new_trans->ttype = j + 1; 1439 new_trans->tclass = cur_rule->tclass; 1440 new_trans->otype = mapped_otype; 1441 } 1442 } 1443 1444 ebitmap_destroy(&stypes); 1445 ebitmap_destroy(&ttypes); 1446 1447 cur_rule = cur_rule->next; 1448 } 1449 return 0; 1450 } 1451 1452 static int exp_rangetr_helper(uint32_t stype, uint32_t ttype, uint32_t tclass, 1453 mls_semantic_range_t * trange, 1454 expand_state_t * state) 1455 { 1456 range_trans_t *rt, *check_rt = state->out->range_tr; 1457 mls_range_t exp_range; 1458 int rc = -1; 1459 1460 if (mls_semantic_range_expand(trange, &exp_range, state->out, 1461 state->handle)) 1462 goto out; 1463 1464 /* check for duplicates/conflicts */ 1465 while (check_rt) { 1466 if ((check_rt->source_type == stype) && 1467 (check_rt->target_type == ttype) && 1468 (check_rt->target_class == tclass)) { 1469 if (mls_range_eq(&check_rt->target_range, &exp_range)) { 1470 /* duplicate */ 1471 break; 1472 } else { 1473 /* conflict */ 1474 ERR(state->handle, 1475 "Conflicting range trans rule %s %s : %s", 1476 state->out->p_type_val_to_name[stype - 1], 1477 state->out->p_type_val_to_name[ttype - 1], 1478 state->out->p_class_val_to_name[tclass - 1479 1]); 1480 goto out; 1481 } 1482 } 1483 check_rt = check_rt->next; 1484 } 1485 if (check_rt) { 1486 /* this is a dup - skip */ 1487 rc = 0; 1488 goto out; 1489 } 1490 1491 rt = (range_trans_t *) calloc(1, sizeof(range_trans_t)); 1492 if (!rt) { 1493 ERR(state->handle, "Out of memory!"); 1494 goto out; 1495 } 1496 1497 rt->next = state->out->range_tr; 1498 state->out->range_tr = rt; 1499 1500 rt->source_type = stype; 1501 rt->target_type = ttype; 1502 rt->target_class = tclass; 1503 if (mls_range_cpy(&rt->target_range, &exp_range)) { 1504 ERR(state->handle, "Out of memory!"); 1505 goto out; 1506 } 1507 1508 rc = 0; 1509 1510 out: 1511 mls_range_destroy(&exp_range); 1512 return rc; 1513 } 1514 1515 static int expand_range_trans(expand_state_t * state, 1516 range_trans_rule_t * rules) 1517 { 1518 unsigned int i, j, k; 1519 range_trans_rule_t *rule; 1520 1521 ebitmap_t stypes, ttypes; 1522 ebitmap_node_t *snode, *tnode, *cnode; 1523 1524 if (state->verbose) 1525 INFO(state->handle, "expanding range transitions"); 1526 1527 for (rule = rules; rule; rule = rule->next) { 1528 ebitmap_init(&stypes); 1529 ebitmap_init(&ttypes); 1530 1531 /* expand the type sets */ 1532 if (expand_convert_type_set(state->out, state->typemap, 1533 &rule->stypes, &stypes, 1)) { 1534 ERR(state->handle, "Out of memory!"); 1535 return -1; 1536 } 1537 if (expand_convert_type_set(state->out, state->typemap, 1538 &rule->ttypes, &ttypes, 1)) { 1539 ebitmap_destroy(&stypes); 1540 ERR(state->handle, "Out of memory!"); 1541 return -1; 1542 } 1543 1544 /* loop on source type */ 1545 ebitmap_for_each_bit(&stypes, snode, i) { 1546 if (!ebitmap_node_get_bit(snode, i)) 1547 continue; 1548 /* loop on target type */ 1549 ebitmap_for_each_bit(&ttypes, tnode, j) { 1550 if (!ebitmap_node_get_bit(tnode, j)) 1551 continue; 1552 /* loop on target class */ 1553 ebitmap_for_each_bit(&rule->tclasses, cnode, k) { 1554 if (!ebitmap_node_get_bit(cnode, k)) 1555 continue; 1556 1557 if (exp_rangetr_helper(i + 1, 1558 j + 1, 1559 k + 1, 1560 &rule->trange, 1561 state)) { 1562 ebitmap_destroy(&stypes); 1563 ebitmap_destroy(&ttypes); 1564 return -1; 1565 } 1566 } 1567 } 1568 } 1569 1570 ebitmap_destroy(&stypes); 1571 ebitmap_destroy(&ttypes); 1572 } 1573 1574 return 0; 1575 } 1576 1577 /* Search for an AV tab node within a hash table with the given key. 1578 * If the node does not exist, create it and return it; otherwise 1579 * return the pre-existing one. 1580 */ 1581 static avtab_ptr_t find_avtab_node(sepol_handle_t * handle, 1582 avtab_t * avtab, avtab_key_t * key, 1583 cond_av_list_t ** cond) 1584 { 1585 avtab_ptr_t node; 1586 avtab_datum_t avdatum; 1587 cond_av_list_t *nl; 1588 1589 node = avtab_search_node(avtab, key); 1590 1591 /* If this is for conditional policies, keep searching in case 1592 the node is part of my conditional avtab. */ 1593 if (cond) { 1594 while (node) { 1595 if (node->parse_context == cond) 1596 break; 1597 node = avtab_search_node_next(node, key->specified); 1598 } 1599 } 1600 1601 if (!node) { 1602 memset(&avdatum, 0, sizeof avdatum); 1603 /* this is used to get the node - insertion is actually unique */ 1604 node = avtab_insert_nonunique(avtab, key, &avdatum); 1605 if (!node) { 1606 ERR(handle, "hash table overflow"); 1607 return NULL; 1608 } 1609 if (cond) { 1610 node->parse_context = cond; 1611 nl = (cond_av_list_t *) malloc(sizeof(cond_av_list_t)); 1612 if (!nl) { 1613 ERR(handle, "Memory error"); 1614 return NULL; 1615 } 1616 memset(nl, 0, sizeof(cond_av_list_t)); 1617 nl->node = node; 1618 nl->next = *cond; 1619 *cond = nl; 1620 } 1621 } 1622 1623 return node; 1624 } 1625 1626 #define EXPAND_RULE_SUCCESS 1 1627 #define EXPAND_RULE_CONFLICT 0 1628 #define EXPAND_RULE_ERROR -1 1629 1630 static int expand_terule_helper(sepol_handle_t * handle, 1631 policydb_t * p, uint32_t * typemap, 1632 uint32_t specified, cond_av_list_t ** cond, 1633 cond_av_list_t ** other, uint32_t stype, 1634 uint32_t ttype, class_perm_node_t * perms, 1635 avtab_t * avtab, int enabled) 1636 { 1637 avtab_key_t avkey; 1638 avtab_datum_t *avdatump; 1639 avtab_ptr_t node; 1640 class_perm_node_t *cur; 1641 int conflict; 1642 uint32_t oldtype = 0, spec = 0; 1643 1644 if (specified & AVRULE_TRANSITION) { 1645 spec = AVTAB_TRANSITION; 1646 } else if (specified & AVRULE_MEMBER) { 1647 spec = AVTAB_MEMBER; 1648 } else if (specified & AVRULE_CHANGE) { 1649 spec = AVTAB_CHANGE; 1650 } else { 1651 assert(0); /* unreachable */ 1652 } 1653 1654 cur = perms; 1655 while (cur) { 1656 uint32_t remapped_data = 1657 typemap ? typemap[cur->data - 1] : cur->data; 1658 avkey.source_type = stype + 1; 1659 avkey.target_type = ttype + 1; 1660 avkey.target_class = cur->class; 1661 avkey.specified = spec; 1662 1663 conflict = 0; 1664 /* check to see if the expanded TE already exists -- 1665 * either in the global scope or in another 1666 * conditional AV tab */ 1667 node = avtab_search_node(&p->te_avtab, &avkey); 1668 if (node) { 1669 conflict = 1; 1670 } else { 1671 node = avtab_search_node(&p->te_cond_avtab, &avkey); 1672 if (node && node->parse_context != other) { 1673 conflict = 2; 1674 } 1675 } 1676 1677 if (conflict) { 1678 avdatump = &node->datum; 1679 if (specified & AVRULE_TRANSITION) { 1680 oldtype = avdatump->data; 1681 } else if (specified & AVRULE_MEMBER) { 1682 oldtype = avdatump->data; 1683 } else if (specified & AVRULE_CHANGE) { 1684 oldtype = avdatump->data; 1685 } 1686 1687 if (oldtype == remapped_data) { 1688 /* if the duplicate is inside the same scope (eg., unconditional 1689 * or in same conditional then ignore it */ 1690 if ((conflict == 1 && cond == NULL) 1691 || node->parse_context == cond) 1692 return EXPAND_RULE_SUCCESS; 1693 ERR(handle, "duplicate TE rule for %s %s:%s %s", 1694 p->p_type_val_to_name[avkey.source_type - 1695 1], 1696 p->p_type_val_to_name[avkey.target_type - 1697 1], 1698 p->p_class_val_to_name[avkey.target_class - 1699 1], 1700 p->p_type_val_to_name[oldtype - 1]); 1701 return EXPAND_RULE_CONFLICT; 1702 } 1703 ERR(handle, 1704 "conflicting TE rule for (%s, %s:%s): old was %s, new is %s", 1705 p->p_type_val_to_name[avkey.source_type - 1], 1706 p->p_type_val_to_name[avkey.target_type - 1], 1707 p->p_class_val_to_name[avkey.target_class - 1], 1708 p->p_type_val_to_name[oldtype - 1], 1709 p->p_type_val_to_name[remapped_data - 1]); 1710 return EXPAND_RULE_CONFLICT; 1711 } 1712 1713 node = find_avtab_node(handle, avtab, &avkey, cond); 1714 if (!node) 1715 return -1; 1716 if (enabled) { 1717 node->key.specified |= AVTAB_ENABLED; 1718 } else { 1719 node->key.specified &= ~AVTAB_ENABLED; 1720 } 1721 1722 avdatump = &node->datum; 1723 if (specified & AVRULE_TRANSITION) { 1724 avdatump->data = remapped_data; 1725 } else if (specified & AVRULE_MEMBER) { 1726 avdatump->data = remapped_data; 1727 } else if (specified & AVRULE_CHANGE) { 1728 avdatump->data = remapped_data; 1729 } else { 1730 assert(0); /* should never occur */ 1731 } 1732 1733 cur = cur->next; 1734 } 1735 1736 return EXPAND_RULE_SUCCESS; 1737 } 1738 1739 static int expand_avrule_helper(sepol_handle_t * handle, 1740 uint32_t specified, 1741 cond_av_list_t ** cond, 1742 uint32_t stype, uint32_t ttype, 1743 class_perm_node_t * perms, avtab_t * avtab, 1744 int enabled) 1745 { 1746 avtab_key_t avkey; 1747 avtab_datum_t *avdatump; 1748 avtab_ptr_t node; 1749 class_perm_node_t *cur; 1750 uint32_t spec = 0; 1751 1752 if (specified & AVRULE_ALLOWED) { 1753 spec = AVTAB_ALLOWED; 1754 } else if (specified & AVRULE_AUDITALLOW) { 1755 spec = AVTAB_AUDITALLOW; 1756 } else if (specified & AVRULE_AUDITDENY) { 1757 spec = AVTAB_AUDITDENY; 1758 } else if (specified & AVRULE_DONTAUDIT) { 1759 if (handle && handle->disable_dontaudit) 1760 return EXPAND_RULE_SUCCESS; 1761 spec = AVTAB_AUDITDENY; 1762 } else if (specified & AVRULE_NEVERALLOW) { 1763 spec = AVTAB_NEVERALLOW; 1764 } else { 1765 assert(0); /* unreachable */ 1766 } 1767 1768 cur = perms; 1769 while (cur) { 1770 avkey.source_type = stype + 1; 1771 avkey.target_type = ttype + 1; 1772 avkey.target_class = cur->class; 1773 avkey.specified = spec; 1774 1775 node = find_avtab_node(handle, avtab, &avkey, cond); 1776 if (!node) 1777 return EXPAND_RULE_ERROR; 1778 if (enabled) { 1779 node->key.specified |= AVTAB_ENABLED; 1780 } else { 1781 node->key.specified &= ~AVTAB_ENABLED; 1782 } 1783 1784 avdatump = &node->datum; 1785 if (specified & AVRULE_ALLOWED) { 1786 avdatump->data |= cur->data; 1787 } else if (specified & AVRULE_AUDITALLOW) { 1788 avdatump->data |= cur->data; 1789 } else if (specified & AVRULE_NEVERALLOW) { 1790 avdatump->data |= cur->data; 1791 } else if (specified & AVRULE_AUDITDENY) { 1792 /* Since a '0' in an auditdeny mask represents 1793 * a permission we do NOT want to audit 1794 * (dontaudit), we use the '&' operand to 1795 * ensure that all '0's in the mask are 1796 * retained (much unlike the allow and 1797 * auditallow cases). 1798 */ 1799 avdatump->data &= cur->data; 1800 } else if (specified & AVRULE_DONTAUDIT) { 1801 if (avdatump->data) 1802 avdatump->data &= ~cur->data; 1803 else 1804 avdatump->data = ~cur->data; 1805 } else { 1806 assert(0); /* should never occur */ 1807 } 1808 1809 cur = cur->next; 1810 } 1811 return EXPAND_RULE_SUCCESS; 1812 } 1813 1814 static int expand_rule_helper(sepol_handle_t * handle, 1815 policydb_t * p, uint32_t * typemap, 1816 avrule_t * source_rule, avtab_t * dest_avtab, 1817 cond_av_list_t ** cond, cond_av_list_t ** other, 1818 int enabled, 1819 ebitmap_t * stypes, ebitmap_t * ttypes) 1820 { 1821 unsigned int i, j; 1822 int retval; 1823 ebitmap_node_t *snode, *tnode; 1824 1825 ebitmap_for_each_bit(stypes, snode, i) { 1826 if (!ebitmap_node_get_bit(snode, i)) 1827 continue; 1828 if (source_rule->flags & RULE_SELF) { 1829 if (source_rule->specified & AVRULE_AV) { 1830 retval = expand_avrule_helper(handle, source_rule->specified, 1831 cond, i, i, source_rule->perms, 1832 dest_avtab, enabled); 1833 if (retval != EXPAND_RULE_SUCCESS) 1834 return retval; 1835 } else { 1836 retval = expand_terule_helper(handle, p, typemap, 1837 source_rule->specified, cond, 1838 other, i, i, source_rule->perms, 1839 dest_avtab, enabled); 1840 if (retval != EXPAND_RULE_SUCCESS) 1841 return retval; 1842 } 1843 } 1844 ebitmap_for_each_bit(ttypes, tnode, j) { 1845 if (!ebitmap_node_get_bit(tnode, j)) 1846 continue; 1847 if (source_rule->specified & AVRULE_AV) { 1848 retval = expand_avrule_helper(handle, source_rule->specified, 1849 cond, i, j, source_rule->perms, 1850 dest_avtab, enabled); 1851 if (retval != EXPAND_RULE_SUCCESS) 1852 return retval; 1853 } else { 1854 retval = expand_terule_helper(handle, p, typemap, 1855 source_rule->specified, cond, 1856 other, i, j, source_rule->perms, 1857 dest_avtab, enabled); 1858 if (retval != EXPAND_RULE_SUCCESS) 1859 return retval; 1860 } 1861 } 1862 } 1863 1864 return EXPAND_RULE_SUCCESS; 1865 } 1866 1867 /* 1868 * Expand a rule into a given avtab - checking for conflicting type 1869 * rules in the destination policy. Return EXPAND_RULE_SUCCESS on 1870 * success, EXPAND_RULE_CONFLICT if the rule conflicts with something 1871 * (and hence was not added), or EXPAND_RULE_ERROR on error. 1872 */ 1873 static int convert_and_expand_rule(sepol_handle_t * handle, 1874 policydb_t * dest_pol, uint32_t * typemap, 1875 avrule_t * source_rule, avtab_t * dest_avtab, 1876 cond_av_list_t ** cond, 1877 cond_av_list_t ** other, int enabled, 1878 int do_neverallow) 1879 { 1880 int retval; 1881 ebitmap_t stypes, ttypes; 1882 unsigned char alwaysexpand; 1883 1884 if (!do_neverallow && source_rule->specified & AVRULE_NEVERALLOW) 1885 return EXPAND_RULE_SUCCESS; 1886 1887 ebitmap_init(&stypes); 1888 ebitmap_init(&ttypes); 1889 1890 /* Force expansion for type rules and for self rules. */ 1891 alwaysexpand = ((source_rule->specified & AVRULE_TYPE) || 1892 (source_rule->flags & RULE_SELF)); 1893 1894 if (expand_convert_type_set 1895 (dest_pol, typemap, &source_rule->stypes, &stypes, alwaysexpand)) 1896 return EXPAND_RULE_ERROR; 1897 if (expand_convert_type_set 1898 (dest_pol, typemap, &source_rule->ttypes, &ttypes, alwaysexpand)) 1899 return EXPAND_RULE_ERROR; 1900 1901 retval = expand_rule_helper(handle, dest_pol, typemap, 1902 source_rule, dest_avtab, 1903 cond, other, enabled, &stypes, &ttypes); 1904 ebitmap_destroy(&stypes); 1905 ebitmap_destroy(&ttypes); 1906 return retval; 1907 } 1908 1909 static int cond_avrule_list_copy(policydb_t * dest_pol, avrule_t * source_rules, 1910 avtab_t * dest_avtab, cond_av_list_t ** list, 1911 cond_av_list_t ** other, uint32_t * typemap, 1912 int enabled, expand_state_t * state) 1913 { 1914 avrule_t *cur; 1915 1916 cur = source_rules; 1917 while (cur) { 1918 if (convert_and_expand_rule(state->handle, dest_pol, 1919 typemap, cur, dest_avtab, 1920 list, other, enabled, 1921 0) != EXPAND_RULE_SUCCESS) { 1922 return -1; 1923 } 1924 1925 cur = cur->next; 1926 } 1927 1928 return 0; 1929 } 1930 1931 static int cond_node_map_bools(expand_state_t * state, cond_node_t * cn) 1932 { 1933 cond_expr_t *cur; 1934 unsigned int i; 1935 1936 cur = cn->expr; 1937 while (cur) { 1938 if (cur->bool) 1939 cur->bool = state->boolmap[cur->bool - 1]; 1940 cur = cur->next; 1941 } 1942 1943 for (i = 0; i < min(cn->nbools, COND_MAX_BOOLS); i++) 1944 cn->bool_ids[i] = state->boolmap[cn->bool_ids[i] - 1]; 1945 1946 if (cond_normalize_expr(state->out, cn)) { 1947 ERR(state->handle, "Error while normalizing conditional"); 1948 return -1; 1949 } 1950 1951 return 0; 1952 } 1953 1954 /* copy the nodes in *reverse* order -- the result is that the last 1955 * given conditional appears first in the policy, so as to match the 1956 * behavior of the upstream compiler */ 1957 static int cond_node_copy(expand_state_t * state, cond_node_t * cn) 1958 { 1959 cond_node_t *new_cond, *tmp; 1960 1961 if (cn == NULL) { 1962 return 0; 1963 } 1964 if (cond_node_copy(state, cn->next)) { 1965 return -1; 1966 } 1967 1968 /* If current cond_node_t is of tunable, its effective branch 1969 * has been appended to its home decl->avrules list during link 1970 * and now we should just skip it. */ 1971 if (cn->flags & COND_NODE_FLAGS_TUNABLE) 1972 return 0; 1973 1974 if (cond_normalize_expr(state->base, cn)) { 1975 ERR(state->handle, "Error while normalizing conditional"); 1976 return -1; 1977 } 1978 1979 /* create a new temporary conditional node with the booleans 1980 * mapped */ 1981 tmp = cond_node_create(state->base, cn); 1982 if (!tmp) { 1983 ERR(state->handle, "Out of memory"); 1984 return -1; 1985 } 1986 1987 if (cond_node_map_bools(state, tmp)) { 1988 ERR(state->handle, "Error mapping booleans"); 1989 free(tmp); 1990 return -1; 1991 } 1992 1993 new_cond = cond_node_search(state->out, state->out->cond_list, tmp); 1994 if (!new_cond) { 1995 cond_node_destroy(tmp); 1996 free(tmp); 1997 ERR(state->handle, "Out of memory!"); 1998 return -1; 1999 } 2000 cond_node_destroy(tmp); 2001 free(tmp); 2002 2003 if (cond_avrule_list_copy 2004 (state->out, cn->avtrue_list, &state->out->te_cond_avtab, 2005 &new_cond->true_list, &new_cond->false_list, state->typemap, 2006 new_cond->cur_state, state)) 2007 return -1; 2008 if (cond_avrule_list_copy 2009 (state->out, cn->avfalse_list, &state->out->te_cond_avtab, 2010 &new_cond->false_list, &new_cond->true_list, state->typemap, 2011 !new_cond->cur_state, state)) 2012 return -1; 2013 2014 return 0; 2015 } 2016 2017 static int context_copy(context_struct_t * dst, context_struct_t * src, 2018 expand_state_t * state) 2019 { 2020 dst->user = state->usermap[src->user - 1]; 2021 dst->role = state->rolemap[src->role - 1]; 2022 dst->type = state->typemap[src->type - 1]; 2023 return mls_context_cpy(dst, src); 2024 } 2025 2026 static int ocontext_copy_xen(expand_state_t *state) 2027 { 2028 unsigned int i; 2029 ocontext_t *c, *n, *l; 2030 2031 for (i = 0; i < OCON_NUM; i++) { 2032 l = NULL; 2033 for (c = state->base->ocontexts[i]; c; c = c->next) { 2034 n = malloc(sizeof(ocontext_t)); 2035 if (!n) { 2036 ERR(state->handle, "Out of memory!"); 2037 return -1; 2038 } 2039 memset(n, 0, sizeof(ocontext_t)); 2040 if (l) 2041 l->next = n; 2042 else 2043 state->out->ocontexts[i] = n; 2044 l = n; 2045 switch (i) { 2046 case OCON_XEN_ISID: 2047 if (c->context[0].user == 0) { 2048 ERR(state->handle, 2049 "Missing context for %s initial sid", 2050 c->u.name); 2051 return -1; 2052 } 2053 n->sid[0] = c->sid[0]; 2054 break; 2055 case OCON_XEN_PIRQ: 2056 n->u.pirq = c->u.pirq; 2057 break; 2058 case OCON_XEN_IOPORT: 2059 n->u.ioport.low_ioport = c->u.ioport.low_ioport; 2060 n->u.ioport.high_ioport = 2061 c->u.ioport.high_ioport; 2062 break; 2063 case OCON_XEN_IOMEM: 2064 n->u.iomem.low_iomem = c->u.iomem.low_iomem; 2065 n->u.iomem.high_iomem = c->u.iomem.high_iomem; 2066 break; 2067 case OCON_XEN_PCIDEVICE: 2068 n->u.device = c->u.device; 2069 break; 2070 default: 2071 /* shouldn't get here */ 2072 ERR(state->handle, "Unknown ocontext"); 2073 return -1; 2074 } 2075 if (context_copy(&n->context[0], &c->context[0], 2076 state)) { 2077 ERR(state->handle, "Out of memory!"); 2078 return -1; 2079 } 2080 } 2081 } 2082 return 0; 2083 } 2084 2085 static int ocontext_copy_selinux(expand_state_t *state) 2086 { 2087 unsigned int i, j; 2088 ocontext_t *c, *n, *l; 2089 2090 for (i = 0; i < OCON_NUM; i++) { 2091 l = NULL; 2092 for (c = state->base->ocontexts[i]; c; c = c->next) { 2093 n = malloc(sizeof(ocontext_t)); 2094 if (!n) { 2095 ERR(state->handle, "Out of memory!"); 2096 return -1; 2097 } 2098 memset(n, 0, sizeof(ocontext_t)); 2099 if (l) 2100 l->next = n; 2101 else 2102 state->out->ocontexts[i] = n; 2103 l = n; 2104 switch (i) { 2105 case OCON_ISID: 2106 if (c->context[0].user == 0) { 2107 ERR(state->handle, 2108 "Missing context for %s initial sid", 2109 c->u.name); 2110 return -1; 2111 } 2112 n->sid[0] = c->sid[0]; 2113 break; 2114 case OCON_FS: /* FALLTHROUGH */ 2115 case OCON_NETIF: 2116 n->u.name = strdup(c->u.name); 2117 if (!n->u.name) { 2118 ERR(state->handle, "Out of memory!"); 2119 return -1; 2120 } 2121 if (context_copy 2122 (&n->context[1], &c->context[1], state)) { 2123 ERR(state->handle, "Out of memory!"); 2124 return -1; 2125 } 2126 break; 2127 case OCON_PORT: 2128 n->u.port.protocol = c->u.port.protocol; 2129 n->u.port.low_port = c->u.port.low_port; 2130 n->u.port.high_port = c->u.port.high_port; 2131 break; 2132 case OCON_NODE: 2133 n->u.node.addr = c->u.node.addr; 2134 n->u.node.mask = c->u.node.mask; 2135 break; 2136 case OCON_FSUSE: 2137 n->v.behavior = c->v.behavior; 2138 n->u.name = strdup(c->u.name); 2139 if (!n->u.name) { 2140 ERR(state->handle, "Out of memory!"); 2141 return -1; 2142 } 2143 break; 2144 case OCON_NODE6: 2145 for (j = 0; j < 4; j++) 2146 n->u.node6.addr[j] = c->u.node6.addr[j]; 2147 for (j = 0; j < 4; j++) 2148 n->u.node6.mask[j] = c->u.node6.mask[j]; 2149 break; 2150 default: 2151 /* shouldn't get here */ 2152 ERR(state->handle, "Unknown ocontext"); 2153 return -1; 2154 } 2155 if (context_copy(&n->context[0], &c->context[0], state)) { 2156 ERR(state->handle, "Out of memory!"); 2157 return -1; 2158 } 2159 } 2160 } 2161 return 0; 2162 } 2163 2164 static int ocontext_copy(expand_state_t *state, uint32_t target) 2165 { 2166 int rc = -1; 2167 switch (target) { 2168 case SEPOL_TARGET_SELINUX: 2169 rc = ocontext_copy_selinux(state); 2170 break; 2171 case SEPOL_TARGET_XEN: 2172 rc = ocontext_copy_xen(state); 2173 break; 2174 default: 2175 ERR(state->handle, "Unknown target"); 2176 return -1; 2177 } 2178 return rc; 2179 } 2180 2181 static int genfs_copy(expand_state_t * state) 2182 { 2183 ocontext_t *c, *newc, *l; 2184 genfs_t *genfs, *newgenfs, *end; 2185 2186 end = NULL; 2187 for (genfs = state->base->genfs; genfs; genfs = genfs->next) { 2188 newgenfs = malloc(sizeof(genfs_t)); 2189 if (!newgenfs) { 2190 ERR(state->handle, "Out of memory!"); 2191 return -1; 2192 } 2193 memset(newgenfs, 0, sizeof(genfs_t)); 2194 newgenfs->fstype = strdup(genfs->fstype); 2195 if (!newgenfs->fstype) { 2196 ERR(state->handle, "Out of memory!"); 2197 free(newgenfs); 2198 return -1; 2199 } 2200 2201 l = NULL; 2202 for (c = genfs->head; c; c = c->next) { 2203 newc = malloc(sizeof(ocontext_t)); 2204 if (!newc) { 2205 ERR(state->handle, "Out of memory!"); 2206 free(newgenfs->fstype); 2207 free(newgenfs); 2208 return -1; 2209 } 2210 memset(newc, 0, sizeof(ocontext_t)); 2211 newc->u.name = strdup(c->u.name); 2212 if (!newc->u.name) { 2213 ERR(state->handle, "Out of memory!"); 2214 free(newc); 2215 free(newgenfs->fstype); 2216 free(newgenfs); 2217 return -1; 2218 } 2219 newc->v.sclass = c->v.sclass; 2220 context_copy(&newc->context[0], &c->context[0], state); 2221 if (l) 2222 l->next = newc; 2223 else 2224 newgenfs->head = newc; 2225 l = newc; 2226 } 2227 if (!end) { 2228 state->out->genfs = newgenfs; 2229 } else { 2230 end->next = newgenfs; 2231 } 2232 end = newgenfs; 2233 } 2234 return 0; 2235 } 2236 2237 static int type_attr_map(hashtab_key_t key 2238 __attribute__ ((unused)), hashtab_datum_t datum, 2239 void *ptr) 2240 { 2241 type_datum_t *type; 2242 expand_state_t *state = ptr; 2243 policydb_t *p = state->out; 2244 unsigned int i; 2245 ebitmap_node_t *tnode; 2246 2247 type = (type_datum_t *) datum; 2248 if (type->flavor == TYPE_ATTRIB) { 2249 if (ebitmap_cpy(&p->attr_type_map[type->s.value - 1], 2250 &type->types)) { 2251 ERR(state->handle, "Out of memory!"); 2252 return -1; 2253 } 2254 ebitmap_for_each_bit(&type->types, tnode, i) { 2255 if (!ebitmap_node_get_bit(tnode, i)) 2256 continue; 2257 if (ebitmap_set_bit(&p->type_attr_map[i], 2258 type->s.value - 1, 1)) { 2259 ERR(state->handle, "Out of memory!"); 2260 return -1; 2261 } 2262 } 2263 } 2264 return 0; 2265 } 2266 2267 /* converts typeset using typemap and expands into ebitmap_t types using the attributes in the passed in policy. 2268 * this should not be called until after all the blocks have been processed and the attributes in target policy 2269 * are complete. */ 2270 int expand_convert_type_set(policydb_t * p, uint32_t * typemap, 2271 type_set_t * set, ebitmap_t * types, 2272 unsigned char alwaysexpand) 2273 { 2274 type_set_t tmpset; 2275 2276 type_set_init(&tmpset); 2277 2278 if (map_ebitmap(&set->types, &tmpset.types, typemap)) 2279 return -1; 2280 2281 if (map_ebitmap(&set->negset, &tmpset.negset, typemap)) 2282 return -1; 2283 2284 tmpset.flags = set->flags; 2285 2286 if (type_set_expand(&tmpset, types, p, alwaysexpand)) 2287 return -1; 2288 2289 type_set_destroy(&tmpset); 2290 2291 return 0; 2292 } 2293 2294 /* Expand a rule into a given avtab - checking for conflicting type 2295 * rules. Return 1 on success, 0 if the rule conflicts with something 2296 * (and hence was not added), or -1 on error. */ 2297 int expand_rule(sepol_handle_t * handle, 2298 policydb_t * source_pol, 2299 avrule_t * source_rule, avtab_t * dest_avtab, 2300 cond_av_list_t ** cond, cond_av_list_t ** other, int enabled) 2301 { 2302 int retval; 2303 ebitmap_t stypes, ttypes; 2304 2305 if (source_rule->specified & AVRULE_NEVERALLOW) 2306 return 1; 2307 2308 ebitmap_init(&stypes); 2309 ebitmap_init(&ttypes); 2310 2311 if (type_set_expand(&source_rule->stypes, &stypes, source_pol, 1)) 2312 return -1; 2313 if (type_set_expand(&source_rule->ttypes, &ttypes, source_pol, 1)) 2314 return -1; 2315 retval = expand_rule_helper(handle, source_pol, NULL, 2316 source_rule, dest_avtab, 2317 cond, other, enabled, &stypes, &ttypes); 2318 ebitmap_destroy(&stypes); 2319 ebitmap_destroy(&ttypes); 2320 return retval; 2321 } 2322 2323 /* Expand a role set into an ebitmap containing the roles. 2324 * This handles the attribute and flags. 2325 * Attribute expansion depends on if the rolemap is available. 2326 * During module compile the rolemap is not available, the 2327 * possible duplicates of a regular role and the role attribute 2328 * the regular role belongs to could be properly handled by 2329 * copy_role_trans and copy_role_allow. 2330 */ 2331 int role_set_expand(role_set_t * x, ebitmap_t * r, policydb_t * out, policydb_t * base, uint32_t * rolemap) 2332 { 2333 unsigned int i; 2334 ebitmap_node_t *rnode; 2335 ebitmap_t mapped_roles, roles; 2336 policydb_t *p = out; 2337 role_datum_t *role; 2338 2339 ebitmap_init(r); 2340 2341 if (x->flags & ROLE_STAR) { 2342 for (i = 0; i < p->p_roles.nprim++; i++) 2343 if (ebitmap_set_bit(r, i, 1)) 2344 return -1; 2345 return 0; 2346 } 2347 2348 ebitmap_init(&mapped_roles); 2349 ebitmap_init(&roles); 2350 2351 if (rolemap) { 2352 assert(base != NULL); 2353 ebitmap_for_each_bit(&x->roles, rnode, i) { 2354 if (ebitmap_node_get_bit(rnode, i)) { 2355 /* take advantage of p_role_val_to_struct[] 2356 * of the base module */ 2357 role = base->role_val_to_struct[i]; 2358 assert(role != NULL); 2359 if (role->flavor == ROLE_ATTRIB) { 2360 if (ebitmap_union(&roles, 2361 &role->roles)) 2362 goto bad; 2363 } else { 2364 if (ebitmap_set_bit(&roles, i, 1)) 2365 goto bad; 2366 } 2367 } 2368 } 2369 if (map_ebitmap(&roles, &mapped_roles, rolemap)) 2370 goto bad; 2371 } else { 2372 if (ebitmap_cpy(&mapped_roles, &x->roles)) 2373 goto bad; 2374 } 2375 2376 ebitmap_for_each_bit(&mapped_roles, rnode, i) { 2377 if (ebitmap_node_get_bit(rnode, i)) { 2378 if (ebitmap_set_bit(r, i, 1)) 2379 goto bad; 2380 } 2381 } 2382 2383 ebitmap_destroy(&mapped_roles); 2384 ebitmap_destroy(&roles); 2385 2386 /* if role is to be complimented, invert the entire bitmap here */ 2387 if (x->flags & ROLE_COMP) { 2388 for (i = 0; i < ebitmap_length(r); i++) { 2389 if (ebitmap_get_bit(r, i)) { 2390 if (ebitmap_set_bit(r, i, 0)) 2391 return -1; 2392 } else { 2393 if (ebitmap_set_bit(r, i, 1)) 2394 return -1; 2395 } 2396 } 2397 } 2398 return 0; 2399 2400 bad: 2401 ebitmap_destroy(&mapped_roles); 2402 ebitmap_destroy(&roles); 2403 return -1; 2404 } 2405 2406 /* Expand a type set into an ebitmap containing the types. This 2407 * handles the negset, attributes, and flags. 2408 * Attribute expansion depends on several factors: 2409 * - if alwaysexpand is 1, then they will be expanded, 2410 * - if the type set has a negset or flags, then they will be expanded, 2411 * - otherwise, they will not be expanded. 2412 */ 2413 int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, 2414 unsigned char alwaysexpand) 2415 { 2416 unsigned int i; 2417 ebitmap_t types, neg_types; 2418 ebitmap_node_t *tnode; 2419 2420 ebitmap_init(&types); 2421 ebitmap_init(t); 2422 2423 if (alwaysexpand || ebitmap_length(&set->negset) || set->flags) { 2424 /* First go through the types and OR all the attributes to types */ 2425 ebitmap_for_each_bit(&set->types, tnode, i) { 2426 if (ebitmap_node_get_bit(tnode, i)) { 2427 if (p->type_val_to_struct[i]->flavor == 2428 TYPE_ATTRIB) { 2429 if (ebitmap_union 2430 (&types, 2431 &p->type_val_to_struct[i]-> 2432 types)) { 2433 return -1; 2434 } 2435 } else { 2436 if (ebitmap_set_bit(&types, i, 1)) { 2437 return -1; 2438 } 2439 } 2440 } 2441 } 2442 } else { 2443 /* No expansion of attributes, just copy the set as is. */ 2444 if (ebitmap_cpy(&types, &set->types)) 2445 return -1; 2446 } 2447 2448 /* Now do the same thing for negset */ 2449 ebitmap_init(&neg_types); 2450 ebitmap_for_each_bit(&set->negset, tnode, i) { 2451 if (ebitmap_node_get_bit(tnode, i)) { 2452 if (p->type_val_to_struct[i] && 2453 p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) { 2454 if (ebitmap_union 2455 (&neg_types, 2456 &p->type_val_to_struct[i]->types)) { 2457 return -1; 2458 } 2459 } else { 2460 if (ebitmap_set_bit(&neg_types, i, 1)) { 2461 return -1; 2462 } 2463 } 2464 } 2465 } 2466 2467 if (set->flags & TYPE_STAR) { 2468 /* set all types not in neg_types */ 2469 for (i = 0; i < p->p_types.nprim; i++) { 2470 if (ebitmap_get_bit(&neg_types, i)) 2471 continue; 2472 if (p->type_val_to_struct[i] && 2473 p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) 2474 continue; 2475 if (ebitmap_set_bit(t, i, 1)) 2476 return -1; 2477 } 2478 goto out; 2479 } 2480 2481 ebitmap_for_each_bit(&types, tnode, i) { 2482 if (ebitmap_node_get_bit(tnode, i) 2483 && (!ebitmap_get_bit(&neg_types, i))) 2484 if (ebitmap_set_bit(t, i, 1)) 2485 return -1; 2486 } 2487 2488 if (set->flags & TYPE_COMP) { 2489 for (i = 0; i < p->p_types.nprim; i++) { 2490 if (p->type_val_to_struct[i] && 2491 p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) { 2492 assert(!ebitmap_get_bit(t, i)); 2493 continue; 2494 } 2495 if (ebitmap_get_bit(t, i)) { 2496 if (ebitmap_set_bit(t, i, 0)) 2497 return -1; 2498 } else { 2499 if (ebitmap_set_bit(t, i, 1)) 2500 return -1; 2501 } 2502 } 2503 } 2504 2505 out: 2506 2507 ebitmap_destroy(&types); 2508 ebitmap_destroy(&neg_types); 2509 2510 return 0; 2511 } 2512 2513 static int copy_neverallow(policydb_t * dest_pol, uint32_t * typemap, 2514 avrule_t * source_rule) 2515 { 2516 ebitmap_t stypes, ttypes; 2517 avrule_t *avrule; 2518 class_perm_node_t *cur_perm, *new_perm, *tail_perm; 2519 2520 ebitmap_init(&stypes); 2521 ebitmap_init(&ttypes); 2522 2523 if (expand_convert_type_set 2524 (dest_pol, typemap, &source_rule->stypes, &stypes, 1)) 2525 return -1; 2526 if (expand_convert_type_set 2527 (dest_pol, typemap, &source_rule->ttypes, &ttypes, 1)) 2528 return -1; 2529 2530 avrule = (avrule_t *) malloc(sizeof(avrule_t)); 2531 if (!avrule) 2532 return -1; 2533 2534 avrule_init(avrule); 2535 avrule->specified = AVRULE_NEVERALLOW; 2536 avrule->line = source_rule->line; 2537 avrule->flags = source_rule->flags; 2538 2539 if (ebitmap_cpy(&avrule->stypes.types, &stypes)) 2540 goto err; 2541 2542 if (ebitmap_cpy(&avrule->ttypes.types, &ttypes)) 2543 goto err; 2544 2545 cur_perm = source_rule->perms; 2546 tail_perm = NULL; 2547 while (cur_perm) { 2548 new_perm = 2549 (class_perm_node_t *) malloc(sizeof(class_perm_node_t)); 2550 if (!new_perm) 2551 goto err; 2552 class_perm_node_init(new_perm); 2553 new_perm->class = cur_perm->class; 2554 assert(new_perm->class); 2555 2556 /* once we have modules with permissions we'll need to map the permissions (and classes) */ 2557 new_perm->data = cur_perm->data; 2558 2559 if (!avrule->perms) 2560 avrule->perms = new_perm; 2561 2562 if (tail_perm) 2563 tail_perm->next = new_perm; 2564 tail_perm = new_perm; 2565 cur_perm = cur_perm->next; 2566 } 2567 2568 /* just prepend the avrule to the first branch; it'll never be 2569 written to disk */ 2570 if (!dest_pol->global->branch_list->avrules) 2571 dest_pol->global->branch_list->avrules = avrule; 2572 else { 2573 avrule->next = dest_pol->global->branch_list->avrules; 2574 dest_pol->global->branch_list->avrules = avrule; 2575 } 2576 2577 ebitmap_destroy(&stypes); 2578 ebitmap_destroy(&ttypes); 2579 2580 return 0; 2581 2582 err: 2583 ebitmap_destroy(&stypes); 2584 ebitmap_destroy(&ttypes); 2585 ebitmap_destroy(&avrule->stypes.types); 2586 ebitmap_destroy(&avrule->ttypes.types); 2587 cur_perm = avrule->perms; 2588 while (cur_perm) { 2589 tail_perm = cur_perm->next; 2590 free(cur_perm); 2591 cur_perm = tail_perm; 2592 } 2593 free(avrule); 2594 return -1; 2595 } 2596 2597 /* 2598 * Expands the avrule blocks for a policy. RBAC rules are copied. Neverallow 2599 * rules are copied or expanded as per the settings in the state object; all 2600 * other AV rules are expanded. If neverallow rules are expanded, they are not 2601 * copied, otherwise they are copied for later use by the assertion checker. 2602 */ 2603 static int copy_and_expand_avrule_block(expand_state_t * state) 2604 { 2605 avrule_block_t *curblock = state->base->global; 2606 avrule_block_t *prevblock; 2607 int retval = -1; 2608 2609 if (avtab_alloc(&state->out->te_avtab, MAX_AVTAB_SIZE)) { 2610 ERR(state->handle, "Out of Memory!"); 2611 return -1; 2612 } 2613 2614 if (avtab_alloc(&state->out->te_cond_avtab, MAX_AVTAB_SIZE)) { 2615 ERR(state->handle, "Out of Memory!"); 2616 return -1; 2617 } 2618 2619 while (curblock) { 2620 avrule_decl_t *decl = curblock->enabled; 2621 avrule_t *cur_avrule; 2622 2623 if (decl == NULL) { 2624 /* nothing was enabled within this block */ 2625 goto cont; 2626 } 2627 2628 /* copy role allows and role trans */ 2629 if (copy_role_allows(state, decl->role_allow_rules) != 0 || 2630 copy_role_trans(state, decl->role_tr_rules) != 0) { 2631 goto cleanup; 2632 } 2633 2634 if (expand_filename_trans(state, decl->filename_trans_rules)) 2635 goto cleanup; 2636 2637 /* expand the range transition rules */ 2638 if (expand_range_trans(state, decl->range_tr_rules)) 2639 goto cleanup; 2640 2641 /* copy rules */ 2642 cur_avrule = decl->avrules; 2643 while (cur_avrule != NULL) { 2644 if (!(state->expand_neverallow) 2645 && cur_avrule->specified & AVRULE_NEVERALLOW) { 2646 /* copy this over directly so that assertions are checked later */ 2647 if (copy_neverallow 2648 (state->out, state->typemap, cur_avrule)) 2649 ERR(state->handle, 2650 "Error while copying neverallow."); 2651 } else { 2652 if (cur_avrule->specified & AVRULE_NEVERALLOW) { 2653 state->out->unsupported_format = 1; 2654 } 2655 if (convert_and_expand_rule 2656 (state->handle, state->out, state->typemap, 2657 cur_avrule, &state->out->te_avtab, NULL, 2658 NULL, 0, 2659 state->expand_neverallow) != 2660 EXPAND_RULE_SUCCESS) { 2661 goto cleanup; 2662 } 2663 } 2664 cur_avrule = cur_avrule->next; 2665 } 2666 2667 /* copy conditional rules */ 2668 if (cond_node_copy(state, decl->cond_list)) 2669 goto cleanup; 2670 2671 cont: 2672 prevblock = curblock; 2673 curblock = curblock->next; 2674 2675 if (state->handle && state->handle->expand_consume_base) { 2676 /* set base top avrule block in case there 2677 * is an error condition and the policy needs 2678 * to be destroyed */ 2679 state->base->global = curblock; 2680 avrule_block_destroy(prevblock); 2681 } 2682 } 2683 2684 retval = 0; 2685 2686 cleanup: 2687 return retval; 2688 } 2689 2690 /* 2691 * This function allows external users of the library (such as setools) to 2692 * expand only the avrules and optionally perform expansion of neverallow rules 2693 * or expand into the same policy for analysis purposes. 2694 */ 2695 int expand_module_avrules(sepol_handle_t * handle, policydb_t * base, 2696 policydb_t * out, uint32_t * typemap, 2697 uint32_t * boolmap, uint32_t * rolemap, 2698 uint32_t * usermap, int verbose, 2699 int expand_neverallow) 2700 { 2701 expand_state_t state; 2702 2703 expand_state_init(&state); 2704 2705 state.base = base; 2706 state.out = out; 2707 state.typemap = typemap; 2708 state.boolmap = boolmap; 2709 state.rolemap = rolemap; 2710 state.usermap = usermap; 2711 state.handle = handle; 2712 state.verbose = verbose; 2713 state.expand_neverallow = expand_neverallow; 2714 2715 return copy_and_expand_avrule_block(&state); 2716 } 2717 2718 static void discard_tunables(sepol_handle_t *sh, policydb_t *pol) 2719 { 2720 avrule_block_t *block; 2721 avrule_decl_t *decl; 2722 cond_node_t *cur_node; 2723 cond_expr_t *cur_expr; 2724 int cur_state, preserve_tunables = 0; 2725 avrule_t *tail, *to_be_appended; 2726 2727 if (sh && sh->preserve_tunables) 2728 preserve_tunables = 1; 2729 2730 /* Iterate through all cond_node of all enabled decls, if a cond_node 2731 * is about tunable, calculate its state value and concatenate one of 2732 * its avrule list to the current decl->avrules list. On the other 2733 * hand, the disabled unused branch of a tunable would be discarded. 2734 * 2735 * Note, such tunable cond_node would be skipped over in expansion, 2736 * so we won't have to worry about removing it from decl->cond_list 2737 * here :-) 2738 * 2739 * If tunables are requested to be preserved then they would be 2740 * "transformed" as booleans by having their TUNABLE flag cleared. 2741 */ 2742 for (block = pol->global; block != NULL; block = block->next) { 2743 decl = block->enabled; 2744 if (decl == NULL || decl->enabled == 0) 2745 continue; 2746 2747 tail = decl->avrules; 2748 while (tail && tail->next) 2749 tail = tail->next; 2750 2751 for (cur_node = decl->cond_list; cur_node != NULL; 2752 cur_node = cur_node->next) { 2753 int booleans, tunables, i; 2754 cond_bool_datum_t *booldatum; 2755 cond_bool_datum_t *tmp[COND_EXPR_MAXDEPTH]; 2756 2757 booleans = tunables = 0; 2758 memset(tmp, 0, sizeof(cond_bool_datum_t *) * COND_EXPR_MAXDEPTH); 2759 2760 for (cur_expr = cur_node->expr; cur_expr != NULL; 2761 cur_expr = cur_expr->next) { 2762 if (cur_expr->expr_type != COND_BOOL) 2763 continue; 2764 booldatum = pol->bool_val_to_struct[cur_expr->bool - 1]; 2765 if (booldatum->flags & COND_BOOL_FLAGS_TUNABLE) 2766 tmp[tunables++] = booldatum; 2767 else 2768 booleans++; 2769 } 2770 2771 /* bool_copy_callback() at link phase has ensured 2772 * that no mixture of tunables and booleans in one 2773 * expression. However, this would be broken by the 2774 * request to preserve tunables */ 2775 if (!preserve_tunables) 2776 assert(!(booleans && tunables)); 2777 2778 if (booleans || preserve_tunables) { 2779 cur_node->flags &= ~COND_NODE_FLAGS_TUNABLE; 2780 if (tunables) { 2781 for (i = 0; i < tunables; i++) 2782 tmp[i]->flags &= ~COND_BOOL_FLAGS_TUNABLE; 2783 } 2784 } else { 2785 cur_node->flags |= COND_NODE_FLAGS_TUNABLE; 2786 cur_state = cond_evaluate_expr(pol, cur_node->expr); 2787 if (cur_state == -1) { 2788 printf("Expression result was " 2789 "undefined, skipping all" 2790 "rules\n"); 2791 continue; 2792 } 2793 2794 to_be_appended = (cur_state == 1) ? 2795 cur_node->avtrue_list : cur_node->avfalse_list; 2796 2797 if (tail) 2798 tail->next = to_be_appended; 2799 else 2800 tail = decl->avrules = to_be_appended; 2801 2802 /* Now that the effective branch has been 2803 * appended, neutralize its original pointer */ 2804 if (cur_state == 1) 2805 cur_node->avtrue_list = NULL; 2806 else 2807 cur_node->avfalse_list = NULL; 2808 2809 /* Update the tail of decl->avrules for 2810 * further concatenation */ 2811 while (tail && tail->next) 2812 tail = tail->next; 2813 } 2814 } 2815 } 2816 } 2817 2818 /* Linking should always be done before calling expand, even if 2819 * there is only a base since all optionals are dealt with at link time 2820 * the base passed in should be indexed and avrule blocks should be 2821 * enabled. 2822 */ 2823 int expand_module(sepol_handle_t * handle, 2824 policydb_t * base, policydb_t * out, int verbose, int check) 2825 { 2826 int retval = -1; 2827 unsigned int i; 2828 expand_state_t state; 2829 avrule_block_t *curblock; 2830 2831 /* Append tunable's avtrue_list or avfalse_list to the avrules list 2832 * of its home decl depending on its state value, so that the effect 2833 * rules of a tunable would be added to te_avtab permanently. Whereas 2834 * the disabled unused branch would be discarded. 2835 * 2836 * Originally this function is called at the very end of link phase, 2837 * however, we need to keep the linked policy intact for analysis 2838 * purpose. */ 2839 discard_tunables(handle, base); 2840 2841 expand_state_init(&state); 2842 2843 state.verbose = verbose; 2844 state.typemap = NULL; 2845 state.base = base; 2846 state.out = out; 2847 state.handle = handle; 2848 2849 if (base->policy_type != POLICY_BASE) { 2850 ERR(handle, "Target of expand was not a base policy."); 2851 return -1; 2852 } 2853 2854 state.out->policy_type = POLICY_KERN; 2855 state.out->policyvers = POLICYDB_VERSION_MAX; 2856 2857 /* Copy mls state from base to out */ 2858 out->mls = base->mls; 2859 out->handle_unknown = base->handle_unknown; 2860 2861 /* Copy target from base to out */ 2862 out->target_platform = base->target_platform; 2863 2864 /* Copy policy capabilities */ 2865 if (ebitmap_cpy(&out->policycaps, &base->policycaps)) { 2866 ERR(handle, "Out of memory!"); 2867 goto cleanup; 2868 } 2869 2870 if ((state.typemap = 2871 (uint32_t *) calloc(state.base->p_types.nprim, 2872 sizeof(uint32_t))) == NULL) { 2873 ERR(handle, "Out of memory!"); 2874 goto cleanup; 2875 } 2876 2877 state.boolmap = (uint32_t *)calloc(state.base->p_bools.nprim, sizeof(uint32_t)); 2878 if (!state.boolmap) { 2879 ERR(handle, "Out of memory!"); 2880 goto cleanup; 2881 } 2882 2883 state.rolemap = (uint32_t *)calloc(state.base->p_roles.nprim, sizeof(uint32_t)); 2884 if (!state.rolemap) { 2885 ERR(handle, "Out of memory!"); 2886 goto cleanup; 2887 } 2888 2889 state.usermap = (uint32_t *)calloc(state.base->p_users.nprim, sizeof(uint32_t)); 2890 if (!state.usermap) { 2891 ERR(handle, "Out of memory!"); 2892 goto cleanup; 2893 } 2894 2895 /* order is important - types must be first */ 2896 2897 /* copy types */ 2898 if (hashtab_map(state.base->p_types.table, type_copy_callback, &state)) { 2899 goto cleanup; 2900 } 2901 2902 /* convert attribute type sets */ 2903 if (hashtab_map 2904 (state.base->p_types.table, attr_convert_callback, &state)) { 2905 goto cleanup; 2906 } 2907 2908 /* copy commons */ 2909 if (hashtab_map 2910 (state.base->p_commons.table, common_copy_callback, &state)) { 2911 goto cleanup; 2912 } 2913 2914 /* copy classes, note, this does not copy constraints, constraints can't be 2915 * copied until after all the blocks have been processed and attributes are complete */ 2916 if (hashtab_map 2917 (state.base->p_classes.table, class_copy_callback, &state)) { 2918 goto cleanup; 2919 } 2920 2921 /* copy type bounds */ 2922 if (hashtab_map(state.base->p_types.table, 2923 type_bounds_copy_callback, &state)) 2924 goto cleanup; 2925 2926 /* copy aliases */ 2927 if (hashtab_map(state.base->p_types.table, alias_copy_callback, &state)) 2928 goto cleanup; 2929 2930 /* index here so that type indexes are available for role_copy_callback */ 2931 if (policydb_index_others(handle, out, verbose)) { 2932 ERR(handle, "Error while indexing out symbols"); 2933 goto cleanup; 2934 } 2935 2936 /* copy roles */ 2937 if (hashtab_map(state.base->p_roles.table, role_copy_callback, &state)) 2938 goto cleanup; 2939 if (hashtab_map(state.base->p_roles.table, 2940 role_bounds_copy_callback, &state)) 2941 goto cleanup; 2942 /* escalate the type_set_t in a role attribute to all regular roles 2943 * that belongs to it. */ 2944 if (hashtab_map(state.base->p_roles.table, role_fix_callback, &state)) 2945 goto cleanup; 2946 2947 /* copy MLS's sensitivity level and categories - this needs to be done 2948 * before expanding users (they need to be indexed too) */ 2949 if (hashtab_map(state.base->p_levels.table, sens_copy_callback, &state)) 2950 goto cleanup; 2951 if (hashtab_map(state.base->p_cats.table, cats_copy_callback, &state)) 2952 goto cleanup; 2953 if (policydb_index_others(handle, out, verbose)) { 2954 ERR(handle, "Error while indexing out symbols"); 2955 goto cleanup; 2956 } 2957 2958 /* copy users */ 2959 if (hashtab_map(state.base->p_users.table, user_copy_callback, &state)) 2960 goto cleanup; 2961 if (hashtab_map(state.base->p_users.table, 2962 user_bounds_copy_callback, &state)) 2963 goto cleanup; 2964 2965 /* copy bools */ 2966 if (hashtab_map(state.base->p_bools.table, bool_copy_callback, &state)) 2967 goto cleanup; 2968 2969 if (policydb_index_classes(out)) { 2970 ERR(handle, "Error while indexing out classes"); 2971 goto cleanup; 2972 } 2973 if (policydb_index_others(handle, out, verbose)) { 2974 ERR(handle, "Error while indexing out symbols"); 2975 goto cleanup; 2976 } 2977 2978 /* loop through all decls and union attributes, roles, users */ 2979 for (curblock = state.base->global; curblock != NULL; 2980 curblock = curblock->next) { 2981 avrule_decl_t *decl = curblock->enabled; 2982 2983 if (decl == NULL) { 2984 /* nothing was enabled within this block */ 2985 continue; 2986 } 2987 2988 /* convert attribute type sets */ 2989 if (hashtab_map 2990 (decl->p_types.table, attr_convert_callback, &state)) { 2991 goto cleanup; 2992 } 2993 2994 /* copy roles */ 2995 if (hashtab_map 2996 (decl->p_roles.table, role_copy_callback, &state)) 2997 goto cleanup; 2998 2999 /* copy users */ 3000 if (hashtab_map 3001 (decl->p_users.table, user_copy_callback, &state)) 3002 goto cleanup; 3003 3004 } 3005 3006 /* remap role dominates bitmaps */ 3007 if (hashtab_map(state.out->p_roles.table, role_remap_dominates, &state)) { 3008 goto cleanup; 3009 } 3010 3011 if (copy_and_expand_avrule_block(&state) < 0) { 3012 ERR(handle, "Error during expand"); 3013 goto cleanup; 3014 } 3015 3016 /* copy constraints */ 3017 if (hashtab_map 3018 (state.base->p_classes.table, constraint_copy_callback, &state)) { 3019 goto cleanup; 3020 } 3021 3022 cond_optimize_lists(state.out->cond_list); 3023 evaluate_conds(state.out); 3024 3025 /* copy ocontexts */ 3026 if (ocontext_copy(&state, out->target_platform)) 3027 goto cleanup; 3028 3029 /* copy genfs */ 3030 if (genfs_copy(&state)) 3031 goto cleanup; 3032 3033 /* Build the type<->attribute maps and remove attributes. */ 3034 state.out->attr_type_map = malloc(state.out->p_types.nprim * 3035 sizeof(ebitmap_t)); 3036 state.out->type_attr_map = malloc(state.out->p_types.nprim * 3037 sizeof(ebitmap_t)); 3038 if (!state.out->attr_type_map || !state.out->type_attr_map) { 3039 ERR(handle, "Out of memory!"); 3040 goto cleanup; 3041 } 3042 for (i = 0; i < state.out->p_types.nprim; i++) { 3043 ebitmap_init(&state.out->type_attr_map[i]); 3044 ebitmap_init(&state.out->attr_type_map[i]); 3045 /* add the type itself as the degenerate case */ 3046 if (ebitmap_set_bit(&state.out->type_attr_map[i], i, 1)) { 3047 ERR(handle, "Out of memory!"); 3048 goto cleanup; 3049 } 3050 } 3051 if (hashtab_map(state.out->p_types.table, type_attr_map, &state)) 3052 goto cleanup; 3053 if (check) { 3054 if (hierarchy_check_constraints(handle, state.out)) 3055 goto cleanup; 3056 3057 if (check_assertions 3058 (handle, state.out, 3059 state.out->global->branch_list->avrules)) 3060 goto cleanup; 3061 } 3062 3063 retval = 0; 3064 3065 cleanup: 3066 free(state.typemap); 3067 free(state.boolmap); 3068 free(state.rolemap); 3069 free(state.usermap); 3070 return retval; 3071 } 3072 3073 static int expand_avtab_insert(avtab_t * a, avtab_key_t * k, avtab_datum_t * d) 3074 { 3075 avtab_ptr_t node; 3076 avtab_datum_t *avd; 3077 int rc; 3078 3079 node = avtab_search_node(a, k); 3080 if (!node) { 3081 rc = avtab_insert(a, k, d); 3082 if (rc) 3083 ERR(NULL, "Out of memory!"); 3084 return rc; 3085 } 3086 3087 if ((k->specified & AVTAB_ENABLED) != 3088 (node->key.specified & AVTAB_ENABLED)) { 3089 node = avtab_insert_nonunique(a, k, d); 3090 if (!node) { 3091 ERR(NULL, "Out of memory!"); 3092 return -1; 3093 } 3094 return 0; 3095 } 3096 3097 avd = &node->datum; 3098 switch (k->specified & ~AVTAB_ENABLED) { 3099 case AVTAB_ALLOWED: 3100 case AVTAB_AUDITALLOW: 3101 avd->data |= d->data; 3102 break; 3103 case AVTAB_AUDITDENY: 3104 avd->data &= d->data; 3105 break; 3106 default: 3107 ERR(NULL, "Type conflict!"); 3108 return -1; 3109 } 3110 3111 return 0; 3112 } 3113 3114 struct expand_avtab_data { 3115 avtab_t *expa; 3116 policydb_t *p; 3117 3118 }; 3119 3120 static int expand_avtab_node(avtab_key_t * k, avtab_datum_t * d, void *args) 3121 { 3122 struct expand_avtab_data *ptr = args; 3123 avtab_t *expa = ptr->expa; 3124 policydb_t *p = ptr->p; 3125 type_datum_t *stype = p->type_val_to_struct[k->source_type - 1]; 3126 type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1]; 3127 ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1]; 3128 ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1]; 3129 ebitmap_node_t *snode, *tnode; 3130 unsigned int i, j; 3131 avtab_key_t newkey; 3132 int rc; 3133 3134 newkey.target_class = k->target_class; 3135 newkey.specified = k->specified; 3136 3137 if (stype->flavor != TYPE_ATTRIB && ttype->flavor != TYPE_ATTRIB) { 3138 /* Both are individual types, no expansion required. */ 3139 return expand_avtab_insert(expa, k, d); 3140 } 3141 3142 if (stype->flavor != TYPE_ATTRIB) { 3143 /* Source is an individual type, target is an attribute. */ 3144 newkey.source_type = k->source_type; 3145 ebitmap_for_each_bit(tattr, tnode, j) { 3146 if (!ebitmap_node_get_bit(tnode, j)) 3147 continue; 3148 newkey.target_type = j + 1; 3149 rc = expand_avtab_insert(expa, &newkey, d); 3150 if (rc) 3151 return -1; 3152 } 3153 return 0; 3154 } 3155 3156 if (ttype->flavor != TYPE_ATTRIB) { 3157 /* Target is an individual type, source is an attribute. */ 3158 newkey.target_type = k->target_type; 3159 ebitmap_for_each_bit(sattr, snode, i) { 3160 if (!ebitmap_node_get_bit(snode, i)) 3161 continue; 3162 newkey.source_type = i + 1; 3163 rc = expand_avtab_insert(expa, &newkey, d); 3164 if (rc) 3165 return -1; 3166 } 3167 return 0; 3168 } 3169 3170 /* Both source and target type are attributes. */ 3171 ebitmap_for_each_bit(sattr, snode, i) { 3172 if (!ebitmap_node_get_bit(snode, i)) 3173 continue; 3174 ebitmap_for_each_bit(tattr, tnode, j) { 3175 if (!ebitmap_node_get_bit(tnode, j)) 3176 continue; 3177 newkey.source_type = i + 1; 3178 newkey.target_type = j + 1; 3179 rc = expand_avtab_insert(expa, &newkey, d); 3180 if (rc) 3181 return -1; 3182 } 3183 } 3184 3185 return 0; 3186 } 3187 3188 int expand_avtab(policydb_t * p, avtab_t * a, avtab_t * expa) 3189 { 3190 struct expand_avtab_data data; 3191 3192 if (avtab_alloc(expa, MAX_AVTAB_SIZE)) { 3193 ERR(NULL, "Out of memory!"); 3194 return -1; 3195 } 3196 3197 data.expa = expa; 3198 data.p = p; 3199 return avtab_map(a, expand_avtab_node, &data); 3200 } 3201 3202 static int expand_cond_insert(cond_av_list_t ** l, 3203 avtab_t * expa, 3204 avtab_key_t * k, avtab_datum_t * d) 3205 { 3206 avtab_ptr_t node; 3207 avtab_datum_t *avd; 3208 cond_av_list_t *nl; 3209 3210 node = avtab_search_node(expa, k); 3211 if (!node || 3212 (k->specified & AVTAB_ENABLED) != 3213 (node->key.specified & AVTAB_ENABLED)) { 3214 node = avtab_insert_nonunique(expa, k, d); 3215 if (!node) { 3216 ERR(NULL, "Out of memory!"); 3217 return -1; 3218 } 3219 node->parse_context = (void *)1; 3220 nl = (cond_av_list_t *) malloc(sizeof(*nl)); 3221 if (!nl) { 3222 ERR(NULL, "Out of memory!"); 3223 return -1; 3224 } 3225 memset(nl, 0, sizeof(*nl)); 3226 nl->node = node; 3227 nl->next = *l; 3228 *l = nl; 3229 return 0; 3230 } 3231 3232 avd = &node->datum; 3233 switch (k->specified & ~AVTAB_ENABLED) { 3234 case AVTAB_ALLOWED: 3235 case AVTAB_AUDITALLOW: 3236 avd->data |= d->data; 3237 break; 3238 case AVTAB_AUDITDENY: 3239 avd->data &= d->data; 3240 break; 3241 default: 3242 ERR(NULL, "Type conflict!"); 3243 return -1; 3244 } 3245 3246 return 0; 3247 } 3248 3249 int expand_cond_av_node(policydb_t * p, 3250 avtab_ptr_t node, 3251 cond_av_list_t ** newl, avtab_t * expa) 3252 { 3253 avtab_key_t *k = &node->key; 3254 avtab_datum_t *d = &node->datum; 3255 type_datum_t *stype = p->type_val_to_struct[k->source_type - 1]; 3256 type_datum_t *ttype = p->type_val_to_struct[k->target_type - 1]; 3257 ebitmap_t *sattr = &p->attr_type_map[k->source_type - 1]; 3258 ebitmap_t *tattr = &p->attr_type_map[k->target_type - 1]; 3259 ebitmap_node_t *snode, *tnode; 3260 unsigned int i, j; 3261 avtab_key_t newkey; 3262 int rc; 3263 3264 newkey.target_class = k->target_class; 3265 newkey.specified = k->specified; 3266 3267 if (stype->flavor != TYPE_ATTRIB && ttype->flavor != TYPE_ATTRIB) { 3268 /* Both are individual types, no expansion required. */ 3269 return expand_cond_insert(newl, expa, k, d); 3270 } 3271 3272 if (stype->flavor != TYPE_ATTRIB) { 3273 /* Source is an individual type, target is an attribute. */ 3274 newkey.source_type = k->source_type; 3275 ebitmap_for_each_bit(tattr, tnode, j) { 3276 if (!ebitmap_node_get_bit(tnode, j)) 3277 continue; 3278 newkey.target_type = j + 1; 3279 rc = expand_cond_insert(newl, expa, &newkey, d); 3280 if (rc) 3281 return -1; 3282 } 3283 return 0; 3284 } 3285 3286 if (ttype->flavor != TYPE_ATTRIB) { 3287 /* Target is an individual type, source is an attribute. */ 3288 newkey.target_type = k->target_type; 3289 ebitmap_for_each_bit(sattr, snode, i) { 3290 if (!ebitmap_node_get_bit(snode, i)) 3291 continue; 3292 newkey.source_type = i + 1; 3293 rc = expand_cond_insert(newl, expa, &newkey, d); 3294 if (rc) 3295 return -1; 3296 } 3297 return 0; 3298 } 3299 3300 /* Both source and target type are attributes. */ 3301 ebitmap_for_each_bit(sattr, snode, i) { 3302 if (!ebitmap_node_get_bit(snode, i)) 3303 continue; 3304 ebitmap_for_each_bit(tattr, tnode, j) { 3305 if (!ebitmap_node_get_bit(tnode, j)) 3306 continue; 3307 newkey.source_type = i + 1; 3308 newkey.target_type = j + 1; 3309 rc = expand_cond_insert(newl, expa, &newkey, d); 3310 if (rc) 3311 return -1; 3312 } 3313 } 3314 3315 return 0; 3316 } 3317 3318 int expand_cond_av_list(policydb_t * p, cond_av_list_t * l, 3319 cond_av_list_t ** newl, avtab_t * expa) 3320 { 3321 cond_av_list_t *cur; 3322 avtab_ptr_t node; 3323 int rc; 3324 3325 if (avtab_alloc(expa, MAX_AVTAB_SIZE)) { 3326 ERR(NULL, "Out of memory!"); 3327 return -1; 3328 } 3329 3330 *newl = NULL; 3331 for (cur = l; cur; cur = cur->next) { 3332 node = cur->node; 3333 rc = expand_cond_av_node(p, node, newl, expa); 3334 if (rc) 3335 return rc; 3336 } 3337 3338 return 0; 3339 } 3340