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