1 /* 2 * Copyright 2011 Tresys Technology, LLC. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * 1. Redistributions of source code must retain the above copyright notice, 8 * this list of conditions and the following disclaimer. 9 * 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS 15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 18 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 21 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 22 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 * The views and conclusions contained in the software and documentation are those 26 * of the authors and should not be interpreted as representing official policies, 27 * either expressed or implied, of Tresys Technology, LLC. 28 */ 29 30 #include <stdlib.h> 31 #include <stdio.h> 32 #include <assert.h> 33 #include <netinet/in.h> 34 35 #include <sepol/policydb/policydb.h> 36 #include <sepol/policydb/polcaps.h> 37 #include <sepol/policydb/conditional.h> 38 #include <sepol/policydb/constraint.h> 39 #include <sepol/policydb/flask.h> 40 41 #include "cil_internal.h" 42 #include "cil_flavor.h" 43 #include "cil_log.h" 44 #include "cil_mem.h" 45 #include "cil_tree.h" 46 #include "cil_binary.h" 47 #include "cil_symtab.h" 48 49 /* There are 44000 filename_trans in current fedora policy. 1.33 times this is the recommended 50 * size of a hashtable. The next power of 2 of this is 2 ** 16. 51 */ 52 #define FILENAME_TRANS_TABLE_SIZE 1 << 16 53 #define RANGE_TRANS_TABLE_SIZE 1 << 13 54 #define ROLE_TRANS_TABLE_SIZE 1 << 10 55 56 struct cil_args_binary { 57 const struct cil_db *db; 58 policydb_t *pdb; 59 struct cil_list *neverallows; 60 int pass; 61 hashtab_t filename_trans_table; 62 hashtab_t range_trans_table; 63 hashtab_t role_trans_table; 64 }; 65 66 struct cil_args_booleanif { 67 const struct cil_db *db; 68 policydb_t *pdb; 69 cond_node_t *cond_node; 70 enum cil_flavor cond_flavor; 71 struct cil_list *neverallows; 72 hashtab_t filename_trans_table; 73 }; 74 75 struct cil_neverallow { 76 struct cil_tree_node *node; 77 struct cil_list *rules; 78 }; 79 80 struct cil_neverallow_rule { 81 struct cil_symtab_datum *src; 82 struct cil_symtab_datum *tgt; 83 uint32_t class; 84 uint32_t perms; 85 }; 86 87 void cil_neverallows_list_destroy(struct cil_list *neverallows) 88 { 89 struct cil_list_item *i; 90 struct cil_list_item *j; 91 92 cil_list_for_each(i, neverallows) { 93 struct cil_neverallow *neverallow = i->data; 94 cil_list_for_each(j, neverallow->rules) { 95 struct cil_neverallow_rule *rule = j->data; 96 free(rule); 97 } 98 cil_list_destroy(&neverallow->rules, CIL_FALSE); 99 free(neverallow); 100 } 101 cil_list_destroy(&neverallows, CIL_FALSE); 102 } 103 104 static int __cil_get_sepol_user_datum(policydb_t *pdb, struct cil_symtab_datum *datum, user_datum_t **sepol_user) 105 { 106 *sepol_user = hashtab_search(pdb->p_users.table, datum->fqn); 107 if (*sepol_user == NULL) { 108 cil_log(CIL_INFO, "Failed to find user %s in sepol hashtab\n", datum->fqn); 109 return SEPOL_ERR; 110 } 111 112 return SEPOL_OK; 113 } 114 115 static int __cil_get_sepol_role_datum(policydb_t *pdb, struct cil_symtab_datum *datum, role_datum_t **sepol_role) 116 { 117 *sepol_role = hashtab_search(pdb->p_roles.table, datum->fqn); 118 if (*sepol_role == NULL) { 119 cil_log(CIL_INFO, "Failed to find role %s in sepol hashtab\n", datum->fqn); 120 return SEPOL_ERR; 121 } 122 123 return SEPOL_OK; 124 } 125 126 static int __cil_get_sepol_type_datum(policydb_t *pdb, struct cil_symtab_datum *datum, type_datum_t **sepol_type) 127 { 128 *sepol_type = hashtab_search(pdb->p_types.table, datum->fqn); 129 if (*sepol_type == NULL) { 130 cil_log(CIL_INFO, "Failed to find type %s in sepol hashtab\n", datum->fqn); 131 return SEPOL_ERR; 132 } 133 134 return SEPOL_OK; 135 } 136 137 static int __cil_get_sepol_class_datum(policydb_t *pdb, struct cil_symtab_datum *datum, class_datum_t **sepol_class) 138 { 139 *sepol_class = hashtab_search(pdb->p_classes.table, datum->fqn); 140 if (*sepol_class == NULL) { 141 cil_log(CIL_INFO, "Failed to find class %s in sepol hashtab\n", datum->fqn); 142 return SEPOL_ERR; 143 } 144 145 return SEPOL_OK; 146 } 147 148 static int __cil_get_sepol_cat_datum(policydb_t *pdb, struct cil_symtab_datum *datum, cat_datum_t **sepol_cat) 149 { 150 *sepol_cat = hashtab_search(pdb->p_cats.table, datum->fqn); 151 if (*sepol_cat == NULL) { 152 cil_log(CIL_INFO, "Failed to find category %s in sepol hashtab\n", datum->fqn); 153 return SEPOL_ERR; 154 } 155 156 return SEPOL_OK; 157 } 158 159 static int __cil_get_sepol_level_datum(policydb_t *pdb, struct cil_symtab_datum *datum, level_datum_t **sepol_level) 160 { 161 *sepol_level = hashtab_search(pdb->p_levels.table, datum->fqn); 162 if (*sepol_level == NULL) { 163 cil_log(CIL_INFO, "Failed to find level %s in sepol hashtab\n", datum->fqn); 164 return SEPOL_ERR; 165 } 166 167 return SEPOL_OK; 168 } 169 170 static int __cil_expand_role(struct cil_symtab_datum *datum, ebitmap_t *new) 171 { 172 struct cil_tree_node *node = datum->nodes->head->data; 173 174 if (node->flavor == CIL_ROLEATTRIBUTE) { 175 struct cil_roleattribute *attr = (struct cil_roleattribute *)datum; 176 if (ebitmap_cpy(new, attr->roles)) { 177 cil_log(CIL_ERR, "Failed to copy role bits\n"); 178 goto exit; 179 } 180 } else { 181 struct cil_role *role = (struct cil_role *)datum; 182 ebitmap_init(new); 183 if (ebitmap_set_bit(new, role->value, 1)) { 184 cil_log(CIL_ERR, "Failed to set role bit\n"); 185 ebitmap_destroy(new); 186 goto exit; 187 } 188 } 189 190 return SEPOL_OK; 191 192 exit: 193 return SEPOL_ERR; 194 } 195 196 static int __cil_expand_type(struct cil_symtab_datum *datum, ebitmap_t *new) 197 { 198 struct cil_tree_node *node = datum->nodes->head->data; 199 200 if (node->flavor == CIL_TYPEATTRIBUTE) { 201 struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; 202 if (ebitmap_cpy(new, attr->types)) { 203 cil_log(CIL_ERR, "Failed to copy type bits\n"); 204 goto exit; 205 } 206 } else { 207 struct cil_type *type = (struct cil_type *)datum; 208 ebitmap_init(new); 209 if (ebitmap_set_bit(new, type->value, 1)) { 210 cil_log(CIL_ERR, "Failed to set type bit\n"); 211 ebitmap_destroy(new); 212 goto exit; 213 } 214 } 215 216 return SEPOL_OK; 217 218 exit: 219 return SEPOL_ERR; 220 } 221 222 static ocontext_t *cil_add_ocontext(ocontext_t **head, ocontext_t **tail) 223 { 224 ocontext_t *new = cil_malloc(sizeof(ocontext_t)); 225 memset(new, 0, sizeof(ocontext_t)); 226 if (*tail) { 227 (*tail)->next = new; 228 } else { 229 *head = new; 230 } 231 *tail = new; 232 233 return new; 234 } 235 236 static void __add_classes_from_classperms_list(struct cil_list *classperms, struct cil_list *class_list) 237 { 238 struct cil_list_item *curr; 239 240 cil_list_for_each(curr, classperms) { 241 if (curr->flavor == CIL_CLASSPERMS) { 242 struct cil_classperms *cp = curr->data; 243 if (FLAVOR(cp->class) == CIL_CLASS) { 244 cil_list_append(class_list, CIL_CLASS, cp->class); 245 } else { /* MAP */ 246 struct cil_list_item *i = NULL; 247 cil_list_for_each(i, cp->perms) { 248 struct cil_perm *cmp = i->data; 249 __add_classes_from_classperms_list(cmp->classperms, class_list); 250 } 251 } 252 } else { /* SET */ 253 struct cil_classperms_set *cp_set = curr->data; 254 struct cil_classpermission *cp = cp_set->set; 255 __add_classes_from_classperms_list(cp->classperms, class_list); 256 } 257 } 258 } 259 260 static int __add_classes_from_map_perms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) 261 { 262 struct cil_list *class_list = args; 263 struct cil_perm *cmp = (struct cil_perm *)d; 264 265 __add_classes_from_classperms_list(cmp->classperms, class_list); 266 267 return SEPOL_OK; 268 } 269 270 static struct cil_list *cil_expand_class(struct cil_class *class) 271 { 272 struct cil_list *class_list; 273 274 cil_list_init(&class_list, CIL_CLASS); 275 276 if (FLAVOR(class) == CIL_CLASS) { 277 cil_list_append(class_list, CIL_CLASS, class); 278 } else { /* MAP */ 279 cil_symtab_map(&class->perms, __add_classes_from_map_perms, class_list); 280 } 281 282 return class_list; 283 } 284 285 int cil_common_to_policydb(policydb_t *pdb, struct cil_class *cil_common, common_datum_t **common_out) 286 { 287 int rc = SEPOL_ERR; 288 uint32_t value = 0; 289 char *key = NULL; 290 struct cil_tree_node *node = cil_common->datum.nodes->head->data; 291 struct cil_tree_node *cil_perm = node->cl_head; 292 common_datum_t *sepol_common = cil_malloc(sizeof(*sepol_common)); 293 memset(sepol_common, 0, sizeof(common_datum_t)); 294 295 key = cil_strdup(cil_common->datum.fqn); 296 rc = symtab_insert(pdb, SYM_COMMONS, key, sepol_common, SCOPE_DECL, 0, &value); 297 if (rc != SEPOL_OK) { 298 free(sepol_common); 299 goto exit; 300 } 301 sepol_common->s.value = value; 302 303 rc = symtab_init(&sepol_common->permissions, PERM_SYMTAB_SIZE); 304 if (rc != SEPOL_OK) { 305 goto exit; 306 } 307 308 while (cil_perm != NULL) { 309 struct cil_perm *curr = cil_perm->data; 310 perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm)); 311 memset(sepol_perm, 0, sizeof(perm_datum_t)); 312 313 key = cil_strdup(curr->datum.fqn); 314 rc = hashtab_insert(sepol_common->permissions.table, key, sepol_perm); 315 if (rc != SEPOL_OK) { 316 free(sepol_perm); 317 goto exit; 318 } 319 sepol_perm->s.value = sepol_common->permissions.nprim + 1; 320 sepol_common->permissions.nprim++; 321 cil_perm = cil_perm->next; 322 } 323 324 *common_out = sepol_common; 325 326 return SEPOL_OK; 327 328 exit: 329 free(key); 330 return rc; 331 } 332 333 int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db) 334 { 335 int rc = SEPOL_ERR; 336 struct cil_list_item *curr_class; 337 338 cil_list_for_each(curr_class, db->classorder) { 339 struct cil_class *cil_class = curr_class->data; 340 uint32_t value = 0; 341 char *key = NULL; 342 struct cil_tree_node *node = cil_class->datum.nodes->head->data; 343 struct cil_tree_node *cil_perm = node->cl_head; 344 common_datum_t *sepol_common = NULL; 345 class_datum_t *sepol_class = cil_malloc(sizeof(*sepol_class)); 346 memset(sepol_class, 0, sizeof(class_datum_t)); 347 348 key = cil_strdup(cil_class->datum.fqn); 349 rc = symtab_insert(pdb, SYM_CLASSES, key, sepol_class, SCOPE_DECL, 0, &value); 350 if (rc != SEPOL_OK) { 351 free(sepol_class); 352 free(key); 353 goto exit; 354 } 355 sepol_class->s.value = value; 356 357 rc = symtab_init(&sepol_class->permissions, PERM_SYMTAB_SIZE); 358 if (rc != SEPOL_OK) { 359 goto exit; 360 } 361 362 if (cil_class->common != NULL) { 363 struct cil_class *cil_common = cil_class->common; 364 365 key = cil_class->common->datum.fqn; 366 sepol_common = hashtab_search(pdb->p_commons.table, key); 367 if (sepol_common == NULL) { 368 rc = cil_common_to_policydb(pdb, cil_common, &sepol_common); 369 if (rc != SEPOL_OK) { 370 goto exit; 371 } 372 } 373 sepol_class->comdatum = sepol_common; 374 sepol_class->comkey = cil_strdup(key); 375 sepol_class->permissions.nprim += sepol_common->permissions.nprim; 376 } 377 378 while (cil_perm != NULL) { 379 struct cil_perm *curr_perm = cil_perm->data; 380 perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm)); 381 memset(sepol_perm, 0, sizeof(perm_datum_t)); 382 383 key = cil_strdup(curr_perm->datum.fqn); 384 rc = hashtab_insert(sepol_class->permissions.table, key, sepol_perm); 385 if (rc != SEPOL_OK) { 386 free(sepol_perm); 387 free(key); 388 goto exit; 389 } 390 sepol_perm->s.value = sepol_class->permissions.nprim + 1; 391 sepol_class->permissions.nprim++; 392 cil_perm = cil_perm->next; 393 } 394 } 395 396 return SEPOL_OK; 397 398 exit: 399 return rc; 400 } 401 402 int cil_role_to_policydb(policydb_t *pdb, struct cil_role *cil_role) 403 { 404 int rc = SEPOL_ERR; 405 uint32_t value = 0; 406 char *key = NULL; 407 role_datum_t *sepol_role = cil_malloc(sizeof(*sepol_role)); 408 role_datum_init(sepol_role); 409 410 if (cil_role->datum.fqn == CIL_KEY_OBJECT_R) { 411 /* special case 412 * object_r defaults to 1 in libsepol symtab */ 413 rc = SEPOL_OK; 414 goto exit; 415 } 416 417 key = cil_strdup(cil_role->datum.fqn); 418 rc = symtab_insert(pdb, SYM_ROLES, (hashtab_key_t)key, sepol_role, SCOPE_DECL, 0, &value); 419 if (rc != SEPOL_OK) { 420 goto exit; 421 } 422 if (ebitmap_set_bit(&sepol_role->dominates, value - 1, 1)) { 423 cil_log(CIL_INFO, "Failed to set dominates bit for role\n"); 424 rc = SEPOL_ERR; 425 goto exit; 426 } 427 sepol_role->s.value = value; 428 return SEPOL_OK; 429 430 exit: 431 free(key); 432 role_datum_destroy(sepol_role); 433 free(sepol_role); 434 return rc; 435 } 436 437 int cil_role_bounds_to_policydb(policydb_t *pdb, struct cil_role *cil_role) 438 { 439 int rc = SEPOL_ERR; 440 role_datum_t *sepol_role = NULL; 441 role_datum_t *sepol_parent = NULL; 442 443 if (cil_role->bounds) { 444 rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_role), &sepol_role); 445 if (rc != SEPOL_OK) goto exit; 446 447 rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_role->bounds), &sepol_parent); 448 if (rc != SEPOL_OK) goto exit; 449 450 sepol_role->bounds = sepol_parent->s.value; 451 } 452 453 return SEPOL_OK; 454 455 exit: 456 cil_log(CIL_ERR, "Failed to insert role bounds for role %s\n", cil_role->datum.fqn); 457 return SEPOL_ERR; 458 } 459 460 int cil_roletype_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_role *role) 461 { 462 int rc = SEPOL_ERR; 463 464 if (role->types) { 465 role_datum_t *sepol_role = NULL; 466 type_datum_t *sepol_type = NULL; 467 ebitmap_node_t *tnode; 468 unsigned int i; 469 470 rc = __cil_get_sepol_role_datum(pdb, DATUM(role), &sepol_role); 471 if (rc != SEPOL_OK) goto exit; 472 473 ebitmap_for_each_bit(role->types, tnode, i) { 474 if (!ebitmap_get_bit(role->types, i)) continue; 475 476 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type); 477 if (rc != SEPOL_OK) goto exit; 478 479 if (ebitmap_set_bit(&sepol_role->types.types, sepol_type->s.value - 1, 1)) { 480 cil_log(CIL_INFO, "Failed to set type bit for role\n"); 481 rc = SEPOL_ERR; 482 goto exit; 483 } 484 } 485 } 486 487 return SEPOL_OK; 488 489 exit: 490 return rc; 491 } 492 493 int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type) 494 { 495 int rc = SEPOL_ERR; 496 uint32_t value = 0; 497 char *key = NULL; 498 type_datum_t *sepol_type = cil_malloc(sizeof(*sepol_type)); 499 type_datum_init(sepol_type); 500 501 sepol_type->flavor = TYPE_TYPE; 502 503 key = cil_strdup(cil_type->datum.fqn); 504 rc = symtab_insert(pdb, SYM_TYPES, key, sepol_type, SCOPE_DECL, 0, &value); 505 if (rc != SEPOL_OK) { 506 goto exit; 507 } 508 sepol_type->s.value = value; 509 sepol_type->primary = 1; 510 511 return SEPOL_OK; 512 513 exit: 514 free(key); 515 type_datum_destroy(sepol_type); 516 free(sepol_type); 517 return rc; 518 } 519 520 int cil_type_bounds_to_policydb(policydb_t *pdb, struct cil_type *cil_type) 521 { 522 int rc = SEPOL_ERR; 523 type_datum_t *sepol_type = NULL; 524 type_datum_t *sepol_parent = NULL; 525 526 if (cil_type->bounds) { 527 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_type), &sepol_type); 528 if (rc != SEPOL_OK) goto exit; 529 530 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_type->bounds), &sepol_parent); 531 if (rc != SEPOL_OK) goto exit; 532 533 sepol_type->bounds = sepol_parent->s.value; 534 } 535 536 return SEPOL_OK; 537 538 exit: 539 cil_log(CIL_ERR, "Failed to insert type bounds for type %s\n", cil_type->datum.fqn); 540 return SEPOL_ERR; 541 } 542 543 int cil_typealias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias) 544 { 545 int rc = SEPOL_ERR; 546 char *key = NULL; 547 type_datum_t *sepol_type = NULL; 548 type_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_alias)); 549 type_datum_init(sepol_alias); 550 551 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_alias->actual), &sepol_type); 552 if (rc != SEPOL_OK) goto exit; 553 554 sepol_alias->flavor = TYPE_TYPE; 555 556 key = cil_strdup(cil_alias->datum.fqn); 557 rc = symtab_insert(pdb, SYM_TYPES, key, sepol_alias, SCOPE_DECL, 0, NULL); 558 if (rc != SEPOL_OK) { 559 goto exit; 560 } 561 sepol_alias->s.value = sepol_type->s.value; 562 sepol_alias->primary = 0; 563 564 return SEPOL_OK; 565 566 exit: 567 free(key); 568 type_datum_destroy(sepol_alias); 569 free(sepol_alias); 570 return rc; 571 } 572 573 int cil_typepermissive_to_policydb(policydb_t *pdb, struct cil_typepermissive *cil_typeperm) 574 { 575 int rc = SEPOL_ERR; 576 type_datum_t *sepol_type = NULL; 577 578 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_typeperm->type), &sepol_type); 579 if (rc != SEPOL_OK) goto exit; 580 581 if (ebitmap_set_bit(&pdb->permissive_map, sepol_type->s.value, 1)) { 582 goto exit; 583 } 584 585 return SEPOL_OK; 586 587 exit: 588 type_datum_destroy(sepol_type); 589 free(sepol_type); 590 return rc; 591 592 } 593 594 int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr) 595 { 596 int rc = SEPOL_ERR; 597 uint32_t value = 0; 598 char *key = NULL; 599 type_datum_t *sepol_attr = NULL; 600 601 if (cil_attr->used == CIL_FALSE) { 602 return SEPOL_OK; 603 } 604 605 sepol_attr = cil_malloc(sizeof(*sepol_attr)); 606 type_datum_init(sepol_attr); 607 608 sepol_attr->flavor = TYPE_ATTRIB; 609 610 key = cil_strdup(cil_attr->datum.fqn); 611 rc = symtab_insert(pdb, SYM_TYPES, key, sepol_attr, SCOPE_DECL, 0, &value); 612 if (rc != SEPOL_OK) { 613 goto exit; 614 } 615 sepol_attr->s.value = value; 616 sepol_attr->primary = 1; 617 618 return SEPOL_OK; 619 620 exit: 621 type_datum_destroy(sepol_attr); 622 free(sepol_attr); 623 return rc; 624 } 625 626 int __cil_typeattr_bitmap_init(policydb_t *pdb) 627 { 628 int rc = SEPOL_ERR; 629 630 pdb->type_attr_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t)); 631 632 uint32_t i = 0; 633 for (i = 0; i < pdb->p_types.nprim; i++) { 634 ebitmap_init(&pdb->type_attr_map[i]); 635 if (ebitmap_set_bit(&pdb->type_attr_map[i], i, 1)) { 636 rc = SEPOL_ERR; 637 goto exit; 638 } 639 } 640 641 return SEPOL_OK; 642 643 exit: 644 return rc; 645 } 646 647 int cil_typeattribute_to_bitmap(policydb_t *pdb, const struct cil_db *db, struct cil_typeattribute *cil_attr) 648 { 649 int rc = SEPOL_ERR; 650 uint32_t value = 0; 651 type_datum_t *sepol_type = NULL; 652 ebitmap_node_t *tnode; 653 unsigned int i; 654 655 if (cil_attr->used == CIL_FALSE) { 656 return SEPOL_OK; 657 } 658 659 if (pdb->type_attr_map == NULL) { 660 rc = __cil_typeattr_bitmap_init(pdb); 661 if (rc != SEPOL_OK) { 662 goto exit; 663 } 664 } 665 666 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_attr), &sepol_type); 667 if (rc != SEPOL_OK) goto exit; 668 669 value = sepol_type->s.value; 670 671 ebitmap_for_each_bit(cil_attr->types, tnode, i) { 672 if (!ebitmap_get_bit(cil_attr->types, i)) continue; 673 674 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type); 675 if (rc != SEPOL_OK) goto exit; 676 677 ebitmap_set_bit(&pdb->type_attr_map[sepol_type->s.value - 1], value - 1, 1); 678 } 679 680 rc = SEPOL_OK; 681 exit: 682 return rc; 683 } 684 685 int cil_policycap_to_policydb(policydb_t *pdb, struct cil_policycap *cil_polcap) 686 { 687 int rc = SEPOL_ERR; 688 int capnum; 689 690 capnum = sepol_polcap_getnum(cil_polcap->datum.fqn); 691 if (capnum == -1) { 692 goto exit; 693 } 694 695 if (ebitmap_set_bit(&pdb->policycaps, capnum, 1)) { 696 goto exit; 697 } 698 699 return SEPOL_OK; 700 701 exit: 702 return rc; 703 } 704 705 int cil_user_to_policydb(policydb_t *pdb, struct cil_user *cil_user) 706 { 707 int rc = SEPOL_ERR; 708 uint32_t value = 0; 709 char *key = NULL; 710 user_datum_t *sepol_user = cil_malloc(sizeof(*sepol_user)); 711 user_datum_init(sepol_user); 712 713 key = cil_strdup(cil_user->datum.fqn); 714 rc = symtab_insert(pdb, SYM_USERS, key, sepol_user, SCOPE_DECL, 0, &value); 715 if (rc != SEPOL_OK) { 716 goto exit; 717 } 718 sepol_user->s.value = value; 719 720 return SEPOL_OK; 721 722 exit: 723 free(key); 724 user_datum_destroy(sepol_user); 725 free(sepol_user); 726 return rc; 727 } 728 729 int cil_user_bounds_to_policydb(policydb_t *pdb, struct cil_user *cil_user) 730 { 731 int rc = SEPOL_ERR; 732 user_datum_t *sepol_user = NULL; 733 user_datum_t *sepol_parent = NULL; 734 735 if (cil_user->bounds) { 736 rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user); 737 if (rc != SEPOL_OK) goto exit; 738 739 rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user->bounds), &sepol_parent); 740 if (rc != SEPOL_OK) goto exit; 741 742 sepol_user->bounds = sepol_parent->s.value; 743 } 744 745 return SEPOL_OK; 746 747 exit: 748 cil_log(CIL_ERR, "Failed to insert user bounds for user %s\n", cil_user->datum.fqn); 749 return SEPOL_ERR; 750 } 751 752 int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_userrole *userrole) 753 { 754 int rc = SEPOL_ERR; 755 user_datum_t *sepol_user = NULL; 756 role_datum_t *sepol_role = NULL; 757 ebitmap_t role_bitmap; 758 ebitmap_node_t *rnode; 759 unsigned int i; 760 761 rc = __cil_get_sepol_user_datum(pdb, DATUM(userrole->user), &sepol_user); 762 if (rc != SEPOL_OK) goto exit; 763 764 rc = __cil_expand_role(userrole->role, &role_bitmap); 765 if (rc != SEPOL_OK) goto exit; 766 767 ebitmap_for_each_bit(&role_bitmap, rnode, i) { 768 if (!ebitmap_get_bit(&role_bitmap, i)) continue; 769 770 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role); 771 if (rc != SEPOL_OK) goto exit; 772 773 if (sepol_role->s.value == 1) { 774 // role is object_r, ignore it since it is implicitly associated 775 // with all users 776 continue; 777 } 778 779 if (ebitmap_set_bit(&sepol_user->roles.roles, sepol_role->s.value - 1, 1)) { 780 cil_log(CIL_INFO, "Failed to set role bit for user\n"); 781 goto exit; 782 } 783 } 784 785 rc = SEPOL_OK; 786 787 exit: 788 ebitmap_destroy(&role_bitmap); 789 return rc; 790 } 791 792 int cil_bool_to_policydb(policydb_t *pdb, struct cil_bool *cil_bool) 793 { 794 int rc = SEPOL_ERR; 795 uint32_t value = 0; 796 char *key = NULL; 797 cond_bool_datum_t *sepol_bool = cil_malloc(sizeof(*sepol_bool)); 798 memset(sepol_bool, 0, sizeof(cond_bool_datum_t)); 799 800 key = cil_strdup(cil_bool->datum.fqn); 801 rc = symtab_insert(pdb, SYM_BOOLS, key, sepol_bool, SCOPE_DECL, 0, &value); 802 if (rc != SEPOL_OK) { 803 goto exit; 804 } 805 sepol_bool->s.value = value; 806 sepol_bool->state = cil_bool->value; 807 808 return SEPOL_OK; 809 810 exit: 811 free(key); 812 free(sepol_bool); 813 return rc; 814 } 815 816 int cil_catorder_to_policydb(policydb_t *pdb, const struct cil_db *db) 817 { 818 int rc = SEPOL_ERR; 819 uint32_t value = 0; 820 char *key = NULL; 821 struct cil_list_item *curr_cat; 822 struct cil_cat *cil_cat = NULL; 823 cat_datum_t *sepol_cat = NULL; 824 825 cil_list_for_each(curr_cat, db->catorder) { 826 cil_cat = curr_cat->data; 827 sepol_cat = cil_malloc(sizeof(*sepol_cat)); 828 cat_datum_init(sepol_cat); 829 830 key = cil_strdup(cil_cat->datum.fqn); 831 rc = symtab_insert(pdb, SYM_CATS, key, sepol_cat, SCOPE_DECL, 0, &value); 832 if (rc != SEPOL_OK) { 833 goto exit; 834 } 835 sepol_cat->s.value = value; 836 } 837 838 return SEPOL_OK; 839 840 exit: 841 free(key); 842 cat_datum_destroy(sepol_cat); 843 free(sepol_cat); 844 return rc; 845 } 846 847 int cil_catalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias) 848 { 849 int rc = SEPOL_ERR; 850 char *key = NULL; 851 cat_datum_t *sepol_cat; 852 cat_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_cat)); 853 cat_datum_init(sepol_alias); 854 855 rc = __cil_get_sepol_cat_datum(pdb, DATUM(cil_alias->actual), &sepol_cat); 856 if (rc != SEPOL_OK) goto exit; 857 858 key = cil_strdup(cil_alias->datum.fqn); 859 rc = symtab_insert(pdb, SYM_CATS, key, sepol_alias, SCOPE_DECL, 0, NULL); 860 if (rc != SEPOL_OK) { 861 free(key); 862 goto exit; 863 } 864 sepol_alias->s.value = sepol_cat->s.value; 865 sepol_alias->isalias = 1; 866 867 return SEPOL_OK; 868 869 exit: 870 free(key); 871 cat_datum_destroy(sepol_alias); 872 free(sepol_alias); 873 return rc; 874 } 875 876 int cil_sensitivityorder_to_policydb(policydb_t *pdb, const struct cil_db *db) 877 { 878 int rc = SEPOL_ERR; 879 uint32_t value = 0; 880 char *key = NULL; 881 struct cil_list_item *curr; 882 struct cil_sens *cil_sens = NULL; 883 level_datum_t *sepol_level = NULL; 884 mls_level_t *mls_level = NULL; 885 886 cil_list_for_each(curr, db->sensitivityorder) { 887 cil_sens = curr->data; 888 sepol_level = cil_malloc(sizeof(*sepol_level)); 889 mls_level = cil_malloc(sizeof(*mls_level)); 890 level_datum_init(sepol_level); 891 mls_level_init(mls_level); 892 893 key = cil_strdup(cil_sens->datum.fqn); 894 rc = symtab_insert(pdb, SYM_LEVELS, key, sepol_level, SCOPE_DECL, 0, &value); 895 if (rc != SEPOL_OK) { 896 goto exit; 897 } 898 mls_level->sens = value; 899 sepol_level->level = mls_level; 900 } 901 902 return SEPOL_OK; 903 904 exit: 905 level_datum_destroy(sepol_level); 906 mls_level_destroy(mls_level); 907 free(sepol_level); 908 free(mls_level); 909 free(key); 910 return rc; 911 } 912 913 int cil_sensalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias) 914 { 915 int rc = SEPOL_ERR; 916 char *key = NULL; 917 mls_level_t *mls_level = NULL; 918 level_datum_t *sepol_level = NULL; 919 level_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_alias)); 920 level_datum_init(sepol_alias); 921 922 rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_alias->actual), &sepol_level); 923 if (rc != SEPOL_OK) goto exit; 924 925 key = cil_strdup(cil_alias->datum.fqn); 926 rc = symtab_insert(pdb, SYM_LEVELS, key, sepol_alias, SCOPE_DECL, 0, NULL); 927 if (rc != SEPOL_OK) { 928 goto exit; 929 } 930 931 mls_level = cil_malloc(sizeof(*mls_level)); 932 mls_level_init(mls_level); 933 934 rc = mls_level_cpy(mls_level, sepol_level->level); 935 if (rc != SEPOL_OK) { 936 goto exit; 937 } 938 sepol_alias->level = mls_level; 939 sepol_alias->defined = 1; 940 sepol_alias->isalias = 1; 941 942 return SEPOL_OK; 943 944 exit: 945 level_datum_destroy(sepol_alias); 946 free(sepol_level); 947 free(key); 948 return rc; 949 } 950 951 int __cil_cond_insert_rule(avtab_t *avtab, avtab_key_t *avtab_key, avtab_datum_t *avtab_datum, cond_node_t *cond_node, enum cil_flavor cond_flavor) 952 { 953 int rc = SEPOL_OK; 954 avtab_ptr_t avtab_ptr = NULL; 955 cond_av_list_t *cond_list = NULL; 956 957 avtab_ptr = avtab_insert_nonunique(avtab, avtab_key, avtab_datum); 958 if (!avtab_ptr) { 959 rc = SEPOL_ERR; 960 goto exit; 961 } 962 963 // parse_context needs to be non-NULL for conditional rules to be 964 // written to the binary. it is normally used for finding duplicates, 965 // but cil checks that earlier, so we don't use it. it just needs to be 966 // set 967 avtab_ptr->parse_context = (void*)1; 968 969 cond_list = cil_malloc(sizeof(cond_av_list_t)); 970 memset(cond_list, 0, sizeof(cond_av_list_t)); 971 972 cond_list->node = avtab_ptr; 973 974 if (cond_flavor == CIL_CONDTRUE) { 975 cond_list->next = cond_node->true_list; 976 cond_node->true_list = cond_list; 977 } else { 978 cond_list->next = cond_node->false_list; 979 cond_node->false_list = cond_list; 980 } 981 982 exit: 983 return rc; 984 } 985 986 avtab_datum_t *cil_cond_av_list_search(avtab_key_t *key, cond_av_list_t *cond_list) 987 { 988 cond_av_list_t *cur_av; 989 990 for (cur_av = cond_list; cur_av != NULL; cur_av = cur_av->next) { 991 if (cur_av->node->key.source_type == key->source_type && 992 cur_av->node->key.target_type == key->target_type && 993 cur_av->node->key.target_class == key->target_class && 994 (cur_av->node->key.specified & key->specified)) 995 996 return &cur_av->node->datum; 997 998 } 999 return NULL; 1000 } 1001 1002 int __cil_insert_type_rule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t res, cond_node_t *cond_node, enum cil_flavor cond_flavor) 1003 { 1004 int rc = SEPOL_OK; 1005 avtab_key_t avtab_key; 1006 avtab_datum_t avtab_datum; 1007 avtab_ptr_t existing; 1008 1009 avtab_key.source_type = src; 1010 avtab_key.target_type = tgt; 1011 avtab_key.target_class = obj; 1012 1013 switch (kind) { 1014 case CIL_TYPE_TRANSITION: 1015 avtab_key.specified = AVTAB_TRANSITION; 1016 break; 1017 case CIL_TYPE_CHANGE: 1018 avtab_key.specified = AVTAB_CHANGE; 1019 break; 1020 case CIL_TYPE_MEMBER: 1021 avtab_key.specified = AVTAB_MEMBER; 1022 break; 1023 default: 1024 rc = SEPOL_ERR; 1025 goto exit; 1026 } 1027 1028 avtab_datum.data = res; 1029 1030 existing = avtab_search_node(&pdb->te_avtab, &avtab_key); 1031 if (existing) { 1032 /* Don't add duplicate type rule and warn if they conflict. 1033 * A warning should have been previously given if there is a 1034 * non-duplicate rule using the same key. 1035 */ 1036 if (existing->datum.data != res) { 1037 cil_log(CIL_ERR, "Conflicting type rules\n"); 1038 rc = SEPOL_ERR; 1039 } 1040 goto exit; 1041 } 1042 1043 if (!cond_node) { 1044 rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum); 1045 } else { 1046 existing = avtab_search_node(&pdb->te_cond_avtab, &avtab_key); 1047 if (existing) { 1048 cond_av_list_t *this_list; 1049 cond_av_list_t *other_list; 1050 avtab_datum_t *search_datum; 1051 1052 if (cond_flavor == CIL_CONDTRUE) { 1053 this_list = cond_node->true_list; 1054 other_list = cond_node->false_list; 1055 } else { 1056 this_list = cond_node->false_list; 1057 other_list = cond_node->true_list; 1058 } 1059 1060 search_datum = cil_cond_av_list_search(&avtab_key, other_list); 1061 if (search_datum == NULL) { 1062 if (existing->datum.data != res) { 1063 cil_log(CIL_ERR, "Conflicting type rules\n"); 1064 rc = SEPOL_ERR; 1065 goto exit; 1066 } 1067 1068 search_datum = cil_cond_av_list_search(&avtab_key, this_list); 1069 if (search_datum) { 1070 goto exit; 1071 } 1072 } 1073 } 1074 rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor); 1075 } 1076 1077 exit: 1078 return rc; 1079 } 1080 1081 int __cil_type_rule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_type_rule *cil_rule, cond_node_t *cond_node, enum cil_flavor cond_flavor) 1082 { 1083 int rc = SEPOL_ERR; 1084 uint16_t kind = cil_rule->rule_kind; 1085 type_datum_t *sepol_src = NULL; 1086 type_datum_t *sepol_tgt = NULL; 1087 class_datum_t *sepol_obj = NULL; 1088 struct cil_list *class_list; 1089 type_datum_t *sepol_result = NULL; 1090 ebitmap_t src_bitmap, tgt_bitmap; 1091 ebitmap_node_t *node1, *node2; 1092 unsigned int i, j; 1093 struct cil_list_item *c; 1094 1095 rc = __cil_expand_type(cil_rule->src, &src_bitmap); 1096 if (rc != SEPOL_OK) goto exit; 1097 1098 rc = __cil_expand_type(cil_rule->tgt, &tgt_bitmap); 1099 if (rc != SEPOL_OK) goto exit; 1100 1101 class_list = cil_expand_class(cil_rule->obj); 1102 1103 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_rule->result), &sepol_result); 1104 if (rc != SEPOL_OK) goto exit; 1105 1106 ebitmap_for_each_bit(&src_bitmap, node1, i) { 1107 if (!ebitmap_get_bit(&src_bitmap, i)) continue; 1108 1109 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); 1110 if (rc != SEPOL_OK) goto exit; 1111 1112 ebitmap_for_each_bit(&tgt_bitmap, node2, j) { 1113 if (!ebitmap_get_bit(&tgt_bitmap, j)) continue; 1114 1115 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt); 1116 if (rc != SEPOL_OK) goto exit; 1117 1118 cil_list_for_each(c, class_list) { 1119 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); 1120 if (rc != SEPOL_OK) goto exit; 1121 1122 rc = __cil_insert_type_rule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, sepol_result->s.value, cond_node, cond_flavor); 1123 if (rc != SEPOL_OK) goto exit; 1124 } 1125 } 1126 } 1127 1128 rc = SEPOL_OK; 1129 1130 exit: 1131 ebitmap_destroy(&src_bitmap); 1132 ebitmap_destroy(&tgt_bitmap); 1133 cil_list_destroy(&class_list, CIL_FALSE); 1134 return rc; 1135 } 1136 1137 int cil_type_rule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_type_rule *cil_rule) 1138 { 1139 return __cil_type_rule_to_avtab(pdb, db, cil_rule, NULL, CIL_FALSE); 1140 } 1141 1142 int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, cond_node_t *cond_node, enum cil_flavor cond_flavor, hashtab_t filename_trans_table) 1143 { 1144 int rc = SEPOL_ERR; 1145 type_datum_t *sepol_src = NULL; 1146 type_datum_t *sepol_tgt = NULL; 1147 class_datum_t *sepol_obj = NULL; 1148 struct cil_list *class_list; 1149 type_datum_t *sepol_result = NULL; 1150 filename_trans_t *new = NULL; 1151 ebitmap_t src_bitmap, tgt_bitmap; 1152 ebitmap_node_t *node1, *node2; 1153 unsigned int i, j; 1154 struct cil_list_item *c; 1155 char *name = DATUM(typetrans->name)->name; 1156 uint32_t *otype = NULL; 1157 1158 if (name == CIL_KEY_STAR) { 1159 struct cil_type_rule trans; 1160 trans.rule_kind = CIL_TYPE_TRANSITION; 1161 trans.src = typetrans->src; 1162 trans.tgt = typetrans->tgt; 1163 trans.obj = typetrans->obj; 1164 trans.result = typetrans->result; 1165 return __cil_type_rule_to_avtab(pdb, db, &trans, cond_node, cond_flavor); 1166 } 1167 1168 rc = __cil_expand_type(typetrans->src, &src_bitmap); 1169 if (rc != SEPOL_OK) goto exit; 1170 1171 rc = __cil_expand_type(typetrans->tgt, &tgt_bitmap); 1172 if (rc != SEPOL_OK) goto exit; 1173 1174 class_list = cil_expand_class(typetrans->obj); 1175 1176 rc = __cil_get_sepol_type_datum(pdb, DATUM(typetrans->result), &sepol_result); 1177 if (rc != SEPOL_OK) goto exit; 1178 1179 ebitmap_for_each_bit(&src_bitmap, node1, i) { 1180 if (!ebitmap_get_bit(&src_bitmap, i)) continue; 1181 1182 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); 1183 if (rc != SEPOL_OK) goto exit; 1184 1185 ebitmap_for_each_bit(&tgt_bitmap, node2, j) { 1186 if (!ebitmap_get_bit(&tgt_bitmap, j)) continue; 1187 1188 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt); 1189 if (rc != SEPOL_OK) goto exit; 1190 1191 cil_list_for_each(c, class_list) { 1192 int add = CIL_TRUE; 1193 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); 1194 if (rc != SEPOL_OK) goto exit; 1195 1196 new = cil_malloc(sizeof(*new)); 1197 memset(new, 0, sizeof(*new)); 1198 new->stype = sepol_src->s.value; 1199 new->ttype = sepol_tgt->s.value; 1200 new->tclass = sepol_obj->s.value; 1201 new->otype = sepol_result->s.value; 1202 new->name = cil_strdup(name); 1203 1204 rc = hashtab_insert(filename_trans_table, (hashtab_key_t)new, &(new->otype)); 1205 if (rc != SEPOL_OK) { 1206 if (rc == SEPOL_EEXIST) { 1207 add = CIL_FALSE; 1208 otype = hashtab_search(filename_trans_table, (hashtab_key_t)new); 1209 if (new->otype != *otype) { 1210 cil_log(CIL_ERR, "Conflicting name type transition rules\n"); 1211 } else { 1212 rc = SEPOL_OK; 1213 } 1214 } else { 1215 cil_log(CIL_ERR, "Out of memory\n"); 1216 } 1217 } 1218 1219 if (add == CIL_TRUE) { 1220 new->next = pdb->filename_trans; 1221 pdb->filename_trans = new; 1222 } else { 1223 free(new->name); 1224 free(new); 1225 if (rc != SEPOL_OK) { 1226 goto exit; 1227 } 1228 } 1229 } 1230 } 1231 } 1232 1233 rc = SEPOL_OK; 1234 1235 exit: 1236 ebitmap_destroy(&src_bitmap); 1237 ebitmap_destroy(&tgt_bitmap); 1238 cil_list_destroy(&class_list, CIL_FALSE); 1239 return rc; 1240 } 1241 1242 int cil_typetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, hashtab_t filename_trans_table) 1243 { 1244 return __cil_typetransition_to_avtab(pdb, db, typetrans, NULL, CIL_FALSE, filename_trans_table); 1245 } 1246 1247 int __cil_perms_to_datum(struct cil_list *perms, class_datum_t *sepol_class, uint32_t *datum) 1248 { 1249 int rc = SEPOL_ERR; 1250 char *key = NULL; 1251 struct cil_list_item *curr_perm; 1252 struct cil_perm *cil_perm; 1253 uint32_t data = 0; 1254 1255 cil_list_for_each(curr_perm, perms) { 1256 perm_datum_t *sepol_perm; 1257 cil_perm = curr_perm->data; 1258 key = cil_perm->datum.fqn; 1259 sepol_perm = hashtab_search(sepol_class->permissions.table, key); 1260 if (sepol_perm == NULL) { 1261 common_datum_t *sepol_common = sepol_class->comdatum; 1262 sepol_perm = hashtab_search(sepol_common->permissions.table, key); 1263 if (sepol_perm == NULL) { 1264 cil_log(CIL_ERR, "Failed to find datum for perm %s\n", key); 1265 rc = SEPOL_ERR; 1266 goto exit; 1267 } 1268 } 1269 data |= 1 << (sepol_perm->s.value - 1); 1270 } 1271 1272 *datum = data; 1273 1274 return SEPOL_OK; 1275 1276 exit: 1277 return rc; 1278 } 1279 1280 int __cil_insert_avrule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t data, cond_node_t *cond_node, enum cil_flavor cond_flavor) 1281 { 1282 int rc = SEPOL_OK; 1283 avtab_key_t avtab_key; 1284 avtab_datum_t avtab_datum; 1285 avtab_datum_t *avtab_dup = NULL; 1286 1287 avtab_key.source_type = src; 1288 avtab_key.target_type = tgt; 1289 avtab_key.target_class = obj; 1290 1291 switch (kind) { 1292 case CIL_AVRULE_ALLOWED: 1293 avtab_key.specified = AVTAB_ALLOWED; 1294 break; 1295 case CIL_AVRULE_AUDITALLOW: 1296 avtab_key.specified = AVTAB_AUDITALLOW; 1297 break; 1298 case CIL_AVRULE_DONTAUDIT: 1299 avtab_key.specified = AVTAB_AUDITDENY; 1300 break; 1301 default: 1302 rc = SEPOL_ERR; 1303 goto exit; 1304 break; 1305 } 1306 1307 if (!cond_node) { 1308 avtab_dup = avtab_search(&pdb->te_avtab, &avtab_key); 1309 if (!avtab_dup) { 1310 avtab_datum.data = data; 1311 rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum); 1312 } else { 1313 if (kind == CIL_AVRULE_DONTAUDIT) 1314 avtab_dup->data &= data; 1315 else 1316 avtab_dup->data |= data; 1317 } 1318 } else { 1319 avtab_datum.data = data; 1320 rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor); 1321 } 1322 1323 exit: 1324 return rc; 1325 } 1326 1327 static void __cil_neverallow_handle(struct cil_list *neverallows, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, uint32_t class, uint32_t perms) 1328 { 1329 struct cil_neverallow *neverallow = neverallows->head->data; 1330 struct cil_list *neverallow_rules = neverallow->rules; 1331 struct cil_neverallow_rule *new = NULL; 1332 1333 new = cil_malloc(sizeof(*new)); 1334 new->src = src; 1335 new->tgt = tgt; 1336 new->class = class; 1337 new->perms = perms; 1338 1339 cil_list_append(neverallow_rules, CIL_LIST_ITEM, new); 1340 } 1341 1342 static int __cil_is_type_match(enum cil_flavor f1, struct cil_symtab_datum *t1, enum cil_flavor f2, struct cil_symtab_datum *t2) 1343 { 1344 if (t1->fqn == t2->fqn) { 1345 return CIL_TRUE; 1346 } else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) { 1347 struct cil_typeattribute *a = (struct cil_typeattribute *)t1; 1348 struct cil_type *t = (struct cil_type *)t2; 1349 if (ebitmap_get_bit(a->types, t->value)) { 1350 return CIL_TRUE; 1351 } 1352 } else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) { 1353 struct cil_typeattribute *a = (struct cil_typeattribute *)t2; 1354 struct cil_type *t = (struct cil_type *)t1; 1355 if (ebitmap_get_bit(a->types, t->value)) { 1356 return CIL_TRUE; 1357 } 1358 } else if (f1 == CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) { 1359 struct cil_typeattribute *a1 = (struct cil_typeattribute *)t2; 1360 struct cil_typeattribute *a2 = (struct cil_typeattribute *)t1; 1361 /* abusing the ebitmap abstraction for speed */ 1362 ebitmap_node_t *n1 = a1->types->node; 1363 ebitmap_node_t *n2 = a2->types->node; 1364 while (n1 && n2) { 1365 if (n1->startbit < n2->startbit) { 1366 n1 = n1->next; 1367 } else if (n2->startbit < n1->startbit) { 1368 n2 = n2->next; 1369 } else { 1370 if (n1->map & n2->map) { 1371 return CIL_TRUE; 1372 } 1373 n1 = n1->next; 1374 n2 = n2->next; 1375 } 1376 } 1377 } 1378 return CIL_FALSE; 1379 } 1380 1381 static int __cil_check_neverallows(struct cil_list *neverallows, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, uint32_t class, uint32_t perms) 1382 { 1383 struct cil_list_item *curr = NULL; 1384 enum cil_flavor al_src_flavor = ((struct cil_tree_node*)src->nodes->head->data)->flavor; 1385 enum cil_flavor al_tgt_flavor = ((struct cil_tree_node*)tgt->nodes->head->data)->flavor; 1386 cil_list_for_each(curr, neverallows) { 1387 struct cil_neverallow *neverallow = curr->data; 1388 struct cil_tree_node *node = neverallow->node; 1389 struct cil_list_item *curr_item = NULL; 1390 cil_list_for_each(curr_item, neverallow->rules) { 1391 struct cil_neverallow_rule *curr_rule = curr_item->data; 1392 enum cil_flavor nv_src_flavor = ((struct cil_tree_node*)curr_rule->src->nodes->head->data)->flavor; 1393 enum cil_flavor nv_tgt_flavor = ((struct cil_tree_node*)curr_rule->tgt->nodes->head->data)->flavor; 1394 if ((curr_rule->perms & perms) && (class == curr_rule->class)) { 1395 int src_match = __cil_is_type_match(al_src_flavor, src, nv_src_flavor, curr_rule->src); 1396 if (src_match) { 1397 int tgt_match = __cil_is_type_match(al_tgt_flavor, tgt, nv_tgt_flavor, curr_rule->tgt); 1398 if (tgt_match) { 1399 cil_log(CIL_ERR, "Neverallow found that matches avrule at line %d of %s\n", node->line, node->path); 1400 return SEPOL_ERR; 1401 } 1402 } 1403 } 1404 } 1405 } 1406 return SEPOL_OK; 1407 } 1408 1409 int __cil_avrule_expand_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_classperms *cp, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor) 1410 { 1411 int rc = SEPOL_ERR; 1412 type_datum_t *sepol_src = NULL; 1413 type_datum_t *sepol_tgt = NULL; 1414 class_datum_t *sepol_class = NULL; 1415 uint32_t data = 0; 1416 1417 rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class); 1418 if (rc != SEPOL_OK) goto exit; 1419 1420 rc = __cil_perms_to_datum(cp->perms, sepol_class, &data); 1421 if (rc != SEPOL_OK) goto exit; 1422 1423 if (data == 0) { 1424 /* No permissions, so don't insert rule. Maybe should return an error? */ 1425 return SEPOL_OK; 1426 } 1427 1428 if (kind == CIL_AVRULE_NEVERALLOW) { 1429 __cil_neverallow_handle(neverallows, src, tgt, sepol_class->s.value, data); 1430 } else { 1431 if (kind == CIL_AVRULE_DONTAUDIT) { 1432 data = ~data; 1433 } else if (neverallows != NULL && kind == CIL_AVRULE_ALLOWED) { 1434 rc = __cil_check_neverallows(neverallows, src, tgt, sepol_class->s.value, data); 1435 if (rc != SEPOL_OK) { 1436 goto exit; 1437 } 1438 } 1439 1440 rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src); 1441 if (rc != SEPOL_OK) goto exit; 1442 1443 rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt); 1444 if (rc != SEPOL_OK) goto exit; 1445 1446 rc = __cil_insert_avrule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_class->s.value, data, cond_node, cond_flavor); 1447 if (rc != SEPOL_OK) { 1448 goto exit; 1449 } 1450 } 1451 1452 return SEPOL_OK; 1453 1454 exit: 1455 return rc; 1456 } 1457 1458 1459 int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor) 1460 { 1461 int rc = SEPOL_ERR; 1462 struct cil_list_item *curr; 1463 1464 cil_list_for_each(curr, classperms) { 1465 if (curr->flavor == CIL_CLASSPERMS) { 1466 struct cil_classperms *cp = curr->data; 1467 if (FLAVOR(cp->class) == CIL_CLASS) { 1468 rc = __cil_avrule_expand_helper(pdb, kind, src, tgt, cp, neverallows, cond_node, cond_flavor); 1469 if (rc != SEPOL_OK) { 1470 goto exit; 1471 } 1472 } else { /* MAP */ 1473 struct cil_list_item *i = NULL; 1474 cil_list_for_each(i, cp->perms) { 1475 struct cil_perm *cmp = i->data; 1476 rc = __cil_avrule_expand(pdb, kind, src, tgt, cmp->classperms, neverallows, cond_node, cond_flavor); 1477 if (rc != SEPOL_OK) { 1478 goto exit; 1479 } 1480 } 1481 } 1482 } else { /* SET */ 1483 struct cil_classperms_set *cp_set = curr->data; 1484 struct cil_classpermission *cp = cp_set->set; 1485 rc = __cil_avrule_expand(pdb, kind, src, tgt, cp->classperms, neverallows, cond_node, cond_flavor); 1486 if (rc != SEPOL_OK) { 1487 goto exit; 1488 } 1489 } 1490 } 1491 1492 return SEPOL_OK; 1493 1494 exit: 1495 return rc; 1496 } 1497 1498 int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor) 1499 { 1500 int rc = SEPOL_ERR; 1501 uint16_t kind = cil_avrule->rule_kind; 1502 struct cil_symtab_datum *src = NULL; 1503 struct cil_symtab_datum *tgt = NULL; 1504 struct cil_list *classperms = cil_avrule->classperms; 1505 1506 if (cil_avrule->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) { 1507 // Do not add dontaudit rules to binary 1508 rc = SEPOL_OK; 1509 goto exit; 1510 } 1511 1512 if (cil_avrule->rule_kind == CIL_AVRULE_NEVERALLOW && db->disable_neverallow == CIL_TRUE) { 1513 // ignore neverallow rules 1514 rc = SEPOL_OK; 1515 goto exit; 1516 } 1517 1518 src = cil_avrule->src; 1519 tgt = cil_avrule->tgt; 1520 1521 if (tgt->fqn == CIL_KEY_SELF) { 1522 ebitmap_t type_bitmap; 1523 ebitmap_node_t *tnode; 1524 unsigned int i; 1525 1526 rc = __cil_expand_type(src, &type_bitmap); 1527 if (rc != SEPOL_OK) goto exit; 1528 1529 ebitmap_for_each_bit(&type_bitmap, tnode, i) { 1530 if (!ebitmap_get_bit(&type_bitmap, i)) continue; 1531 1532 src = DATUM(db->val_to_type[i]); 1533 rc = __cil_avrule_expand(pdb, kind, src, src, classperms, neverallows, cond_node, cond_flavor); 1534 if (rc != SEPOL_OK) { 1535 ebitmap_destroy(&type_bitmap); 1536 goto exit; 1537 } 1538 } 1539 ebitmap_destroy(&type_bitmap); 1540 } else { 1541 rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, neverallows, cond_node, cond_flavor); 1542 if (rc != SEPOL_OK) goto exit; 1543 } 1544 1545 return SEPOL_OK; 1546 1547 exit: 1548 return rc; 1549 } 1550 1551 int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows) 1552 { 1553 return __cil_avrule_to_avtab(pdb, db, cil_avrule, neverallows, NULL, CIL_FALSE); 1554 } 1555 1556 int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args) 1557 { 1558 int rc; 1559 enum cil_flavor flavor; 1560 struct cil_args_booleanif *args = extra_args; 1561 const struct cil_db *db = args->db; 1562 policydb_t *pdb = args->pdb; 1563 cond_node_t *cond_node = args->cond_node; 1564 enum cil_flavor cond_flavor = args->cond_flavor; 1565 struct cil_type_rule *cil_type_rule; 1566 struct cil_avrule *cil_avrule; 1567 struct cil_nametypetransition *cil_typetrans; 1568 hashtab_t filename_trans_table = args->filename_trans_table; 1569 1570 flavor = node->flavor; 1571 switch (flavor) { 1572 case CIL_NAMETYPETRANSITION: 1573 cil_typetrans = (struct cil_nametypetransition*)node->data; 1574 if (DATUM(cil_typetrans->name)->fqn != CIL_KEY_STAR) { 1575 cil_log(CIL_ERR, "typetransition with file name not allowed within a booleanif block.\n"); 1576 cil_log(CIL_ERR,"Invalid typetransition statement at line %d of %s\n", 1577 node->line, node->path); 1578 goto exit; 1579 } 1580 rc = __cil_typetransition_to_avtab(pdb, db, cil_typetrans, cond_node, cond_flavor, filename_trans_table); 1581 if (rc != SEPOL_OK) { 1582 cil_log(CIL_ERR, "Failed to insert type transition into avtab at line %d of %s\n", node->line, node->path); 1583 goto exit; 1584 } 1585 break; 1586 case CIL_TYPE_RULE: 1587 cil_type_rule = node->data; 1588 rc = __cil_type_rule_to_avtab(pdb, db, cil_type_rule, cond_node, cond_flavor); 1589 if (rc != SEPOL_OK) { 1590 cil_log(CIL_ERR, "Failed to insert typerule into avtab at line %d of %s\n", node->line, node->path); 1591 goto exit; 1592 } 1593 break; 1594 case CIL_AVRULE: 1595 cil_avrule = node->data; 1596 rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, args->neverallows, cond_node, cond_flavor); 1597 if (rc != SEPOL_OK) { 1598 cil_log(CIL_ERR, "Failed to insert avrule into avtab at line %d of %s\n", node->line, node->path); 1599 goto exit; 1600 } 1601 break; 1602 case CIL_CALL: 1603 case CIL_TUNABLEIF: 1604 break; 1605 default: 1606 cil_log(CIL_ERR, "Invalid statement within booleanif at line %d of %s\n", 1607 node->line, node->path); 1608 goto exit; 1609 } 1610 1611 return SEPOL_OK; 1612 1613 exit: 1614 return SEPOL_ERR; 1615 } 1616 1617 static int __cil_cond_expr_to_sepol_expr_helper(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **head, cond_expr_t **tail); 1618 1619 static int __cil_cond_item_to_sepol_expr(policydb_t *pdb, struct cil_list_item *item, cond_expr_t **head, cond_expr_t **tail) 1620 { 1621 if (item == NULL) { 1622 goto exit; 1623 } else if (item->flavor == CIL_DATUM) { 1624 char *key = DATUM(item->data)->fqn; 1625 cond_bool_datum_t *sepol_bool = hashtab_search(pdb->p_bools.table, key); 1626 if (sepol_bool == NULL) { 1627 cil_log(CIL_INFO, "Failed to find boolean\n"); 1628 goto exit; 1629 } 1630 *head = cil_malloc(sizeof(cond_expr_t)); 1631 (*head)->next = NULL; 1632 (*head)->expr_type = COND_BOOL; 1633 (*head)->bool = sepol_bool->s.value; 1634 *tail = *head; 1635 } else if (item->flavor == CIL_LIST) { 1636 struct cil_list *l = item->data; 1637 int rc = __cil_cond_expr_to_sepol_expr_helper(pdb, l, head, tail); 1638 if (rc != SEPOL_OK) { 1639 goto exit; 1640 } 1641 } else { 1642 goto exit; 1643 } 1644 1645 return SEPOL_OK; 1646 1647 exit: 1648 return SEPOL_ERR; 1649 } 1650 1651 static int __cil_cond_expr_to_sepol_expr_helper(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **head, cond_expr_t **tail) 1652 { 1653 int rc = SEPOL_ERR; 1654 struct cil_list_item *item = cil_expr->head; 1655 enum cil_flavor flavor = cil_expr->flavor; 1656 cond_expr_t *op, *h1, *h2, *t1, *t2; 1657 1658 if (flavor != CIL_BOOL) { 1659 cil_log(CIL_INFO, "Expected boolean expression\n"); 1660 goto exit; 1661 } 1662 1663 if (item == NULL) { 1664 goto exit; 1665 } else if (item->flavor == CIL_OP) { 1666 enum cil_flavor cil_op = (enum cil_flavor)item->data; 1667 1668 op = cil_malloc(sizeof(*op)); 1669 op->bool = 0; 1670 op->next = NULL; 1671 1672 switch (cil_op) { 1673 case CIL_NOT: 1674 op->expr_type = COND_NOT; 1675 break; 1676 case CIL_OR: 1677 op->expr_type = COND_OR; 1678 break; 1679 case CIL_AND: 1680 op->expr_type = COND_AND; 1681 break; 1682 case CIL_XOR: 1683 op->expr_type = COND_XOR; 1684 break; 1685 case CIL_EQ: 1686 op->expr_type = COND_EQ; 1687 break; 1688 case CIL_NEQ: 1689 op->expr_type = COND_NEQ; 1690 break; 1691 default: 1692 goto exit; 1693 } 1694 1695 rc = __cil_cond_item_to_sepol_expr(pdb, item->next, &h1, &t1); 1696 if (rc != SEPOL_OK) { 1697 cil_log(CIL_INFO, "Failed to get first operand of conditional expression\n"); 1698 free(op); 1699 goto exit; 1700 } 1701 1702 if (cil_op == CIL_NOT) { 1703 *head = h1; 1704 t1->next = op; 1705 *tail = op; 1706 } else { 1707 rc = __cil_cond_item_to_sepol_expr(pdb, item->next->next, &h2, &t2); 1708 if (rc != SEPOL_OK) { 1709 cil_log(CIL_INFO, "Failed to get second operand of conditional expression\n"); 1710 free(op); 1711 cond_expr_destroy(h1); 1712 goto exit; 1713 } 1714 1715 *head = h1; 1716 t1->next = h2; 1717 t2->next = op; 1718 *tail = op; 1719 } 1720 } else { 1721 rc = __cil_cond_item_to_sepol_expr(pdb, item, &h1, &t1); 1722 if (rc != SEPOL_OK) { 1723 cil_log(CIL_INFO, "Failed to get initial item in conditional list\n"); 1724 goto exit; 1725 } 1726 *head = h1; 1727 for (item = item->next; item; item = item->next) { 1728 rc = __cil_cond_item_to_sepol_expr(pdb, item, &h2, &t2); 1729 if (rc != SEPOL_OK) { 1730 cil_log(CIL_INFO, "Failed to get item in conditional list\n"); 1731 cond_expr_destroy(*head); 1732 goto exit; 1733 } 1734 op = cil_malloc(sizeof(*op)); 1735 op->bool = 0; 1736 op->next = NULL; 1737 op->expr_type = COND_OR; 1738 t1->next = h2; 1739 t2->next = op; 1740 t1 = op; 1741 } 1742 *tail = t1; 1743 } 1744 1745 return SEPOL_OK; 1746 1747 exit: 1748 return SEPOL_ERR; 1749 } 1750 1751 static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **sepol_expr) 1752 { 1753 int rc; 1754 cond_expr_t *head, *tail; 1755 1756 rc = __cil_cond_expr_to_sepol_expr_helper(pdb, cil_expr, &head, &tail); 1757 if (rc != SEPOL_OK) { 1758 return SEPOL_ERR; 1759 } 1760 *sepol_expr = head; 1761 1762 return SEPOL_OK; 1763 } 1764 1765 int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, struct cil_list *neverallows, hashtab_t filename_trans_table) 1766 { 1767 int rc = SEPOL_ERR; 1768 struct cil_args_booleanif bool_args; 1769 struct cil_booleanif *cil_boolif = (struct cil_booleanif*)node->data; 1770 struct cil_tree_node *cb_node = node->cl_head; 1771 struct cil_tree_node *true_node = NULL; 1772 struct cil_tree_node *false_node = NULL; 1773 struct cil_tree_node *tmp_node = NULL; 1774 cond_node_t *tmp_cond = NULL; 1775 cond_node_t *cond_node = NULL; 1776 int was_created; 1777 int swapped = CIL_FALSE; 1778 cond_av_list_t tmp_cl; 1779 1780 tmp_cond = cond_node_create(pdb, NULL); 1781 if (tmp_cond == NULL) { 1782 rc = SEPOL_ERR; 1783 cil_log(CIL_INFO, "Failed to create sepol conditional node at line %d of %s\n", 1784 node->line, node->path); 1785 goto exit; 1786 } 1787 1788 rc = __cil_cond_expr_to_sepol_expr(pdb, cil_boolif->datum_expr, &tmp_cond->expr); 1789 if (rc != SEPOL_OK) { 1790 cil_log(CIL_INFO, "Failed to convert CIL conditional expression to sepol expression at line %d of %s\n", node->line, node->path); 1791 goto exit; 1792 } 1793 1794 tmp_cond->true_list = &tmp_cl; 1795 1796 rc = cond_normalize_expr(pdb, tmp_cond); 1797 if (rc != SEPOL_OK) { 1798 goto exit; 1799 } 1800 1801 if (tmp_cond->false_list != NULL) { 1802 tmp_cond->true_list = NULL; 1803 swapped = CIL_TRUE; 1804 } 1805 1806 cond_node = cond_node_find(pdb, tmp_cond, pdb->cond_list, &was_created); 1807 if (cond_node == NULL) { 1808 rc = SEPOL_ERR; 1809 goto exit; 1810 } 1811 1812 if (was_created) { 1813 cond_node->next = pdb->cond_list; 1814 pdb->cond_list = cond_node; 1815 } 1816 1817 cond_expr_destroy(tmp_cond->expr); 1818 free(tmp_cond); 1819 1820 for (cb_node = node->cl_head; cb_node != NULL; cb_node = cb_node->next) { 1821 if (cb_node->flavor == CIL_CONDBLOCK) { 1822 struct cil_condblock *cb = cb_node->data; 1823 if (cb->flavor == CIL_CONDTRUE) { 1824 true_node = cb_node; 1825 } else if (cb->flavor == CIL_CONDFALSE) { 1826 false_node = cb_node; 1827 } 1828 } 1829 } 1830 1831 if (swapped) { 1832 tmp_node = true_node; 1833 true_node = false_node; 1834 false_node = tmp_node; 1835 } 1836 1837 bool_args.db = db; 1838 bool_args.pdb = pdb; 1839 bool_args.cond_node = cond_node; 1840 bool_args.neverallows = neverallows; 1841 bool_args.filename_trans_table = filename_trans_table; 1842 1843 if (true_node != NULL) { 1844 bool_args.cond_flavor = CIL_CONDTRUE; 1845 rc = cil_tree_walk(true_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args); 1846 if (rc != SEPOL_OK) { 1847 cil_log(CIL_ERR, "Failure while walking true conditional block at line %d of %s\n", true_node->line, true_node->path); 1848 goto exit; 1849 } 1850 } 1851 1852 if (false_node != NULL) { 1853 bool_args.cond_flavor = CIL_CONDFALSE; 1854 rc = cil_tree_walk(false_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args); 1855 if (rc != SEPOL_OK) { 1856 cil_log(CIL_ERR, "Failure while walking false conditional block at line %d of %s\n", false_node->line, false_node->path); 1857 goto exit; 1858 } 1859 } 1860 1861 return SEPOL_OK; 1862 1863 exit: 1864 return rc; 1865 } 1866 1867 int cil_roletrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roletransition *roletrans, hashtab_t role_trans_table) 1868 { 1869 int rc = SEPOL_ERR; 1870 role_datum_t *sepol_src = NULL; 1871 type_datum_t *sepol_tgt = NULL; 1872 class_datum_t *sepol_obj = NULL; 1873 struct cil_list *class_list; 1874 role_datum_t *sepol_result = NULL; 1875 role_trans_t *new = NULL; 1876 uint32_t *new_role = NULL; 1877 ebitmap_t role_bitmap, type_bitmap; 1878 ebitmap_node_t *rnode, *tnode; 1879 unsigned int i, j; 1880 struct cil_list_item *c; 1881 1882 rc = __cil_expand_role(DATUM(roletrans->src), &role_bitmap); 1883 if (rc != SEPOL_OK) goto exit; 1884 1885 rc = __cil_expand_type(roletrans->tgt, &type_bitmap); 1886 if (rc != SEPOL_OK) goto exit; 1887 1888 class_list = cil_expand_class(roletrans->obj); 1889 1890 rc = __cil_get_sepol_role_datum(pdb, DATUM(roletrans->result), &sepol_result); 1891 if (rc != SEPOL_OK) goto exit; 1892 1893 ebitmap_for_each_bit(&role_bitmap, rnode, i) { 1894 if (!ebitmap_get_bit(&role_bitmap, i)) continue; 1895 1896 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src); 1897 if (rc != SEPOL_OK) goto exit; 1898 1899 ebitmap_for_each_bit(&type_bitmap, tnode, j) { 1900 if (!ebitmap_get_bit(&type_bitmap, j)) continue; 1901 1902 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt); 1903 if (rc != SEPOL_OK) goto exit; 1904 1905 cil_list_for_each(c, class_list) { 1906 int add = CIL_TRUE; 1907 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); 1908 if (rc != SEPOL_OK) goto exit; 1909 1910 new = cil_malloc(sizeof(*new)); 1911 memset(new, 0, sizeof(*new)); 1912 new->role = sepol_src->s.value; 1913 new->type = sepol_tgt->s.value; 1914 new->tclass = sepol_obj->s.value; 1915 new->new_role = sepol_result->s.value; 1916 1917 rc = SEPOL_OK; 1918 rc = hashtab_insert(role_trans_table, (hashtab_key_t)new, &(new->new_role)); 1919 if (rc != SEPOL_OK) { 1920 if (rc == SEPOL_EEXIST) { 1921 add = CIL_FALSE; 1922 new_role = hashtab_search(role_trans_table, (hashtab_key_t)new); 1923 if (new->new_role != *new_role) { 1924 cil_log(CIL_ERR, "Conflicting role transition rules\n"); 1925 } else { 1926 rc = SEPOL_OK; 1927 } 1928 } else { 1929 cil_log(CIL_ERR, "Out of memory\n"); 1930 } 1931 } 1932 1933 if (add == CIL_TRUE) { 1934 new->next = pdb->role_tr; 1935 pdb->role_tr = new; 1936 } else { 1937 free(new); 1938 if (rc != SEPOL_OK) { 1939 goto exit; 1940 } 1941 } 1942 } 1943 } 1944 } 1945 1946 rc = SEPOL_OK; 1947 1948 exit: 1949 ebitmap_destroy(&role_bitmap); 1950 ebitmap_destroy(&type_bitmap); 1951 cil_list_destroy(&class_list, CIL_FALSE); 1952 return rc; 1953 } 1954 1955 int cil_roleallow_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roleallow *roleallow) 1956 { 1957 int rc = SEPOL_ERR; 1958 role_datum_t *sepol_src = NULL; 1959 role_datum_t *sepol_tgt = NULL; 1960 role_allow_t *sepol_roleallow = NULL; 1961 ebitmap_t src_bitmap, tgt_bitmap; 1962 ebitmap_node_t *node1, *node2; 1963 unsigned int i, j; 1964 1965 rc = __cil_expand_role(roleallow->src, &src_bitmap); 1966 if (rc != SEPOL_OK) goto exit; 1967 1968 rc = __cil_expand_role(roleallow->tgt, &tgt_bitmap); 1969 if (rc != SEPOL_OK) goto exit; 1970 1971 ebitmap_for_each_bit(&src_bitmap, node1, i) { 1972 if (!ebitmap_get_bit(&src_bitmap, i)) continue; 1973 1974 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src); 1975 if (rc != SEPOL_OK) goto exit; 1976 1977 ebitmap_for_each_bit(&tgt_bitmap, node2, j) { 1978 if (!ebitmap_get_bit(&tgt_bitmap, j)) continue; 1979 1980 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[j]), &sepol_tgt); 1981 if (rc != SEPOL_OK) goto exit; 1982 1983 sepol_roleallow = cil_malloc(sizeof(*sepol_roleallow)); 1984 memset(sepol_roleallow, 0, sizeof(role_allow_t)); 1985 sepol_roleallow->role = sepol_src->s.value; 1986 sepol_roleallow->new_role = sepol_tgt->s.value; 1987 1988 sepol_roleallow->next = pdb->role_allow; 1989 pdb->role_allow = sepol_roleallow; 1990 } 1991 } 1992 1993 rc = SEPOL_OK; 1994 1995 exit: 1996 ebitmap_destroy(&src_bitmap); 1997 ebitmap_destroy(&tgt_bitmap); 1998 return rc; 1999 } 2000 2001 int __cil_constrain_expr_datum_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, struct cil_list_item *item, enum cil_flavor expr_flavor, constraint_expr_t *expr) 2002 { 2003 int rc = SEPOL_ERR; 2004 2005 if (expr_flavor == CIL_USER) { 2006 user_datum_t *sepol_user = NULL; 2007 rc = __cil_get_sepol_user_datum(pdb, item->data, &sepol_user); 2008 if (rc != SEPOL_OK) goto exit; 2009 2010 if (ebitmap_set_bit(&expr->names, sepol_user->s.value - 1, 1)) { 2011 goto exit; 2012 } 2013 } else if (expr_flavor == CIL_ROLE) { 2014 role_datum_t *sepol_role = NULL; 2015 ebitmap_t role_bitmap; 2016 ebitmap_node_t *rnode; 2017 unsigned int i; 2018 2019 rc = __cil_expand_role(item->data, &role_bitmap); 2020 if (rc != SEPOL_OK) goto exit; 2021 2022 ebitmap_for_each_bit(&role_bitmap, rnode, i) { 2023 if (!ebitmap_get_bit(&role_bitmap, i)) continue; 2024 2025 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role); 2026 if (rc != SEPOL_OK) { 2027 ebitmap_destroy(&role_bitmap); 2028 goto exit; 2029 } 2030 2031 if (ebitmap_set_bit(&expr->names, sepol_role->s.value - 1, 1)) { 2032 ebitmap_destroy(&role_bitmap); 2033 goto exit; 2034 } 2035 } 2036 ebitmap_destroy(&role_bitmap); 2037 } else if (expr_flavor == CIL_TYPE) { 2038 type_datum_t *sepol_type = NULL; 2039 ebitmap_t type_bitmap; 2040 ebitmap_node_t *tnode; 2041 unsigned int i; 2042 2043 if (pdb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) { 2044 rc = __cil_get_sepol_type_datum(pdb, item->data, &sepol_type); 2045 if (rc != SEPOL_OK) { 2046 ebitmap_destroy(&type_bitmap); 2047 goto exit; 2048 } 2049 2050 if (ebitmap_set_bit(&expr->type_names->types, sepol_type->s.value - 1, 1)) { 2051 ebitmap_destroy(&type_bitmap); 2052 goto exit; 2053 } 2054 } 2055 2056 rc = __cil_expand_type(item->data, &type_bitmap); 2057 if (rc != SEPOL_OK) goto exit; 2058 2059 ebitmap_for_each_bit(&type_bitmap, tnode, i) { 2060 if (!ebitmap_get_bit(&type_bitmap, i)) continue; 2061 2062 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type); 2063 if (rc != SEPOL_OK) { 2064 ebitmap_destroy(&type_bitmap); 2065 goto exit; 2066 } 2067 2068 if (ebitmap_set_bit(&expr->names, sepol_type->s.value - 1, 1)) { 2069 ebitmap_destroy(&type_bitmap); 2070 goto exit; 2071 } 2072 } 2073 ebitmap_destroy(&type_bitmap); 2074 } else { 2075 goto exit; 2076 } 2077 2078 return SEPOL_OK; 2079 2080 exit: 2081 return SEPOL_ERR; 2082 } 2083 2084 int __cil_constrain_expr_leaf_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, struct cil_list_item *op_item, enum cil_flavor expr_flavor, constraint_expr_t *expr) 2085 { 2086 int rc = SEPOL_ERR; 2087 struct cil_list_item *l_item = op_item->next; 2088 struct cil_list_item *r_item = op_item->next->next; 2089 2090 enum cil_flavor l_operand = (enum cil_flavor)l_item->data; 2091 2092 switch (l_operand) { 2093 case CIL_CONS_U1: 2094 expr->attr = CEXPR_USER; 2095 break; 2096 case CIL_CONS_U2: 2097 expr->attr = CEXPR_USER | CEXPR_TARGET; 2098 break; 2099 case CIL_CONS_U3: 2100 expr->attr = CEXPR_USER | CEXPR_XTARGET; 2101 break; 2102 case CIL_CONS_R1: 2103 expr->attr = CEXPR_ROLE; 2104 break; 2105 case CIL_CONS_R2: 2106 expr->attr = CEXPR_ROLE | CEXPR_TARGET; 2107 break; 2108 case CIL_CONS_R3: 2109 expr->attr = CEXPR_ROLE | CEXPR_XTARGET; 2110 break; 2111 case CIL_CONS_T1: 2112 expr->attr = CEXPR_TYPE; 2113 break; 2114 case CIL_CONS_T2: 2115 expr->attr = CEXPR_TYPE | CEXPR_TARGET; 2116 break; 2117 case CIL_CONS_T3: 2118 expr->attr = CEXPR_TYPE | CEXPR_XTARGET; 2119 break; 2120 case CIL_CONS_L1: { 2121 enum cil_flavor r_operand = (enum cil_flavor)r_item->data; 2122 2123 if (r_operand == CIL_CONS_L2) { 2124 expr->attr = CEXPR_L1L2; 2125 } else if (r_operand == CIL_CONS_H1) { 2126 expr->attr = CEXPR_L1H1; 2127 } else { 2128 expr->attr = CEXPR_L1H2; 2129 } 2130 break; 2131 } 2132 case CIL_CONS_L2: 2133 expr->attr = CEXPR_L2H2; 2134 break; 2135 case CIL_CONS_H1: { 2136 enum cil_flavor r_operand = (enum cil_flavor)r_item->data; 2137 if (r_operand == CIL_CONS_L2) { 2138 expr->attr = CEXPR_H1L2; 2139 } else { 2140 expr->attr = CEXPR_H1H2; 2141 } 2142 break; 2143 } 2144 default: 2145 goto exit; 2146 break; 2147 } 2148 2149 if (r_item->flavor == CIL_CONS_OPERAND) { 2150 expr->expr_type = CEXPR_ATTR; 2151 } else { 2152 expr->expr_type = CEXPR_NAMES; 2153 if (r_item->flavor == CIL_DATUM) { 2154 rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, r_item, expr_flavor, expr); 2155 if (rc != SEPOL_OK) { 2156 goto exit; 2157 } 2158 } else if (r_item->flavor == CIL_LIST) { 2159 struct cil_list *r_expr = r_item->data; 2160 struct cil_list_item *curr; 2161 cil_list_for_each(curr, r_expr) { 2162 rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, curr, expr_flavor, expr); 2163 if (rc != SEPOL_OK) { 2164 goto exit; 2165 } 2166 } 2167 } else { 2168 rc = SEPOL_ERR; 2169 goto exit; 2170 } 2171 } 2172 2173 return SEPOL_OK; 2174 2175 exit: 2176 return rc; 2177 } 2178 2179 int __cil_constrain_expr_to_sepol_expr_helper(policydb_t *pdb, const struct cil_db *db, const struct cil_list *cil_expr, constraint_expr_t **head, constraint_expr_t **tail) 2180 { 2181 int rc = SEPOL_ERR; 2182 struct cil_list_item *item; 2183 enum cil_flavor flavor; 2184 constraint_expr_t *op, *h1, *h2, *t1, *t2; 2185 int is_leaf = CIL_FALSE; 2186 2187 if (cil_expr == NULL) { 2188 return SEPOL_ERR; 2189 } 2190 2191 item = cil_expr->head; 2192 flavor = cil_expr->flavor; 2193 2194 op = cil_malloc(sizeof(constraint_expr_t)); 2195 rc = constraint_expr_init(op); 2196 if (rc != SEPOL_OK) { 2197 goto exit; 2198 } 2199 2200 enum cil_flavor cil_op = (enum cil_flavor)item->data; 2201 switch (cil_op) { 2202 case CIL_NOT: 2203 op->expr_type = CEXPR_NOT; 2204 break; 2205 case CIL_AND: 2206 op->expr_type = CEXPR_AND; 2207 break; 2208 case CIL_OR: 2209 op->expr_type = CEXPR_OR; 2210 break; 2211 case CIL_EQ: 2212 op->op = CEXPR_EQ; 2213 is_leaf = CIL_TRUE; 2214 break; 2215 case CIL_NEQ: 2216 op->op = CEXPR_NEQ; 2217 is_leaf = CIL_TRUE; 2218 break; 2219 case CIL_CONS_DOM: 2220 op->op = CEXPR_DOM; 2221 is_leaf = CIL_TRUE; 2222 break; 2223 case CIL_CONS_DOMBY: 2224 op->op = CEXPR_DOMBY; 2225 is_leaf = CIL_TRUE; 2226 break; 2227 case CIL_CONS_INCOMP: 2228 op->op = CEXPR_INCOMP; 2229 is_leaf = CIL_TRUE; 2230 break; 2231 default: 2232 goto exit; 2233 } 2234 2235 if (is_leaf == CIL_TRUE) { 2236 rc = __cil_constrain_expr_leaf_to_sepol_expr(pdb, db, item, flavor, op); 2237 if (rc != SEPOL_OK) { 2238 goto exit; 2239 } 2240 *head = op; 2241 *tail = op; 2242 } else if (cil_op == CIL_NOT) { 2243 struct cil_list *l_expr = item->next->data; 2244 rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1); 2245 if (rc != SEPOL_OK) { 2246 goto exit; 2247 } 2248 t1->next = op; 2249 *head = h1; 2250 *tail = op; 2251 } else { 2252 struct cil_list *l_expr = item->next->data; 2253 struct cil_list *r_expr = item->next->next->data; 2254 rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1); 2255 if (rc != SEPOL_OK) { 2256 goto exit; 2257 } 2258 rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, r_expr, &h2, &t2); 2259 if (rc != SEPOL_OK) { 2260 constraint_expr_destroy(h1); 2261 goto exit; 2262 } 2263 t1->next = h2; 2264 t2->next = op; 2265 *head = h1; 2266 *tail = op; 2267 } 2268 2269 return SEPOL_OK; 2270 2271 exit: 2272 constraint_expr_destroy(op); 2273 return SEPOL_ERR; 2274 } 2275 2276 int __cil_constrain_expr_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, const struct cil_list *cil_expr, constraint_expr_t **sepol_expr) 2277 { 2278 int rc; 2279 constraint_expr_t *head, *tail; 2280 2281 rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, cil_expr, &head, &tail); 2282 if (rc != SEPOL_OK) { 2283 return SEPOL_ERR; 2284 } 2285 2286 *sepol_expr = head; 2287 2288 return SEPOL_OK; 2289 } 2290 2291 int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *class, struct cil_list *perms, struct cil_list *expr) 2292 { 2293 int rc = SEPOL_ERR; 2294 constraint_node_t *sepol_constrain = NULL; 2295 constraint_expr_t *sepol_expr = NULL; 2296 class_datum_t *sepol_class = NULL; 2297 2298 sepol_constrain = cil_malloc(sizeof(*sepol_constrain)); 2299 memset(sepol_constrain, 0, sizeof(constraint_node_t)); 2300 2301 rc = __cil_get_sepol_class_datum(pdb, class, &sepol_class); 2302 if (rc != SEPOL_OK) goto exit; 2303 2304 rc = __cil_perms_to_datum(perms, sepol_class, &sepol_constrain->permissions); 2305 if (rc != SEPOL_OK) { 2306 goto exit; 2307 } 2308 2309 rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr); 2310 if (rc != SEPOL_OK) { 2311 goto exit; 2312 } 2313 2314 sepol_constrain->expr = sepol_expr; 2315 sepol_constrain->next = sepol_class->constraints; 2316 sepol_class->constraints = sepol_constrain; 2317 2318 return SEPOL_OK; 2319 2320 exit: 2321 free(sepol_constrain); 2322 return rc; 2323 } 2324 2325 int cil_constrain_expand(policydb_t *pdb, const struct cil_db *db, struct cil_list *classperms, struct cil_list *expr) 2326 { 2327 int rc = SEPOL_ERR; 2328 struct cil_list_item *curr; 2329 2330 cil_list_for_each(curr, classperms) { 2331 if (curr->flavor == CIL_CLASSPERMS) { 2332 struct cil_classperms *cp = curr->data; 2333 if (FLAVOR(cp->class) == CIL_CLASS) { 2334 rc = cil_constrain_to_policydb_helper(pdb, db, DATUM(cp->class), cp->perms, expr); 2335 if (rc != SEPOL_OK) { 2336 goto exit; 2337 } 2338 } else { /* MAP */ 2339 struct cil_list_item *i = NULL; 2340 cil_list_for_each(i, cp->perms) { 2341 struct cil_perm *cmp = i->data; 2342 rc = cil_constrain_expand(pdb, db, cmp->classperms, expr); 2343 if (rc != SEPOL_OK) { 2344 goto exit; 2345 } 2346 } 2347 } 2348 } else { /* SET */ 2349 struct cil_classperms_set *cp_set = curr->data; 2350 struct cil_classpermission *cp = cp_set->set; 2351 rc = cil_constrain_expand(pdb, db, cp->classperms, expr); 2352 if (rc != SEPOL_OK) { 2353 goto exit; 2354 } 2355 } 2356 } 2357 2358 return SEPOL_OK; 2359 2360 exit: 2361 return rc; 2362 } 2363 2364 int cil_constrain_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_constrain *cil_constrain) 2365 { 2366 int rc = SEPOL_ERR; 2367 rc = cil_constrain_expand(pdb, db, cil_constrain->classperms, cil_constrain->datum_expr); 2368 if (rc != SEPOL_OK) { 2369 goto exit; 2370 } 2371 2372 return SEPOL_OK; 2373 2374 exit: 2375 cil_log(CIL_ERR, "Failed to insert constraint into policydb\n"); 2376 return rc; 2377 } 2378 2379 int cil_validatetrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_validatetrans *cil_validatetrans) 2380 { 2381 int rc = SEPOL_ERR; 2382 struct cil_list *expr = cil_validatetrans->datum_expr; 2383 class_datum_t *sepol_class = NULL; 2384 struct cil_list *class_list; 2385 constraint_node_t *sepol_validatetrans = NULL; 2386 constraint_expr_t *sepol_expr = NULL; 2387 struct cil_list_item *c; 2388 2389 class_list = cil_expand_class(cil_validatetrans->class); 2390 2391 cil_list_for_each(c, class_list) { 2392 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); 2393 if (rc != SEPOL_OK) goto exit; 2394 2395 sepol_validatetrans = cil_malloc(sizeof(*sepol_validatetrans)); 2396 memset(sepol_validatetrans, 0, sizeof(constraint_node_t)); 2397 2398 rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr); 2399 if (rc != SEPOL_OK) { 2400 free(sepol_validatetrans); 2401 goto exit; 2402 } 2403 sepol_validatetrans->expr = sepol_expr; 2404 2405 sepol_validatetrans->next = sepol_class->validatetrans; 2406 sepol_class->validatetrans = sepol_validatetrans; 2407 } 2408 2409 rc = SEPOL_OK; 2410 2411 exit: 2412 cil_list_destroy(&class_list, CIL_FALSE); 2413 return rc; 2414 } 2415 2416 int __cil_cats_to_mls_level(policydb_t *pdb, struct cil_cats *cats, mls_level_t *mls_level) 2417 { 2418 int rc = SEPOL_ERR; 2419 struct cil_list_item *i; 2420 cat_datum_t *sepol_cat = NULL; 2421 2422 cil_list_for_each(i, cats->datum_expr) { 2423 struct cil_tree_node *node = DATUM(i->data)->nodes->head->data; 2424 if (node->flavor == CIL_CATSET) { 2425 struct cil_list_item *j; 2426 struct cil_catset *cs = i->data; 2427 cil_list_for_each(j, cs->cats->datum_expr) { 2428 rc = __cil_get_sepol_cat_datum(pdb, j->data, &sepol_cat); 2429 if (rc != SEPOL_OK) goto exit; 2430 2431 rc = ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1); 2432 if (rc != SEPOL_OK) goto exit; 2433 } 2434 } else { 2435 rc = __cil_get_sepol_cat_datum(pdb, i->data, &sepol_cat); 2436 if (rc != SEPOL_OK) goto exit; 2437 2438 rc = ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1); 2439 if (rc != SEPOL_OK) goto exit; 2440 } 2441 } 2442 2443 return SEPOL_OK; 2444 2445 exit: 2446 return SEPOL_ERR; 2447 } 2448 2449 int cil_sepol_level_define(policydb_t *pdb, struct cil_sens *cil_sens) 2450 { 2451 int rc = SEPOL_ERR; 2452 struct cil_list_item *curr; 2453 level_datum_t *sepol_level = NULL; 2454 mls_level_t *mls_level = NULL; 2455 2456 rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level); 2457 if (rc != SEPOL_OK) goto exit; 2458 2459 mls_level = sepol_level->level; 2460 2461 ebitmap_init(&mls_level->cat); 2462 2463 if (cil_sens->cats_list) { 2464 cil_list_for_each(curr, cil_sens->cats_list) { 2465 struct cil_cats *cats = curr->data; 2466 rc = __cil_cats_to_mls_level(pdb, cats, mls_level); 2467 if (rc != SEPOL_OK) { 2468 cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n"); 2469 goto exit; 2470 } 2471 } 2472 } 2473 2474 sepol_level->defined = 1; 2475 2476 return SEPOL_OK; 2477 2478 exit: 2479 return rc; 2480 } 2481 2482 int cil_level_to_mls_level(policydb_t *pdb, struct cil_level *cil_level, mls_level_t *mls_level) 2483 { 2484 int rc = SEPOL_ERR; 2485 struct cil_sens *cil_sens = cil_level->sens; 2486 struct cil_cats *cats = cil_level->cats; 2487 level_datum_t *sepol_level = NULL; 2488 2489 rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level); 2490 if (rc != SEPOL_OK) goto exit; 2491 2492 mls_level->sens = sepol_level->level->sens; 2493 2494 ebitmap_init(&mls_level->cat); 2495 2496 if (cats != NULL) { 2497 rc = __cil_cats_to_mls_level(pdb, cats, mls_level); 2498 if (rc != SEPOL_OK) { 2499 cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n"); 2500 goto exit; 2501 } 2502 } 2503 2504 rc = SEPOL_OK; 2505 exit: 2506 return rc; 2507 } 2508 2509 int __cil_levelrange_to_mls_range(policydb_t *pdb, struct cil_levelrange *cil_lvlrange, mls_range_t *mls_range) 2510 { 2511 int rc = SEPOL_ERR; 2512 struct cil_level *low = cil_lvlrange->low; 2513 struct cil_level *high = cil_lvlrange->high; 2514 mls_level_t *mls_level = NULL; 2515 2516 mls_level = &mls_range->level[0]; 2517 2518 rc = cil_level_to_mls_level(pdb, low, mls_level); 2519 if (rc != SEPOL_OK) { 2520 goto exit; 2521 } 2522 2523 mls_level = &mls_range->level[1]; 2524 2525 rc = cil_level_to_mls_level(pdb, high, mls_level); 2526 if (rc != SEPOL_OK) { 2527 goto exit; 2528 } 2529 2530 return SEPOL_OK; 2531 2532 exit: 2533 return rc; 2534 } 2535 2536 int cil_userlevel_userrange_to_policydb(policydb_t *pdb, struct cil_user *cil_user) 2537 { 2538 int rc = SEPOL_ERR; 2539 struct cil_level *cil_level = cil_user->dftlevel; 2540 struct cil_levelrange *cil_levelrange = cil_user->range; 2541 user_datum_t *sepol_user = NULL; 2542 2543 rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user); 2544 if (rc != SEPOL_OK) goto exit; 2545 2546 rc = cil_level_to_mls_level(pdb, cil_level, &sepol_user->exp_dfltlevel); 2547 if (rc != SEPOL_OK) { 2548 goto exit; 2549 } 2550 2551 rc = __cil_levelrange_to_mls_range(pdb, cil_levelrange, &sepol_user->exp_range); 2552 if (rc != SEPOL_OK) { 2553 goto exit; 2554 } 2555 2556 return SEPOL_OK; 2557 2558 exit: 2559 return rc; 2560 } 2561 2562 int __cil_context_to_sepol_context(policydb_t *pdb, struct cil_context *cil_context, context_struct_t *sepol_context) 2563 { 2564 int rc = SEPOL_ERR; 2565 struct cil_levelrange *cil_lvlrange = cil_context->range; 2566 user_datum_t *sepol_user = NULL; 2567 role_datum_t *sepol_role = NULL; 2568 type_datum_t *sepol_type = NULL; 2569 2570 rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_context->user), &sepol_user); 2571 if (rc != SEPOL_OK) goto exit; 2572 2573 rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_context->role), &sepol_role); 2574 if (rc != SEPOL_OK) goto exit; 2575 2576 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_context->type), &sepol_type); 2577 if (rc != SEPOL_OK) goto exit; 2578 2579 sepol_context->user = sepol_user->s.value; 2580 sepol_context->role = sepol_role->s.value; 2581 sepol_context->type = sepol_type->s.value; 2582 2583 if (pdb->mls == CIL_TRUE) { 2584 mls_context_init(sepol_context); 2585 2586 rc = __cil_levelrange_to_mls_range(pdb, cil_lvlrange, &sepol_context->range); 2587 if (rc != SEPOL_OK) { 2588 cil_log(CIL_ERR,"Problem with MLS\n"); 2589 mls_context_destroy(sepol_context); 2590 goto exit; 2591 } 2592 } 2593 2594 return SEPOL_OK; 2595 2596 exit: 2597 return rc; 2598 } 2599 2600 int cil_sidorder_to_policydb(policydb_t *pdb, const struct cil_db *db) 2601 { 2602 int rc = SEPOL_ERR; 2603 struct cil_list_item *curr; 2604 unsigned count = 0; 2605 ocontext_t *tail = NULL; 2606 2607 if (db->sidorder == NULL || db->sidorder->head == NULL) { 2608 cil_log(CIL_WARN, "No sidorder statement in policy\n"); 2609 return SEPOL_OK; 2610 } 2611 2612 cil_list_for_each(curr, db->sidorder) { 2613 struct cil_sid *cil_sid = (struct cil_sid*)curr->data; 2614 struct cil_context *cil_context = cil_sid->context; 2615 2616 if (cil_context != NULL) { 2617 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_ISID], &tail); 2618 count++; 2619 new_ocon->sid[0] = count; 2620 new_ocon->u.name = cil_strdup(cil_sid->datum.fqn); 2621 rc = __cil_context_to_sepol_context(pdb, cil_context, &new_ocon->context[0]); 2622 if (rc != SEPOL_OK) { 2623 cil_log(CIL_ERR,"Problem with context for SID %s\n",cil_sid->datum.fqn); 2624 goto exit; 2625 } 2626 } 2627 } 2628 2629 return SEPOL_OK; 2630 2631 exit: 2632 return rc; 2633 } 2634 2635 int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans, hashtab_t range_trans_table) 2636 { 2637 int rc = SEPOL_ERR; 2638 type_datum_t *sepol_src = NULL; 2639 type_datum_t *sepol_tgt = NULL; 2640 class_datum_t *sepol_class = NULL; 2641 struct cil_list *class_list; 2642 range_trans_t *new; 2643 ebitmap_t src_bitmap, tgt_bitmap; 2644 ebitmap_node_t *node1, *node2; 2645 unsigned int i, j; 2646 struct cil_list_item *c; 2647 struct mls_range *o_range = NULL; 2648 2649 rc = __cil_expand_type(rangetrans->src, &src_bitmap); 2650 if (rc != SEPOL_OK) goto exit; 2651 2652 rc = __cil_expand_type(rangetrans->exec, &tgt_bitmap); 2653 if (rc != SEPOL_OK) goto exit; 2654 2655 class_list = cil_expand_class(rangetrans->obj); 2656 2657 ebitmap_for_each_bit(&src_bitmap, node1, i) { 2658 if (!ebitmap_get_bit(&src_bitmap, i)) continue; 2659 2660 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); 2661 if (rc != SEPOL_OK) goto exit; 2662 2663 ebitmap_for_each_bit(&tgt_bitmap, node2, j) { 2664 if (!ebitmap_get_bit(&tgt_bitmap, j)) continue; 2665 2666 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt); 2667 if (rc != SEPOL_OK) goto exit; 2668 2669 cil_list_for_each(c, class_list) { 2670 int add = CIL_TRUE; 2671 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); 2672 if (rc != SEPOL_OK) goto exit; 2673 2674 new = cil_malloc(sizeof(*new)); 2675 memset(new, 0, sizeof(range_trans_t)); 2676 new->source_type = sepol_src->s.value; 2677 new->target_type = sepol_tgt->s.value; 2678 new->target_class = sepol_class->s.value; 2679 rc = __cil_levelrange_to_mls_range(pdb, rangetrans->range, &new->target_range); 2680 if (rc != SEPOL_OK) { 2681 free(new); 2682 goto exit; 2683 } 2684 2685 rc = SEPOL_OK; 2686 rc = hashtab_insert(range_trans_table, (hashtab_key_t)new, &(new->target_range)); 2687 if (rc != SEPOL_OK) { 2688 if (rc == SEPOL_EEXIST) { 2689 add = CIL_FALSE; 2690 o_range = hashtab_search(range_trans_table, (hashtab_key_t)new); 2691 if (!mls_range_eq(&new->target_range, o_range)) { 2692 cil_log(CIL_ERR, "Conflicting Range transition rules\n"); 2693 } else { 2694 rc = SEPOL_OK; 2695 } 2696 } else { 2697 cil_log(CIL_ERR, "Out of memory\n"); 2698 } 2699 } 2700 2701 if (add == CIL_TRUE) { 2702 new->next = pdb->range_tr; 2703 pdb->range_tr = new; 2704 } else { 2705 mls_range_destroy(&new->target_range); 2706 free(new); 2707 if (rc != SEPOL_OK) { 2708 goto exit; 2709 } 2710 } 2711 } 2712 } 2713 } 2714 2715 rc = SEPOL_OK; 2716 2717 exit: 2718 ebitmap_destroy(&src_bitmap); 2719 ebitmap_destroy(&tgt_bitmap); 2720 cil_list_destroy(&class_list, CIL_FALSE); 2721 return rc; 2722 } 2723 2724 int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons) 2725 { 2726 int rc = SEPOL_ERR; 2727 uint32_t i = 0; 2728 ocontext_t *tail = NULL; 2729 2730 for (i = 0; i < portcons->count; i++) { 2731 struct cil_portcon *cil_portcon = portcons->array[i]; 2732 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_PORT], &tail); 2733 2734 switch (cil_portcon->proto) { 2735 case CIL_PROTOCOL_UDP: 2736 new_ocon->u.port.protocol = IPPROTO_UDP; 2737 break; 2738 case CIL_PROTOCOL_TCP: 2739 new_ocon->u.port.protocol = IPPROTO_TCP; 2740 break; 2741 default: 2742 /* should not get here */ 2743 rc = SEPOL_ERR; 2744 goto exit; 2745 } 2746 2747 new_ocon->u.port.low_port = cil_portcon->port_low; 2748 new_ocon->u.port.high_port = cil_portcon->port_high; 2749 2750 rc = __cil_context_to_sepol_context(pdb, cil_portcon->context, &new_ocon->context[0]); 2751 if (rc != SEPOL_OK) { 2752 goto exit; 2753 } 2754 } 2755 2756 return SEPOL_OK; 2757 2758 exit: 2759 return rc; 2760 } 2761 2762 int cil_netifcon_to_policydb(policydb_t *pdb, struct cil_sort *netifcons) 2763 { 2764 int rc = SEPOL_ERR; 2765 uint32_t i = 0; 2766 ocontext_t *tail = NULL; 2767 2768 for (i = 0; i < netifcons->count; i++) { 2769 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NETIF], &tail); 2770 struct cil_netifcon *cil_netifcon = netifcons->array[i]; 2771 2772 new_ocon->u.name = cil_strdup(cil_netifcon->interface_str); 2773 2774 rc = __cil_context_to_sepol_context(pdb, cil_netifcon->if_context, &new_ocon->context[0]); 2775 if (rc != SEPOL_OK) { 2776 goto exit; 2777 } 2778 2779 rc = __cil_context_to_sepol_context(pdb, cil_netifcon->packet_context, &new_ocon->context[1]); 2780 if (rc != SEPOL_OK) { 2781 context_destroy(&new_ocon->context[0]); 2782 goto exit; 2783 } 2784 } 2785 2786 return SEPOL_OK; 2787 2788 exit: 2789 return rc; 2790 } 2791 2792 int cil_nodecon_to_policydb(policydb_t *pdb, struct cil_sort *nodecons) 2793 { 2794 int rc = SEPOL_ERR; 2795 uint32_t i = 0; 2796 ocontext_t *tail = NULL; 2797 ocontext_t *tail6 = NULL; 2798 2799 for (i = 0; i < nodecons->count; i++) { 2800 ocontext_t *new_ocon = NULL; 2801 struct cil_nodecon *cil_nodecon = nodecons->array[i]; 2802 2803 if (cil_nodecon->addr->family == AF_INET) { 2804 new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE], &tail); 2805 new_ocon->u.node.addr = cil_nodecon->addr->ip.v4.s_addr; 2806 new_ocon->u.node.mask = cil_nodecon->mask->ip.v4.s_addr; 2807 } else if (cil_nodecon->addr->family == AF_INET6) { 2808 new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE6], &tail6); 2809 memcpy(new_ocon->u.node6.addr, &cil_nodecon->addr->ip.v6.s6_addr[0], 16); 2810 memcpy(new_ocon->u.node6.mask, &cil_nodecon->mask->ip.v6.s6_addr[0], 16); 2811 } else { 2812 /* should not get here */ 2813 rc = SEPOL_ERR; 2814 goto exit; 2815 } 2816 2817 rc = __cil_context_to_sepol_context(pdb, cil_nodecon->context, &new_ocon->context[0]); 2818 if (rc != SEPOL_OK) { 2819 goto exit; 2820 } 2821 } 2822 2823 return SEPOL_OK; 2824 2825 exit: 2826 return rc; 2827 } 2828 2829 int cil_fsuse_to_policydb(policydb_t *pdb, struct cil_sort *fsuses) 2830 { 2831 int rc = SEPOL_ERR; 2832 uint32_t i = 0; 2833 ocontext_t *tail = NULL; 2834 2835 for (i = 0; i < fsuses->count; i++) { 2836 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_FSUSE], &tail); 2837 struct cil_fsuse *cil_fsuse = fsuses->array[i]; 2838 2839 new_ocon->u.name = cil_strdup(cil_fsuse->fs_str); 2840 new_ocon->v.behavior = cil_fsuse->type; 2841 2842 rc = __cil_context_to_sepol_context(pdb, cil_fsuse->context, &new_ocon->context[0]); 2843 if (rc != SEPOL_OK) { 2844 goto exit; 2845 } 2846 } 2847 2848 return SEPOL_OK; 2849 2850 exit: 2851 return rc; 2852 } 2853 2854 int cil_genfscon_to_policydb(policydb_t *pdb, struct cil_sort *genfscons) 2855 { 2856 int rc = SEPOL_ERR; 2857 uint32_t i = 0; 2858 genfs_t *genfs_tail = NULL; 2859 ocontext_t *ocon_tail = NULL; 2860 2861 for (i = 0; i < genfscons->count; i++) { 2862 struct cil_genfscon *cil_genfscon = genfscons->array[i]; 2863 ocontext_t *new_ocon = cil_malloc(sizeof(ocontext_t)); 2864 memset(new_ocon, 0, sizeof(ocontext_t)); 2865 2866 if (genfs_tail && strcmp(genfs_tail->fstype, cil_genfscon->fs_str) == 0) { 2867 ocon_tail->next = new_ocon; 2868 } else { 2869 genfs_t *new_genfs = cil_malloc(sizeof(genfs_t)); 2870 memset(new_genfs, 0, sizeof(genfs_t)); 2871 new_genfs->fstype = cil_strdup(cil_genfscon->fs_str); 2872 new_genfs->head = new_ocon; 2873 2874 if (genfs_tail) { 2875 genfs_tail->next = new_genfs; 2876 } else { 2877 pdb->genfs = new_genfs; 2878 } 2879 genfs_tail = new_genfs; 2880 } 2881 2882 ocon_tail = new_ocon; 2883 2884 new_ocon->u.name = cil_strdup(cil_genfscon->path_str); 2885 2886 rc = __cil_context_to_sepol_context(pdb, cil_genfscon->context, &new_ocon->context[0]); 2887 if (rc != SEPOL_OK) { 2888 goto exit; 2889 } 2890 } 2891 2892 return SEPOL_OK; 2893 2894 exit: 2895 return rc; 2896 } 2897 2898 int cil_pirqcon_to_policydb(policydb_t *pdb, struct cil_sort *pirqcons) 2899 { 2900 int rc = SEPOL_ERR; 2901 uint32_t i = 0; 2902 ocontext_t *tail = NULL; 2903 2904 for (i = 0; i < pirqcons->count; i++) { 2905 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PIRQ], &tail); 2906 struct cil_pirqcon *cil_pirqcon = pirqcons->array[i]; 2907 2908 new_ocon->u.pirq = cil_pirqcon->pirq; 2909 2910 rc = __cil_context_to_sepol_context(pdb, cil_pirqcon->context, &new_ocon->context[0]); 2911 if (rc != SEPOL_OK) { 2912 goto exit; 2913 } 2914 } 2915 2916 return SEPOL_OK; 2917 2918 exit: 2919 return rc; 2920 } 2921 2922 int cil_iomemcon_to_policydb(policydb_t *pdb, struct cil_sort *iomemcons) 2923 { 2924 int rc = SEPOL_ERR; 2925 uint32_t i = 0; 2926 ocontext_t *tail = NULL; 2927 2928 for (i = 0; i < iomemcons->count; i++) { 2929 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOMEM], &tail); 2930 struct cil_iomemcon *cil_iomemcon = iomemcons->array[i]; 2931 2932 new_ocon->u.iomem.low_iomem = cil_iomemcon->iomem_low; 2933 new_ocon->u.iomem.high_iomem = cil_iomemcon->iomem_high; 2934 2935 rc = __cil_context_to_sepol_context(pdb, cil_iomemcon->context, &new_ocon->context[0]); 2936 if (rc != SEPOL_OK) { 2937 goto exit; 2938 } 2939 } 2940 2941 return SEPOL_OK; 2942 2943 exit: 2944 return rc; 2945 } 2946 2947 int cil_ioportcon_to_policydb(policydb_t *pdb, struct cil_sort *ioportcons) 2948 { 2949 int rc = SEPOL_ERR; 2950 uint32_t i = 0; 2951 ocontext_t *tail = NULL; 2952 2953 for (i = 0; i < ioportcons->count; i++) { 2954 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOPORT], &tail); 2955 struct cil_ioportcon *cil_ioportcon = ioportcons->array[i]; 2956 2957 new_ocon->u.ioport.low_ioport = cil_ioportcon->ioport_low; 2958 new_ocon->u.ioport.high_ioport = cil_ioportcon->ioport_high; 2959 2960 rc = __cil_context_to_sepol_context(pdb, cil_ioportcon->context, &new_ocon->context[0]); 2961 if (rc != SEPOL_OK) { 2962 goto exit; 2963 } 2964 } 2965 2966 return SEPOL_OK; 2967 2968 exit: 2969 return rc; 2970 } 2971 2972 int cil_pcidevicecon_to_policydb(policydb_t *pdb, struct cil_sort *pcidevicecons) 2973 { 2974 int rc = SEPOL_ERR; 2975 uint32_t i = 0; 2976 ocontext_t *tail = NULL; 2977 2978 for (i = 0; i < pcidevicecons->count; i++) { 2979 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PCIDEVICE], &tail); 2980 struct cil_pcidevicecon *cil_pcidevicecon = pcidevicecons->array[i]; 2981 2982 new_ocon->u.device = cil_pcidevicecon->dev; 2983 2984 rc = __cil_context_to_sepol_context(pdb, cil_pcidevicecon->context, &new_ocon->context[0]); 2985 if (rc != SEPOL_OK) { 2986 goto exit; 2987 } 2988 } 2989 2990 return SEPOL_OK; 2991 2992 exit: 2993 return rc; 2994 } 2995 2996 int cil_devicetreecon_to_policydb(policydb_t *pdb, struct cil_sort *devicetreecons) 2997 { 2998 int rc = SEPOL_ERR; 2999 uint32_t i = 0; 3000 ocontext_t *tail = NULL; 3001 3002 for (i = 0; i < devicetreecons->count; i++) { 3003 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_DEVICETREE], &tail); 3004 struct cil_devicetreecon *cil_devicetreecon = devicetreecons->array[i]; 3005 3006 new_ocon->u.name = cil_strdup(cil_devicetreecon->path); 3007 3008 rc = __cil_context_to_sepol_context(pdb, cil_devicetreecon->context, &new_ocon->context[0]); 3009 if (rc != SEPOL_OK) { 3010 goto exit; 3011 } 3012 } 3013 3014 return SEPOL_OK; 3015 3016 exit: 3017 return rc; 3018 } 3019 3020 int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def) 3021 { 3022 struct cil_list_item *curr; 3023 class_datum_t *sepol_class; 3024 struct cil_list *class_list; 3025 3026 cil_list_for_each(curr, def->class_datums) { 3027 struct cil_list_item *c; 3028 3029 class_list = cil_expand_class(curr->data); 3030 3031 cil_list_for_each(c, class_list) { 3032 int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); 3033 if (rc != SEPOL_OK) goto exit; 3034 3035 switch (def->flavor) { 3036 case CIL_DEFAULTUSER: 3037 if (!sepol_class->default_user) { 3038 sepol_class->default_user = def->object; 3039 } else if (sepol_class->default_user != (char)def->object) { 3040 cil_log(CIL_ERR,"User default labeling for class %s already specified\n",DATUM(c->data)->fqn); 3041 goto exit; 3042 } 3043 break; 3044 case CIL_DEFAULTROLE: 3045 if (!sepol_class->default_role) { 3046 sepol_class->default_role = def->object; 3047 } else if (sepol_class->default_role != (char)def->object) { 3048 cil_log(CIL_ERR,"Role default labeling for class %s already specified\n",DATUM(c->data)->fqn); 3049 goto exit; 3050 } 3051 break; 3052 case CIL_DEFAULTTYPE: 3053 if (!sepol_class->default_type) { 3054 sepol_class->default_type = def->object; 3055 } else if (sepol_class->default_type != (char)def->object) { 3056 cil_log(CIL_ERR,"Type default labeling for class %s already specified\n",DATUM(c->data)->fqn); 3057 goto exit; 3058 } 3059 break; 3060 default: 3061 goto exit; 3062 } 3063 } 3064 3065 cil_list_destroy(&class_list, CIL_FALSE); 3066 } 3067 3068 return SEPOL_OK; 3069 3070 exit: 3071 cil_list_destroy(&class_list, CIL_FALSE); 3072 return SEPOL_ERR; 3073 } 3074 3075 int cil_defaultrange_to_policydb(policydb_t *pdb, struct cil_defaultrange *def) 3076 { 3077 struct cil_list_item *curr; 3078 class_datum_t *sepol_class; 3079 struct cil_list *class_list; 3080 3081 cil_list_for_each(curr, def->class_datums) { 3082 struct cil_list_item *c; 3083 3084 class_list = cil_expand_class(curr->data); 3085 3086 cil_list_for_each(c, class_list) { 3087 int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); 3088 if (rc != SEPOL_OK) goto exit; 3089 3090 if (!sepol_class->default_range) { 3091 sepol_class->default_range = def->object_range; 3092 } else if (sepol_class->default_range != (char)def->object_range) { 3093 cil_log(CIL_ERR,"Range default labeling for class %s already specified\n", DATUM(curr->data)->fqn); 3094 goto exit; 3095 } 3096 } 3097 3098 cil_list_destroy(&class_list, CIL_FALSE); 3099 } 3100 3101 return SEPOL_OK; 3102 3103 exit: 3104 cil_list_destroy(&class_list, CIL_FALSE); 3105 return SEPOL_ERR; 3106 } 3107 3108 int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args) 3109 { 3110 int rc = SEPOL_OK; 3111 int pass; 3112 struct cil_args_binary *args = extra_args; 3113 const struct cil_db *db; 3114 policydb_t *pdb; 3115 hashtab_t filename_trans_table; 3116 hashtab_t range_trans_table; 3117 hashtab_t role_trans_table; 3118 db = args->db; 3119 pdb = args->pdb; 3120 pass = args->pass; 3121 filename_trans_table = args->filename_trans_table; 3122 range_trans_table = args->range_trans_table; 3123 role_trans_table = args->role_trans_table; 3124 3125 if (node->flavor >= CIL_MIN_DECLARATIVE) { 3126 if (node != DATUM(node->data)->nodes->head->data) { 3127 goto exit; 3128 } 3129 } 3130 3131 switch (pass) { 3132 case 1: 3133 switch (node->flavor) { 3134 case CIL_ROLE: 3135 rc = cil_role_to_policydb(pdb, node->data); 3136 break; 3137 case CIL_TYPE: 3138 rc = cil_type_to_policydb(pdb, node->data); 3139 break; 3140 case CIL_TYPEATTRIBUTE: 3141 rc = cil_typeattribute_to_policydb(pdb, node->data); 3142 break; 3143 case CIL_POLICYCAP: 3144 rc = cil_policycap_to_policydb(pdb, node->data); 3145 break; 3146 case CIL_USER: 3147 rc = cil_user_to_policydb(pdb, node->data); 3148 break; 3149 case CIL_BOOL: 3150 rc = cil_bool_to_policydb(pdb, node->data); 3151 break; 3152 case CIL_CATALIAS: 3153 if (pdb->mls == CIL_TRUE) { 3154 rc = cil_catalias_to_policydb(pdb, node->data); 3155 } 3156 break; 3157 case CIL_SENS: 3158 if (pdb->mls == CIL_TRUE) { 3159 rc = cil_sepol_level_define(pdb, node->data); 3160 } 3161 break; 3162 default: 3163 break; 3164 } 3165 break; 3166 case 2: 3167 switch (node->flavor) { 3168 case CIL_TYPE: 3169 rc = cil_type_bounds_to_policydb(pdb, node->data); 3170 break; 3171 case CIL_TYPEALIAS: 3172 rc = cil_typealias_to_policydb(pdb, node->data); 3173 break; 3174 case CIL_TYPEPERMISSIVE: 3175 rc = cil_typepermissive_to_policydb(pdb, node->data); 3176 break; 3177 case CIL_TYPEATTRIBUTE: 3178 rc = cil_typeattribute_to_bitmap(pdb, db, node->data); 3179 break; 3180 case CIL_SENSALIAS: 3181 if (pdb->mls == CIL_TRUE) { 3182 rc = cil_sensalias_to_policydb(pdb, node->data); 3183 } 3184 break; 3185 case CIL_ROLE: 3186 rc = cil_role_bounds_to_policydb(pdb, node->data); 3187 if (rc != SEPOL_OK) goto exit; 3188 rc = cil_roletype_to_policydb(pdb, db, node->data); 3189 break; 3190 case CIL_USER: 3191 rc = cil_user_bounds_to_policydb(pdb, node->data); 3192 if (rc != SEPOL_OK) goto exit; 3193 if (pdb->mls == CIL_TRUE) { 3194 rc = cil_userlevel_userrange_to_policydb(pdb, node->data); 3195 } 3196 break; 3197 case CIL_USERROLE: 3198 rc = cil_userrole_to_policydb(pdb, db, node->data); 3199 break; 3200 case CIL_TYPE_RULE: 3201 rc = cil_type_rule_to_policydb(pdb, db, node->data); 3202 break; 3203 case CIL_AVRULE: { 3204 struct cil_avrule *rule = node->data; 3205 struct cil_list *neverallows = args->neverallows; 3206 if (rule->rule_kind == CIL_AVRULE_NEVERALLOW) { 3207 struct cil_neverallow *new_rule = NULL; 3208 3209 new_rule = cil_malloc(sizeof(*new_rule)); 3210 cil_list_init(&new_rule->rules, CIL_LIST_ITEM); 3211 new_rule->node = node; 3212 3213 cil_list_prepend(neverallows, CIL_LIST_ITEM, new_rule); 3214 3215 rc = cil_avrule_to_policydb(pdb, db, node->data, neverallows); 3216 } 3217 break; 3218 } 3219 case CIL_ROLETRANSITION: 3220 rc = cil_roletrans_to_policydb(pdb, db, node->data, role_trans_table); 3221 break; 3222 case CIL_ROLEATTRIBUTESET: 3223 /*rc = cil_roleattributeset_to_policydb(pdb, node->data);*/ 3224 break; 3225 case CIL_NAMETYPETRANSITION: 3226 rc = cil_typetransition_to_policydb(pdb, db, node->data, filename_trans_table); 3227 break; 3228 case CIL_CONSTRAIN: 3229 rc = cil_constrain_to_policydb(pdb, db, node->data); 3230 break; 3231 case CIL_MLSCONSTRAIN: 3232 if (pdb->mls == CIL_TRUE) { 3233 rc = cil_constrain_to_policydb(pdb, db, node->data); 3234 } 3235 break; 3236 case CIL_VALIDATETRANS: 3237 rc = cil_validatetrans_to_policydb(pdb, db, node->data); 3238 break; 3239 case CIL_MLSVALIDATETRANS: 3240 if (pdb->mls == CIL_TRUE) { 3241 rc = cil_validatetrans_to_policydb(pdb, db, node->data); 3242 } 3243 break; 3244 case CIL_RANGETRANSITION: 3245 if (pdb->mls == CIL_TRUE) { 3246 rc = cil_rangetransition_to_policydb(pdb, db, node->data, range_trans_table); 3247 } 3248 break; 3249 case CIL_DEFAULTUSER: 3250 case CIL_DEFAULTROLE: 3251 case CIL_DEFAULTTYPE: 3252 rc = cil_default_to_policydb(pdb, node->data); 3253 break; 3254 case CIL_DEFAULTRANGE: 3255 rc = cil_defaultrange_to_policydb(pdb, node->data); 3256 break; 3257 default: 3258 break; 3259 } 3260 break; 3261 case 3: 3262 switch (node->flavor) { 3263 case CIL_BOOLEANIF: 3264 rc = cil_booleanif_to_policydb(pdb, db, node, args->neverallows, filename_trans_table); 3265 break; 3266 case CIL_AVRULE: { 3267 struct cil_avrule *rule = node->data; 3268 if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) { 3269 rc = cil_avrule_to_policydb(pdb, db, node->data, args->neverallows); 3270 } 3271 } 3272 break; 3273 case CIL_ROLEALLOW: 3274 rc = cil_roleallow_to_policydb(pdb, db, node->data); 3275 break; 3276 default: 3277 break; 3278 } 3279 default: 3280 break; 3281 } 3282 3283 exit: 3284 if (rc != SEPOL_OK) { 3285 cil_log(CIL_ERR, "Binary policy creation failed at line %d of %s\n", node->line, node->path); 3286 } 3287 return rc; 3288 } 3289 3290 int __cil_binary_create_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args) 3291 { 3292 int rc = SEPOL_ERR; 3293 3294 if (node->flavor == CIL_BLOCK) { 3295 struct cil_block *blk = node->data; 3296 if (blk->is_abstract == CIL_TRUE) { 3297 *finished = CIL_TREE_SKIP_HEAD; 3298 rc = SEPOL_OK; 3299 goto exit; 3300 } 3301 } else if (node->flavor == CIL_MACRO) { 3302 *finished = CIL_TREE_SKIP_HEAD; 3303 rc = SEPOL_OK; 3304 goto exit; 3305 } else if (node->flavor == CIL_BOOLEANIF) { 3306 *finished = CIL_TREE_SKIP_HEAD; 3307 } 3308 3309 rc = __cil_node_to_policydb(node, extra_args); 3310 if (rc != SEPOL_OK) { 3311 goto exit; 3312 } 3313 3314 exit: 3315 return rc; 3316 } 3317 3318 int __cil_contexts_to_policydb(policydb_t *pdb, const struct cil_db *db) 3319 { 3320 int rc = SEPOL_ERR; 3321 3322 rc = cil_portcon_to_policydb(pdb, db->portcon); 3323 if (rc != SEPOL_OK) { 3324 goto exit; 3325 } 3326 3327 rc = cil_netifcon_to_policydb(pdb, db->netifcon); 3328 if (rc != SEPOL_OK) { 3329 goto exit; 3330 } 3331 3332 rc = cil_nodecon_to_policydb(pdb, db->nodecon); 3333 if (rc != SEPOL_OK) { 3334 goto exit; 3335 } 3336 3337 rc = cil_fsuse_to_policydb(pdb, db->fsuse); 3338 if (rc != SEPOL_OK) { 3339 goto exit; 3340 } 3341 3342 rc = cil_genfscon_to_policydb(pdb, db->genfscon); 3343 if (rc != SEPOL_OK) { 3344 goto exit; 3345 } 3346 3347 if (db->target_platform == SEPOL_TARGET_XEN) { 3348 rc = cil_pirqcon_to_policydb(pdb, db->pirqcon); 3349 if (rc != SEPOL_OK) { 3350 goto exit; 3351 } 3352 3353 rc = cil_iomemcon_to_policydb(pdb, db->iomemcon); 3354 if (rc != SEPOL_OK) { 3355 goto exit; 3356 } 3357 3358 rc = cil_ioportcon_to_policydb(pdb, db->ioportcon); 3359 if (rc != SEPOL_OK) { 3360 goto exit; 3361 } 3362 3363 rc = cil_pcidevicecon_to_policydb(pdb, db->pcidevicecon); 3364 if (rc != SEPOL_OK) { 3365 goto exit; 3366 } 3367 3368 rc = cil_devicetreecon_to_policydb(pdb, db->devicetreecon); 3369 if (rc != SEPOL_OK) { 3370 goto exit; 3371 } 3372 } 3373 return SEPOL_OK; 3374 exit: 3375 return rc; 3376 } 3377 3378 int __cil_common_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3379 { 3380 policydb_t *pdb = data; 3381 common_datum_t *common = (common_datum_t *)datum; 3382 3383 if (common->s.value < 1 || common->s.value > pdb->p_commons.nprim) { 3384 return -EINVAL; 3385 } 3386 pdb->p_common_val_to_name[common->s.value - 1] = (char *)key; 3387 3388 return 0; 3389 } 3390 3391 int __cil_class_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3392 { 3393 policydb_t *pdb = data; 3394 class_datum_t *class = (class_datum_t *)datum; 3395 3396 if (class->s.value < 1 || class->s.value > pdb->p_classes.nprim) { 3397 return -EINVAL; 3398 } 3399 pdb->p_class_val_to_name[class->s.value - 1] = (char *)key; 3400 pdb->class_val_to_struct[class->s.value - 1] = class; 3401 3402 return 0; 3403 } 3404 3405 int __cil_role_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3406 { 3407 policydb_t *pdb = data; 3408 role_datum_t *role = (role_datum_t *)datum; 3409 3410 if (role->s.value < 1 || role->s.value > pdb->p_roles.nprim) { 3411 return -EINVAL; 3412 } 3413 pdb->p_role_val_to_name[role->s.value - 1] = (char *)key; 3414 pdb->role_val_to_struct[role->s.value - 1] = role; 3415 3416 return 0; 3417 } 3418 3419 int __cil_type_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3420 { 3421 policydb_t *pdb = data; 3422 type_datum_t *type = (type_datum_t *)datum; 3423 3424 if (type->s.value < 1 || type->s.value > pdb->p_types.nprim) { 3425 return -EINVAL; 3426 } 3427 pdb->p_type_val_to_name[type->s.value - 1] = (char *)key; 3428 pdb->type_val_to_struct[type->s.value - 1] = type; 3429 3430 return 0; 3431 } 3432 3433 int __cil_user_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3434 { 3435 policydb_t *pdb = data; 3436 user_datum_t *user = (user_datum_t *)datum; 3437 3438 if (user->s.value < 1 || user->s.value > pdb->p_users.nprim) { 3439 return -EINVAL; 3440 } 3441 pdb->p_user_val_to_name[user->s.value - 1] = (char *)key; 3442 pdb->user_val_to_struct[user->s.value - 1] = user; 3443 3444 return 0; 3445 } 3446 3447 int __cil_bool_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3448 { 3449 policydb_t *pdb = data; 3450 cond_bool_datum_t *bool = (cond_bool_datum_t *)datum; 3451 3452 if (bool->s.value < 1 || bool->s.value > pdb->p_bools.nprim) { 3453 return -EINVAL; 3454 } 3455 pdb->p_bool_val_to_name[bool->s.value - 1] = (char *)key; 3456 pdb->bool_val_to_struct[bool->s.value - 1] = bool; 3457 3458 return 0; 3459 } 3460 3461 int __cil_level_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3462 { 3463 policydb_t *pdb = data; 3464 level_datum_t *level = (level_datum_t *)datum; 3465 3466 if (level->level->sens < 1 || level->level->sens > pdb->p_levels.nprim) { 3467 return -EINVAL; 3468 } 3469 pdb->p_sens_val_to_name[level->level->sens - 1] = (char *)key; 3470 3471 return 0; 3472 } 3473 3474 int __cil_cat_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3475 { 3476 policydb_t *pdb = data; 3477 cat_datum_t *cat = (cat_datum_t *)datum; 3478 3479 if (cat->s.value < 1 || cat->s.value > pdb->p_cats.nprim) { 3480 return -EINVAL; 3481 } 3482 pdb->p_cat_val_to_name[cat->s.value - 1] = (char *)key; 3483 3484 return 0; 3485 } 3486 3487 int __cil_policydb_val_arrays_create(policydb_t *policydb) 3488 { 3489 int rc = SEPOL_ERR; 3490 3491 policydb->p_common_val_to_name = cil_malloc(sizeof(char *) * policydb->p_commons.nprim); 3492 rc = hashtab_map(policydb->p_commons.table, &__cil_common_val_array_insert, policydb); 3493 if (rc != SEPOL_OK) { 3494 goto exit; 3495 } 3496 3497 policydb->p_class_val_to_name = cil_malloc(sizeof(char *) * policydb->p_classes.nprim); 3498 policydb->class_val_to_struct = cil_malloc(sizeof(class_datum_t *) * policydb->p_classes.nprim); 3499 rc = hashtab_map(policydb->p_classes.table, &__cil_class_val_array_insert, policydb); 3500 if (rc != SEPOL_OK) { 3501 goto exit; 3502 } 3503 3504 policydb->p_role_val_to_name = cil_malloc(sizeof(char *) * policydb->p_roles.nprim); 3505 policydb->role_val_to_struct = cil_malloc(sizeof(role_datum_t *) * policydb->p_roles.nprim); 3506 rc = hashtab_map(policydb->p_roles.table, &__cil_role_val_array_insert, policydb); 3507 if (rc != SEPOL_OK) { 3508 goto exit; 3509 } 3510 3511 policydb->p_type_val_to_name = cil_malloc(sizeof(char *) * policydb->p_types.nprim); 3512 policydb->type_val_to_struct = cil_malloc(sizeof(type_datum_t *) * policydb->p_types.nprim); 3513 rc = hashtab_map(policydb->p_types.table, &__cil_type_val_array_insert, policydb); 3514 if (rc != SEPOL_OK) { 3515 goto exit; 3516 } 3517 3518 policydb->p_user_val_to_name = cil_malloc(sizeof(char *) * policydb->p_users.nprim); 3519 policydb->user_val_to_struct = cil_malloc(sizeof(user_datum_t *) * policydb->p_users.nprim); 3520 rc = hashtab_map(policydb->p_users.table, &__cil_user_val_array_insert, policydb); 3521 if (rc != SEPOL_OK) { 3522 goto exit; 3523 } 3524 3525 policydb->p_bool_val_to_name = cil_malloc(sizeof(char *) * policydb->p_bools.nprim); 3526 policydb->bool_val_to_struct = cil_malloc(sizeof(cond_bool_datum_t *) * policydb->p_bools.nprim); 3527 rc = hashtab_map(policydb->p_bools.table, &__cil_bool_val_array_insert, policydb); 3528 if (rc != SEPOL_OK) { 3529 goto exit; 3530 } 3531 3532 policydb->p_sens_val_to_name = cil_malloc(sizeof(char *) * policydb->p_levels.nprim); 3533 rc = hashtab_map(policydb->p_levels.table, &__cil_level_val_array_insert, policydb); 3534 if (rc != SEPOL_OK) { 3535 goto exit; 3536 } 3537 3538 policydb->p_cat_val_to_name = cil_malloc(sizeof(char *) * policydb->p_cats.nprim); 3539 rc = hashtab_map(policydb->p_cats.table, &__cil_cat_val_array_insert, policydb); 3540 if (rc != SEPOL_OK) { 3541 goto exit; 3542 } 3543 3544 exit: 3545 return rc; 3546 } 3547 3548 static void __cil_set_conditional_state_and_flags(policydb_t *pdb) 3549 { 3550 cond_node_t *cur; 3551 3552 for (cur = pdb->cond_list; cur != NULL; cur = cur->next) { 3553 int new_state; 3554 cond_av_list_t *c; 3555 3556 new_state = cond_evaluate_expr(pdb, cur->expr); 3557 3558 cur->cur_state = new_state; 3559 3560 if (new_state == -1) { 3561 cil_log(CIL_WARN, "Expression result was undefined - disabling all rules\n"); 3562 } 3563 3564 for (c = cur->true_list; c != NULL; c = c->next) { 3565 if (new_state <= 0) { 3566 c->node->key.specified &= ~AVTAB_ENABLED; 3567 } else { 3568 c->node->key.specified |= AVTAB_ENABLED; 3569 } 3570 } 3571 3572 for (c = cur->false_list; c != NULL; c = c->next) { 3573 if (new_state) { /* -1 or 1 */ 3574 c->node->key.specified &= ~AVTAB_ENABLED; 3575 } else { 3576 c->node->key.specified |= AVTAB_ENABLED; 3577 } 3578 } 3579 } 3580 } 3581 3582 int __cil_policydb_create(const struct cil_db *db, struct sepol_policydb **spdb) 3583 { 3584 int rc; 3585 struct policydb *pdb = NULL; 3586 3587 rc = sepol_policydb_create(spdb); 3588 if (rc < 0) { 3589 cil_log(CIL_ERR, "Failed to create policy db\n"); 3590 // spdb could be a dangling pointer at this point, so reset it so 3591 // callers of this function don't need to worry about freeing garbage 3592 *spdb = NULL; 3593 goto exit; 3594 } 3595 3596 pdb = &(*spdb)->p; 3597 3598 pdb->policy_type = POLICY_KERN; 3599 pdb->target_platform = db->target_platform; 3600 pdb->policyvers = db->policy_version; 3601 pdb->handle_unknown = db->handle_unknown; 3602 pdb->mls = db->mls; 3603 3604 return SEPOL_OK; 3605 3606 exit: 3607 return rc; 3608 } 3609 3610 3611 int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db) 3612 { 3613 int rc = SEPOL_ERR; 3614 3615 // these flags should get set in __cil_policydb_create. However, for 3616 // backwards compatability, it is possible that __cil_policydb_create is 3617 // never called. So, they must also be set here. 3618 pdb->handle_unknown = db->handle_unknown; 3619 pdb->mls = db->mls; 3620 3621 rc = cil_classorder_to_policydb(pdb, db); 3622 if (rc != SEPOL_OK) { 3623 goto exit; 3624 } 3625 3626 if (pdb->mls == CIL_TRUE) { 3627 rc = cil_catorder_to_policydb(pdb, db); 3628 if (rc != SEPOL_OK) { 3629 goto exit; 3630 } 3631 3632 rc = cil_sensitivityorder_to_policydb(pdb, db); 3633 if (rc != SEPOL_OK) { 3634 goto exit; 3635 } 3636 } 3637 3638 rc = avtab_alloc(&pdb->te_avtab, MAX_AVTAB_SIZE); 3639 if (rc != SEPOL_OK) { 3640 goto exit; 3641 } 3642 3643 rc = avtab_alloc(&pdb->te_cond_avtab, MAX_AVTAB_SIZE); 3644 if (rc != SEPOL_OK) { 3645 goto exit; 3646 } 3647 3648 return SEPOL_OK; 3649 3650 exit: 3651 3652 return rc; 3653 } 3654 3655 static unsigned int filename_trans_hash(hashtab_t h, hashtab_key_t key) 3656 { 3657 filename_trans_t *k = (filename_trans_t *)key; 3658 return ((k->tclass + (k->ttype << 2) + 3659 (k->stype << 9)) & (h->size - 1)); 3660 } 3661 3662 static int filename_trans_compare(hashtab_t h 3663 __attribute__ ((unused)), hashtab_key_t key1, 3664 hashtab_key_t key2) 3665 { 3666 filename_trans_t *a = (filename_trans_t *)key1; 3667 filename_trans_t *b = (filename_trans_t *)key2; 3668 3669 return a->stype != b->stype || a->ttype != b->ttype || a->tclass != b->tclass || strcmp(a->name, b->name); 3670 } 3671 3672 static unsigned int range_trans_hash(hashtab_t h, hashtab_key_t key) 3673 { 3674 range_trans_t *k = (range_trans_t *)key; 3675 return ((k->target_class + (k->target_type << 2) + 3676 (k->source_type << 5)) & (h->size - 1)); 3677 } 3678 3679 static int range_trans_compare(hashtab_t h 3680 __attribute__ ((unused)), hashtab_key_t key1, 3681 hashtab_key_t key2) 3682 { 3683 range_trans_t *a = (range_trans_t *)key1; 3684 range_trans_t *b = (range_trans_t *)key2; 3685 3686 return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class; 3687 } 3688 3689 static unsigned int role_trans_hash(hashtab_t h, hashtab_key_t key) 3690 { 3691 role_trans_t *k = (role_trans_t *)key; 3692 return ((k->role + (k->type << 2) + 3693 (k->tclass << 5)) & (h->size - 1)); 3694 } 3695 3696 static int role_trans_compare(hashtab_t h 3697 __attribute__ ((unused)), hashtab_key_t key1, 3698 hashtab_key_t key2) 3699 { 3700 role_trans_t *a = (role_trans_t *)key1; 3701 role_trans_t *b = (role_trans_t *)key2; 3702 3703 return a->role != b->role || a->type != b->type || a->tclass != b->tclass; 3704 } 3705 3706 int cil_binary_create(const struct cil_db *db, sepol_policydb_t **policydb) 3707 { 3708 int rc = SEPOL_ERR; 3709 struct sepol_policydb *pdb = NULL; 3710 3711 rc = __cil_policydb_create(db, &pdb); 3712 if (rc != SEPOL_OK) { 3713 goto exit; 3714 } 3715 3716 rc = cil_binary_create_allocated_pdb(db, pdb); 3717 if (rc != SEPOL_OK) { 3718 goto exit; 3719 } 3720 3721 *policydb = pdb; 3722 3723 return SEPOL_OK; 3724 3725 exit: 3726 sepol_policydb_free(pdb); 3727 3728 return rc; 3729 } 3730 3731 // assumes policydb is already allocated and initialized properly with things 3732 // like policy type set to kernel and version set appropriately 3733 int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *policydb) 3734 { 3735 int rc = SEPOL_ERR; 3736 int i; 3737 struct cil_args_binary extra_args; 3738 policydb_t *pdb = &policydb->p; 3739 struct cil_list *neverallows = NULL; 3740 hashtab_t filename_trans_table = NULL; 3741 hashtab_t range_trans_table = NULL; 3742 hashtab_t role_trans_table = NULL; 3743 3744 if (db == NULL || policydb == NULL) { 3745 if (db == NULL) { 3746 cil_log(CIL_ERR,"db == NULL\n"); 3747 } else if (policydb == NULL) { 3748 cil_log(CIL_ERR,"policydb == NULL\n"); 3749 } 3750 return SEPOL_ERR; 3751 } 3752 3753 rc = __cil_policydb_init(pdb, db); 3754 if (rc != SEPOL_OK) { 3755 cil_log(CIL_ERR,"Problem in policydb_init\n"); 3756 goto exit; 3757 } 3758 3759 filename_trans_table = hashtab_create(filename_trans_hash, filename_trans_compare, FILENAME_TRANS_TABLE_SIZE); 3760 if (!filename_trans_table) { 3761 cil_log(CIL_INFO, "Failure to create hashtab for filename_trans\n"); 3762 goto exit; 3763 } 3764 3765 range_trans_table = hashtab_create(range_trans_hash, range_trans_compare, RANGE_TRANS_TABLE_SIZE); 3766 if (!range_trans_table) { 3767 cil_log(CIL_INFO, "Failure to create hashtab for range_trans\n"); 3768 goto exit; 3769 } 3770 3771 role_trans_table = hashtab_create(role_trans_hash, role_trans_compare, ROLE_TRANS_TABLE_SIZE); 3772 if (!role_trans_table) { 3773 cil_log(CIL_INFO, "Failure to create hashtab for role_trans\n"); 3774 goto exit; 3775 } 3776 3777 cil_list_init(&neverallows, CIL_LIST_ITEM); 3778 3779 extra_args.db = db; 3780 extra_args.pdb = pdb; 3781 extra_args.neverallows = neverallows; 3782 extra_args.filename_trans_table = filename_trans_table; 3783 extra_args.range_trans_table = range_trans_table; 3784 extra_args.role_trans_table = role_trans_table; 3785 for (i = 1; i <= 3; i++) { 3786 extra_args.pass = i; 3787 3788 rc = cil_tree_walk(db->ast->root, __cil_binary_create_helper, NULL, NULL, &extra_args); 3789 if (rc != SEPOL_OK) { 3790 cil_log(CIL_INFO, "Failure while walking cil database\n"); 3791 goto exit; 3792 } 3793 3794 if (i == 1) { 3795 rc = __cil_policydb_val_arrays_create(pdb); 3796 if (rc != SEPOL_OK) { 3797 cil_log(CIL_INFO, "Failure creating val_to_{struct,name} arrays\n"); 3798 goto exit; 3799 } 3800 } 3801 } 3802 3803 rc = cil_sidorder_to_policydb(pdb, db); 3804 if (rc != SEPOL_OK) { 3805 goto exit; 3806 } 3807 3808 rc = __cil_contexts_to_policydb(pdb, db); 3809 if (rc != SEPOL_OK) { 3810 cil_log(CIL_INFO, "Failure while inserting cil contexts into sepol policydb\n"); 3811 goto exit; 3812 } 3813 3814 if (pdb->type_attr_map == NULL) { 3815 rc = __cil_typeattr_bitmap_init(pdb); 3816 if (rc != SEPOL_OK) { 3817 cil_log(CIL_INFO, "Failure while initializing typeattribute bitmap\n"); 3818 goto exit; 3819 } 3820 } 3821 3822 cond_optimize_lists(pdb->cond_list); 3823 __cil_set_conditional_state_and_flags(pdb); 3824 3825 rc = SEPOL_OK; 3826 3827 exit: 3828 hashtab_destroy(filename_trans_table); 3829 hashtab_destroy(range_trans_table); 3830 hashtab_destroy(role_trans_table); 3831 cil_neverallows_list_destroy(neverallows); 3832 3833 return rc; 3834 } 3835