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