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