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 #ifndef IPPROTO_DCCP 35 #define IPPROTO_DCCP 33 36 #endif 37 38 #include <sepol/policydb/policydb.h> 39 #include <sepol/policydb/polcaps.h> 40 #include <sepol/policydb/conditional.h> 41 #include <sepol/policydb/constraint.h> 42 #include <sepol/policydb/flask.h> 43 #include <sepol/policydb/expand.h> 44 #include <sepol/policydb/hierarchy.h> 45 46 #include "cil_internal.h" 47 #include "cil_flavor.h" 48 #include "cil_log.h" 49 #include "cil_mem.h" 50 #include "cil_tree.h" 51 #include "cil_binary.h" 52 #include "cil_symtab.h" 53 #include "cil_find.h" 54 55 /* There are 44000 filename_trans in current fedora policy. 1.33 times this is the recommended 56 * size of a hashtable. The next power of 2 of this is 2 ** 16. 57 */ 58 #define FILENAME_TRANS_TABLE_SIZE (1 << 16) 59 #define RANGE_TRANS_TABLE_SIZE (1 << 13) 60 #define ROLE_TRANS_TABLE_SIZE (1 << 10) 61 #define AVRULEX_TABLE_SIZE (1 << 10) 62 #define PERMS_PER_CLASS 32 63 64 struct cil_args_binary { 65 const struct cil_db *db; 66 policydb_t *pdb; 67 struct cil_list *neverallows; 68 int pass; 69 hashtab_t filename_trans_table; 70 hashtab_t range_trans_table; 71 hashtab_t role_trans_table; 72 hashtab_t avrulex_ioctl_table; 73 void **type_value_to_cil; 74 }; 75 76 struct cil_args_booleanif { 77 const struct cil_db *db; 78 policydb_t *pdb; 79 cond_node_t *cond_node; 80 enum cil_flavor cond_flavor; 81 hashtab_t filename_trans_table; 82 }; 83 84 static int __cil_get_sepol_user_datum(policydb_t *pdb, struct cil_symtab_datum *datum, user_datum_t **sepol_user) 85 { 86 *sepol_user = hashtab_search(pdb->p_users.table, datum->fqn); 87 if (*sepol_user == NULL) { 88 cil_log(CIL_INFO, "Failed to find user %s in sepol hashtab\n", datum->fqn); 89 return SEPOL_ERR; 90 } 91 92 return SEPOL_OK; 93 } 94 95 static int __cil_get_sepol_role_datum(policydb_t *pdb, struct cil_symtab_datum *datum, role_datum_t **sepol_role) 96 { 97 *sepol_role = hashtab_search(pdb->p_roles.table, datum->fqn); 98 if (*sepol_role == NULL) { 99 cil_log(CIL_INFO, "Failed to find role %s in sepol hashtab\n", datum->fqn); 100 return SEPOL_ERR; 101 } 102 103 return SEPOL_OK; 104 } 105 106 static int __cil_get_sepol_type_datum(policydb_t *pdb, struct cil_symtab_datum *datum, type_datum_t **sepol_type) 107 { 108 *sepol_type = hashtab_search(pdb->p_types.table, datum->fqn); 109 if (*sepol_type == NULL) { 110 cil_log(CIL_INFO, "Failed to find type %s in sepol hashtab\n", datum->fqn); 111 return SEPOL_ERR; 112 } 113 114 return SEPOL_OK; 115 } 116 117 static int __cil_get_sepol_class_datum(policydb_t *pdb, struct cil_symtab_datum *datum, class_datum_t **sepol_class) 118 { 119 *sepol_class = hashtab_search(pdb->p_classes.table, datum->fqn); 120 if (*sepol_class == NULL) { 121 cil_log(CIL_INFO, "Failed to find class %s in sepol hashtab\n", datum->fqn); 122 return SEPOL_ERR; 123 } 124 125 return SEPOL_OK; 126 } 127 128 static int __cil_get_sepol_cat_datum(policydb_t *pdb, struct cil_symtab_datum *datum, cat_datum_t **sepol_cat) 129 { 130 *sepol_cat = hashtab_search(pdb->p_cats.table, datum->fqn); 131 if (*sepol_cat == NULL) { 132 cil_log(CIL_INFO, "Failed to find category %s in sepol hashtab\n", datum->fqn); 133 return SEPOL_ERR; 134 } 135 136 return SEPOL_OK; 137 } 138 139 static int __cil_get_sepol_level_datum(policydb_t *pdb, struct cil_symtab_datum *datum, level_datum_t **sepol_level) 140 { 141 *sepol_level = hashtab_search(pdb->p_levels.table, datum->fqn); 142 if (*sepol_level == NULL) { 143 cil_log(CIL_INFO, "Failed to find level %s in sepol hashtab\n", datum->fqn); 144 return SEPOL_ERR; 145 } 146 147 return SEPOL_OK; 148 } 149 150 static int __cil_expand_user(struct cil_symtab_datum *datum, ebitmap_t *new) 151 { 152 struct cil_tree_node *node = datum->nodes->head->data; 153 struct cil_user *user = NULL; 154 struct cil_userattribute *attr = NULL; 155 156 if (node->flavor == CIL_USERATTRIBUTE) { 157 attr = (struct cil_userattribute *)datum; 158 if (ebitmap_cpy(new, attr->users)) { 159 cil_log(CIL_ERR, "Failed to copy user bits\n"); 160 goto exit; 161 } 162 } else { 163 user = (struct cil_user *)datum; 164 ebitmap_init(new); 165 if (ebitmap_set_bit(new, user->value, 1)) { 166 cil_log(CIL_ERR, "Failed to set user bit\n"); 167 ebitmap_destroy(new); 168 goto exit; 169 } 170 } 171 172 return SEPOL_OK; 173 174 exit: 175 return SEPOL_ERR; 176 } 177 178 static int __cil_expand_role(struct cil_symtab_datum *datum, ebitmap_t *new) 179 { 180 struct cil_tree_node *node = datum->nodes->head->data; 181 182 if (node->flavor == CIL_ROLEATTRIBUTE) { 183 struct cil_roleattribute *attr = (struct cil_roleattribute *)datum; 184 if (ebitmap_cpy(new, attr->roles)) { 185 cil_log(CIL_ERR, "Failed to copy role bits\n"); 186 goto exit; 187 } 188 } else { 189 struct cil_role *role = (struct cil_role *)datum; 190 ebitmap_init(new); 191 if (ebitmap_set_bit(new, role->value, 1)) { 192 cil_log(CIL_ERR, "Failed to set role bit\n"); 193 ebitmap_destroy(new); 194 goto exit; 195 } 196 } 197 198 return SEPOL_OK; 199 200 exit: 201 return SEPOL_ERR; 202 } 203 204 static int __cil_expand_type(struct cil_symtab_datum *datum, ebitmap_t *new) 205 { 206 struct cil_tree_node *node = datum->nodes->head->data; 207 208 if (node->flavor == CIL_TYPEATTRIBUTE) { 209 struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; 210 if (ebitmap_cpy(new, attr->types)) { 211 cil_log(CIL_ERR, "Failed to copy type bits\n"); 212 goto exit; 213 } 214 } else { 215 struct cil_type *type = (struct cil_type *)datum; 216 ebitmap_init(new); 217 if (ebitmap_set_bit(new, type->value, 1)) { 218 cil_log(CIL_ERR, "Failed to set type bit\n"); 219 ebitmap_destroy(new); 220 goto exit; 221 } 222 } 223 224 return SEPOL_OK; 225 226 exit: 227 return SEPOL_ERR; 228 } 229 230 static ocontext_t *cil_add_ocontext(ocontext_t **head, ocontext_t **tail) 231 { 232 ocontext_t *new = cil_malloc(sizeof(ocontext_t)); 233 memset(new, 0, sizeof(ocontext_t)); 234 if (*tail) { 235 (*tail)->next = new; 236 } else { 237 *head = new; 238 } 239 *tail = new; 240 241 return new; 242 } 243 244 int cil_common_to_policydb(policydb_t *pdb, struct cil_class *cil_common, common_datum_t **common_out) 245 { 246 int rc = SEPOL_ERR; 247 uint32_t value = 0; 248 char *key = NULL; 249 struct cil_tree_node *node = cil_common->datum.nodes->head->data; 250 struct cil_tree_node *cil_perm = node->cl_head; 251 common_datum_t *sepol_common = cil_malloc(sizeof(*sepol_common)); 252 memset(sepol_common, 0, sizeof(common_datum_t)); 253 254 key = cil_strdup(cil_common->datum.fqn); 255 rc = symtab_insert(pdb, SYM_COMMONS, key, sepol_common, SCOPE_DECL, 0, &value); 256 if (rc != SEPOL_OK) { 257 free(sepol_common); 258 goto exit; 259 } 260 sepol_common->s.value = value; 261 262 rc = symtab_init(&sepol_common->permissions, PERM_SYMTAB_SIZE); 263 if (rc != SEPOL_OK) { 264 goto exit; 265 } 266 267 while (cil_perm != NULL) { 268 struct cil_perm *curr = cil_perm->data; 269 perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm)); 270 memset(sepol_perm, 0, sizeof(perm_datum_t)); 271 272 key = cil_strdup(curr->datum.fqn); 273 rc = hashtab_insert(sepol_common->permissions.table, key, sepol_perm); 274 if (rc != SEPOL_OK) { 275 free(sepol_perm); 276 goto exit; 277 } 278 sepol_perm->s.value = sepol_common->permissions.nprim + 1; 279 sepol_common->permissions.nprim++; 280 cil_perm = cil_perm->next; 281 } 282 283 *common_out = sepol_common; 284 285 return SEPOL_OK; 286 287 exit: 288 free(key); 289 return rc; 290 } 291 292 int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) 293 { 294 int rc = SEPOL_ERR; 295 struct cil_list_item *curr_class; 296 297 cil_list_for_each(curr_class, db->classorder) { 298 struct cil_class *cil_class = curr_class->data; 299 uint32_t value = 0; 300 char *key = NULL; 301 int class_index; 302 struct cil_tree_node *curr; 303 common_datum_t *sepol_common = NULL; 304 class_datum_t *sepol_class = cil_malloc(sizeof(*sepol_class)); 305 memset(sepol_class, 0, sizeof(class_datum_t)); 306 307 key = cil_strdup(cil_class->datum.fqn); 308 rc = symtab_insert(pdb, SYM_CLASSES, key, sepol_class, SCOPE_DECL, 0, &value); 309 if (rc != SEPOL_OK) { 310 free(sepol_class); 311 free(key); 312 goto exit; 313 } 314 sepol_class->s.value = value; 315 class_index = value; 316 class_value_to_cil[class_index] = cil_class; 317 318 rc = symtab_init(&sepol_class->permissions, PERM_SYMTAB_SIZE); 319 if (rc != SEPOL_OK) { 320 goto exit; 321 } 322 323 if (cil_class->common != NULL) { 324 int i; 325 struct cil_class *cil_common = cil_class->common; 326 327 key = cil_class->common->datum.fqn; 328 sepol_common = hashtab_search(pdb->p_commons.table, key); 329 if (sepol_common == NULL) { 330 rc = cil_common_to_policydb(pdb, cil_common, &sepol_common); 331 if (rc != SEPOL_OK) { 332 goto exit; 333 } 334 } 335 sepol_class->comdatum = sepol_common; 336 sepol_class->comkey = cil_strdup(key); 337 sepol_class->permissions.nprim += sepol_common->permissions.nprim; 338 339 for (curr = NODE(cil_class->common)->cl_head, i = 1; curr; curr = curr->next, i++) { 340 struct cil_perm *cil_perm = curr->data; 341 perm_value_to_cil[class_index][i] = cil_perm; 342 } 343 } 344 345 for (curr = NODE(cil_class)->cl_head; curr; curr = curr->next) { 346 struct cil_perm *cil_perm = curr->data; 347 perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm)); 348 memset(sepol_perm, 0, sizeof(perm_datum_t)); 349 350 key = cil_strdup(cil_perm->datum.fqn); 351 rc = hashtab_insert(sepol_class->permissions.table, key, sepol_perm); 352 if (rc != SEPOL_OK) { 353 free(sepol_perm); 354 free(key); 355 goto exit; 356 } 357 sepol_perm->s.value = sepol_class->permissions.nprim + 1; 358 sepol_class->permissions.nprim++; 359 perm_value_to_cil[class_index][sepol_perm->s.value] = cil_perm; 360 } 361 } 362 363 return SEPOL_OK; 364 365 exit: 366 return rc; 367 } 368 369 int cil_role_to_policydb(policydb_t *pdb, struct cil_role *cil_role) 370 { 371 int rc = SEPOL_ERR; 372 uint32_t value = 0; 373 char *key = NULL; 374 role_datum_t *sepol_role = cil_malloc(sizeof(*sepol_role)); 375 role_datum_init(sepol_role); 376 377 if (cil_role->datum.fqn == CIL_KEY_OBJECT_R) { 378 /* special case 379 * object_r defaults to 1 in libsepol symtab */ 380 rc = SEPOL_OK; 381 goto exit; 382 } 383 384 key = cil_strdup(cil_role->datum.fqn); 385 rc = symtab_insert(pdb, SYM_ROLES, (hashtab_key_t)key, sepol_role, SCOPE_DECL, 0, &value); 386 if (rc != SEPOL_OK) { 387 goto exit; 388 } 389 if (ebitmap_set_bit(&sepol_role->dominates, value - 1, 1)) { 390 cil_log(CIL_INFO, "Failed to set dominates bit for role\n"); 391 rc = SEPOL_ERR; 392 goto exit; 393 } 394 sepol_role->s.value = value; 395 return SEPOL_OK; 396 397 exit: 398 free(key); 399 role_datum_destroy(sepol_role); 400 free(sepol_role); 401 return rc; 402 } 403 404 int cil_role_bounds_to_policydb(policydb_t *pdb, struct cil_role *cil_role) 405 { 406 int rc = SEPOL_ERR; 407 role_datum_t *sepol_role = NULL; 408 role_datum_t *sepol_parent = NULL; 409 410 if (cil_role->bounds) { 411 rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_role), &sepol_role); 412 if (rc != SEPOL_OK) goto exit; 413 414 rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_role->bounds), &sepol_parent); 415 if (rc != SEPOL_OK) goto exit; 416 417 sepol_role->bounds = sepol_parent->s.value; 418 } 419 420 return SEPOL_OK; 421 422 exit: 423 cil_log(CIL_ERR, "Failed to insert role bounds for role %s\n", cil_role->datum.fqn); 424 return SEPOL_ERR; 425 } 426 427 int cil_roletype_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_role *role) 428 { 429 int rc = SEPOL_ERR; 430 431 if (role->types) { 432 role_datum_t *sepol_role = NULL; 433 type_datum_t *sepol_type = NULL; 434 ebitmap_node_t *tnode; 435 unsigned int i; 436 437 rc = __cil_get_sepol_role_datum(pdb, DATUM(role), &sepol_role); 438 if (rc != SEPOL_OK) goto exit; 439 440 ebitmap_for_each_bit(role->types, tnode, i) { 441 if (!ebitmap_get_bit(role->types, i)) continue; 442 443 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type); 444 if (rc != SEPOL_OK) goto exit; 445 446 if (ebitmap_set_bit(&sepol_role->types.types, sepol_type->s.value - 1, 1)) { 447 cil_log(CIL_INFO, "Failed to set type bit for role\n"); 448 rc = SEPOL_ERR; 449 goto exit; 450 } 451 } 452 } 453 454 return SEPOL_OK; 455 456 exit: 457 return rc; 458 } 459 460 int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type, void *type_value_to_cil[]) 461 { 462 int rc = SEPOL_ERR; 463 uint32_t value = 0; 464 char *key = NULL; 465 type_datum_t *sepol_type = cil_malloc(sizeof(*sepol_type)); 466 type_datum_init(sepol_type); 467 468 sepol_type->flavor = TYPE_TYPE; 469 470 key = cil_strdup(cil_type->datum.fqn); 471 rc = symtab_insert(pdb, SYM_TYPES, key, sepol_type, SCOPE_DECL, 0, &value); 472 if (rc != SEPOL_OK) { 473 goto exit; 474 } 475 sepol_type->s.value = value; 476 sepol_type->primary = 1; 477 478 type_value_to_cil[value] = cil_type; 479 480 return SEPOL_OK; 481 482 exit: 483 free(key); 484 type_datum_destroy(sepol_type); 485 free(sepol_type); 486 return rc; 487 } 488 489 int cil_type_bounds_to_policydb(policydb_t *pdb, struct cil_type *cil_type) 490 { 491 int rc = SEPOL_ERR; 492 type_datum_t *sepol_type = NULL; 493 type_datum_t *sepol_parent = NULL; 494 495 if (cil_type->bounds) { 496 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_type), &sepol_type); 497 if (rc != SEPOL_OK) goto exit; 498 499 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_type->bounds), &sepol_parent); 500 if (rc != SEPOL_OK) goto exit; 501 502 sepol_type->bounds = sepol_parent->s.value; 503 } 504 505 return SEPOL_OK; 506 507 exit: 508 cil_log(CIL_ERR, "Failed to insert type bounds for type %s\n", cil_type->datum.fqn); 509 return SEPOL_ERR; 510 } 511 512 int cil_typealias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias) 513 { 514 int rc = SEPOL_ERR; 515 char *key = NULL; 516 type_datum_t *sepol_type = NULL; 517 type_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_alias)); 518 type_datum_init(sepol_alias); 519 520 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_alias->actual), &sepol_type); 521 if (rc != SEPOL_OK) goto exit; 522 523 sepol_alias->flavor = TYPE_TYPE; 524 525 key = cil_strdup(cil_alias->datum.fqn); 526 rc = symtab_insert(pdb, SYM_TYPES, key, sepol_alias, SCOPE_DECL, 0, NULL); 527 if (rc != SEPOL_OK) { 528 goto exit; 529 } 530 sepol_alias->s.value = sepol_type->s.value; 531 sepol_alias->primary = 0; 532 533 return SEPOL_OK; 534 535 exit: 536 free(key); 537 type_datum_destroy(sepol_alias); 538 free(sepol_alias); 539 return rc; 540 } 541 542 int cil_typepermissive_to_policydb(policydb_t *pdb, struct cil_typepermissive *cil_typeperm) 543 { 544 int rc = SEPOL_ERR; 545 type_datum_t *sepol_type = NULL; 546 547 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_typeperm->type), &sepol_type); 548 if (rc != SEPOL_OK) goto exit; 549 550 if (ebitmap_set_bit(&pdb->permissive_map, sepol_type->s.value, 1)) { 551 goto exit; 552 } 553 554 return SEPOL_OK; 555 556 exit: 557 type_datum_destroy(sepol_type); 558 free(sepol_type); 559 return rc; 560 561 } 562 563 int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr, void *type_value_to_cil[]) 564 { 565 int rc = SEPOL_ERR; 566 uint32_t value = 0; 567 char *key = NULL; 568 type_datum_t *sepol_attr = NULL; 569 570 if (!cil_attr->used) { 571 return SEPOL_OK; 572 } 573 574 sepol_attr = cil_malloc(sizeof(*sepol_attr)); 575 type_datum_init(sepol_attr); 576 577 sepol_attr->flavor = TYPE_ATTRIB; 578 579 key = cil_strdup(cil_attr->datum.fqn); 580 rc = symtab_insert(pdb, SYM_TYPES, key, sepol_attr, SCOPE_DECL, 0, &value); 581 if (rc != SEPOL_OK) { 582 goto exit; 583 } 584 sepol_attr->s.value = value; 585 sepol_attr->primary = 1; 586 587 type_value_to_cil[value] = cil_attr; 588 589 return SEPOL_OK; 590 591 exit: 592 type_datum_destroy(sepol_attr); 593 free(sepol_attr); 594 return rc; 595 } 596 597 int __cil_typeattr_bitmap_init(policydb_t *pdb) 598 { 599 int rc = SEPOL_ERR; 600 601 pdb->type_attr_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t)); 602 pdb->attr_type_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t)); 603 604 uint32_t i = 0; 605 for (i = 0; i < pdb->p_types.nprim; i++) { 606 ebitmap_init(&pdb->type_attr_map[i]); 607 ebitmap_init(&pdb->attr_type_map[i]); 608 if (ebitmap_set_bit(&pdb->type_attr_map[i], i, 1)) { 609 rc = SEPOL_ERR; 610 goto exit; 611 } 612 if (pdb->type_val_to_struct[i] && pdb->type_val_to_struct[i]->flavor != TYPE_ATTRIB) { 613 if (ebitmap_set_bit(&pdb->attr_type_map[i], i, 1)) { 614 rc = SEPOL_ERR; 615 goto exit; 616 } 617 } 618 619 } 620 621 return SEPOL_OK; 622 623 exit: 624 return rc; 625 } 626 627 int cil_typeattribute_to_bitmap(policydb_t *pdb, const struct cil_db *db, struct cil_typeattribute *cil_attr) 628 { 629 int rc = SEPOL_ERR; 630 uint32_t value = 0; 631 type_datum_t *sepol_type = NULL; 632 ebitmap_node_t *tnode; 633 unsigned int i; 634 635 if (!cil_attr->used) { 636 return SEPOL_OK; 637 } 638 639 if (pdb->type_attr_map == NULL) { 640 rc = __cil_typeattr_bitmap_init(pdb); 641 if (rc != SEPOL_OK) { 642 goto exit; 643 } 644 } 645 646 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_attr), &sepol_type); 647 if (rc != SEPOL_OK) goto exit; 648 649 value = sepol_type->s.value; 650 651 ebitmap_for_each_bit(cil_attr->types, tnode, i) { 652 if (!ebitmap_get_bit(cil_attr->types, i)) continue; 653 654 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type); 655 if (rc != SEPOL_OK) goto exit; 656 657 ebitmap_set_bit(&pdb->type_attr_map[sepol_type->s.value - 1], value - 1, 1); 658 ebitmap_set_bit(&pdb->attr_type_map[value - 1], sepol_type->s.value - 1, 1); 659 } 660 661 rc = SEPOL_OK; 662 exit: 663 return rc; 664 } 665 666 int cil_policycap_to_policydb(policydb_t *pdb, struct cil_policycap *cil_polcap) 667 { 668 int rc = SEPOL_ERR; 669 int capnum; 670 671 capnum = sepol_polcap_getnum(cil_polcap->datum.fqn); 672 if (capnum == -1) { 673 goto exit; 674 } 675 676 if (ebitmap_set_bit(&pdb->policycaps, capnum, 1)) { 677 goto exit; 678 } 679 680 return SEPOL_OK; 681 682 exit: 683 return rc; 684 } 685 686 int cil_user_to_policydb(policydb_t *pdb, struct cil_user *cil_user) 687 { 688 int rc = SEPOL_ERR; 689 uint32_t value = 0; 690 char *key = NULL; 691 user_datum_t *sepol_user = cil_malloc(sizeof(*sepol_user)); 692 user_datum_init(sepol_user); 693 694 key = cil_strdup(cil_user->datum.fqn); 695 rc = symtab_insert(pdb, SYM_USERS, key, sepol_user, SCOPE_DECL, 0, &value); 696 if (rc != SEPOL_OK) { 697 goto exit; 698 } 699 sepol_user->s.value = value; 700 701 return SEPOL_OK; 702 703 exit: 704 free(key); 705 user_datum_destroy(sepol_user); 706 free(sepol_user); 707 return rc; 708 } 709 710 int cil_user_bounds_to_policydb(policydb_t *pdb, struct cil_user *cil_user) 711 { 712 int rc = SEPOL_ERR; 713 user_datum_t *sepol_user = NULL; 714 user_datum_t *sepol_parent = NULL; 715 716 if (cil_user->bounds) { 717 rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user); 718 if (rc != SEPOL_OK) goto exit; 719 720 rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user->bounds), &sepol_parent); 721 if (rc != SEPOL_OK) goto exit; 722 723 sepol_user->bounds = sepol_parent->s.value; 724 } 725 726 return SEPOL_OK; 727 728 exit: 729 cil_log(CIL_ERR, "Failed to insert user bounds for user %s\n", cil_user->datum.fqn); 730 return SEPOL_ERR; 731 } 732 733 int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_user *user) 734 { 735 int rc = SEPOL_ERR; 736 user_datum_t *sepol_user = NULL; 737 role_datum_t *sepol_role = NULL; 738 ebitmap_node_t *rnode = NULL; 739 unsigned int i; 740 741 if (user->roles) { 742 rc = __cil_get_sepol_user_datum(pdb, DATUM(user), &sepol_user); 743 if (rc != SEPOL_OK) { 744 goto exit; 745 } 746 747 ebitmap_for_each_bit(user->roles, rnode, i) { 748 if (!ebitmap_get_bit(user->roles, i)) { 749 continue; 750 } 751 752 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role); 753 if (rc != SEPOL_OK) { 754 goto exit; 755 } 756 757 if (sepol_role->s.value == 1) { 758 // role is object_r, ignore it since it is implicitly associated 759 // with all users 760 continue; 761 } 762 763 if (ebitmap_set_bit(&sepol_user->roles.roles, sepol_role->s.value - 1, 1)) { 764 cil_log(CIL_INFO, "Failed to set role bit for user\n"); 765 rc = SEPOL_ERR; 766 goto exit; 767 } 768 } 769 } 770 771 rc = SEPOL_OK; 772 773 exit: 774 return rc; 775 } 776 777 int cil_bool_to_policydb(policydb_t *pdb, struct cil_bool *cil_bool) 778 { 779 int rc = SEPOL_ERR; 780 uint32_t value = 0; 781 char *key = NULL; 782 cond_bool_datum_t *sepol_bool = cil_malloc(sizeof(*sepol_bool)); 783 memset(sepol_bool, 0, sizeof(cond_bool_datum_t)); 784 785 key = cil_strdup(cil_bool->datum.fqn); 786 rc = symtab_insert(pdb, SYM_BOOLS, key, sepol_bool, SCOPE_DECL, 0, &value); 787 if (rc != SEPOL_OK) { 788 goto exit; 789 } 790 sepol_bool->s.value = value; 791 sepol_bool->state = cil_bool->value; 792 793 return SEPOL_OK; 794 795 exit: 796 free(key); 797 free(sepol_bool); 798 return rc; 799 } 800 801 int cil_catorder_to_policydb(policydb_t *pdb, const struct cil_db *db) 802 { 803 int rc = SEPOL_ERR; 804 uint32_t value = 0; 805 char *key = NULL; 806 struct cil_list_item *curr_cat; 807 struct cil_cat *cil_cat = NULL; 808 cat_datum_t *sepol_cat = NULL; 809 810 cil_list_for_each(curr_cat, db->catorder) { 811 cil_cat = curr_cat->data; 812 sepol_cat = cil_malloc(sizeof(*sepol_cat)); 813 cat_datum_init(sepol_cat); 814 815 key = cil_strdup(cil_cat->datum.fqn); 816 rc = symtab_insert(pdb, SYM_CATS, key, sepol_cat, SCOPE_DECL, 0, &value); 817 if (rc != SEPOL_OK) { 818 goto exit; 819 } 820 sepol_cat->s.value = value; 821 } 822 823 return SEPOL_OK; 824 825 exit: 826 free(key); 827 cat_datum_destroy(sepol_cat); 828 free(sepol_cat); 829 return rc; 830 } 831 832 int cil_catalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias) 833 { 834 int rc = SEPOL_ERR; 835 char *key = NULL; 836 cat_datum_t *sepol_cat; 837 cat_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_cat)); 838 cat_datum_init(sepol_alias); 839 840 rc = __cil_get_sepol_cat_datum(pdb, DATUM(cil_alias->actual), &sepol_cat); 841 if (rc != SEPOL_OK) goto exit; 842 843 key = cil_strdup(cil_alias->datum.fqn); 844 rc = symtab_insert(pdb, SYM_CATS, key, sepol_alias, SCOPE_DECL, 0, NULL); 845 if (rc != SEPOL_OK) { 846 goto exit; 847 } 848 sepol_alias->s.value = sepol_cat->s.value; 849 sepol_alias->isalias = 1; 850 851 return SEPOL_OK; 852 853 exit: 854 free(key); 855 cat_datum_destroy(sepol_alias); 856 free(sepol_alias); 857 return rc; 858 } 859 860 int cil_sensitivityorder_to_policydb(policydb_t *pdb, const struct cil_db *db) 861 { 862 int rc = SEPOL_ERR; 863 uint32_t value = 0; 864 char *key = NULL; 865 struct cil_list_item *curr; 866 struct cil_sens *cil_sens = NULL; 867 level_datum_t *sepol_level = NULL; 868 mls_level_t *mls_level = NULL; 869 870 cil_list_for_each(curr, db->sensitivityorder) { 871 cil_sens = curr->data; 872 sepol_level = cil_malloc(sizeof(*sepol_level)); 873 mls_level = cil_malloc(sizeof(*mls_level)); 874 level_datum_init(sepol_level); 875 mls_level_init(mls_level); 876 877 key = cil_strdup(cil_sens->datum.fqn); 878 rc = symtab_insert(pdb, SYM_LEVELS, key, sepol_level, SCOPE_DECL, 0, &value); 879 if (rc != SEPOL_OK) { 880 goto exit; 881 } 882 mls_level->sens = value; 883 sepol_level->level = mls_level; 884 } 885 886 return SEPOL_OK; 887 888 exit: 889 level_datum_destroy(sepol_level); 890 mls_level_destroy(mls_level); 891 free(sepol_level); 892 free(mls_level); 893 free(key); 894 return rc; 895 } 896 897 int cil_sensalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias) 898 { 899 int rc = SEPOL_ERR; 900 char *key = NULL; 901 mls_level_t *mls_level = NULL; 902 level_datum_t *sepol_level = NULL; 903 level_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_alias)); 904 level_datum_init(sepol_alias); 905 906 rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_alias->actual), &sepol_level); 907 if (rc != SEPOL_OK) goto exit; 908 909 key = cil_strdup(cil_alias->datum.fqn); 910 rc = symtab_insert(pdb, SYM_LEVELS, key, sepol_alias, SCOPE_DECL, 0, NULL); 911 if (rc != SEPOL_OK) { 912 goto exit; 913 } 914 915 mls_level = cil_malloc(sizeof(*mls_level)); 916 mls_level_init(mls_level); 917 918 rc = mls_level_cpy(mls_level, sepol_level->level); 919 if (rc != SEPOL_OK) { 920 goto exit; 921 } 922 sepol_alias->level = mls_level; 923 sepol_alias->defined = 1; 924 sepol_alias->isalias = 1; 925 926 return SEPOL_OK; 927 928 exit: 929 level_datum_destroy(sepol_alias); 930 free(sepol_level); 931 free(key); 932 return rc; 933 } 934 935 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) 936 { 937 int rc = SEPOL_OK; 938 avtab_ptr_t avtab_ptr = NULL; 939 cond_av_list_t *cond_list = NULL; 940 941 avtab_ptr = avtab_insert_nonunique(avtab, avtab_key, avtab_datum); 942 if (!avtab_ptr) { 943 rc = SEPOL_ERR; 944 goto exit; 945 } 946 947 // parse_context needs to be non-NULL for conditional rules to be 948 // written to the binary. it is normally used for finding duplicates, 949 // but cil checks that earlier, so we don't use it. it just needs to be 950 // set 951 avtab_ptr->parse_context = (void*)1; 952 953 cond_list = cil_malloc(sizeof(cond_av_list_t)); 954 memset(cond_list, 0, sizeof(cond_av_list_t)); 955 956 cond_list->node = avtab_ptr; 957 958 if (cond_flavor == CIL_CONDTRUE) { 959 cond_list->next = cond_node->true_list; 960 cond_node->true_list = cond_list; 961 } else { 962 cond_list->next = cond_node->false_list; 963 cond_node->false_list = cond_list; 964 } 965 966 exit: 967 return rc; 968 } 969 970 avtab_datum_t *cil_cond_av_list_search(avtab_key_t *key, cond_av_list_t *cond_list) 971 { 972 cond_av_list_t *cur_av; 973 974 for (cur_av = cond_list; cur_av != NULL; cur_av = cur_av->next) { 975 if (cur_av->node->key.source_type == key->source_type && 976 cur_av->node->key.target_type == key->target_type && 977 cur_av->node->key.target_class == key->target_class && 978 (cur_av->node->key.specified & key->specified)) 979 980 return &cur_av->node->datum; 981 982 } 983 return NULL; 984 } 985 986 int __cil_insert_type_rule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t res, struct cil_type_rule *cil_rule, cond_node_t *cond_node, enum cil_flavor cond_flavor) 987 { 988 int rc = SEPOL_OK; 989 avtab_key_t avtab_key; 990 avtab_datum_t avtab_datum; 991 avtab_ptr_t existing; 992 993 avtab_key.source_type = src; 994 avtab_key.target_type = tgt; 995 avtab_key.target_class = obj; 996 997 switch (kind) { 998 case CIL_TYPE_TRANSITION: 999 avtab_key.specified = AVTAB_TRANSITION; 1000 break; 1001 case CIL_TYPE_CHANGE: 1002 avtab_key.specified = AVTAB_CHANGE; 1003 break; 1004 case CIL_TYPE_MEMBER: 1005 avtab_key.specified = AVTAB_MEMBER; 1006 break; 1007 default: 1008 rc = SEPOL_ERR; 1009 goto exit; 1010 } 1011 1012 avtab_datum.data = res; 1013 1014 existing = avtab_search_node(&pdb->te_avtab, &avtab_key); 1015 if (existing) { 1016 /* Don't add duplicate type rule and warn if they conflict. 1017 * A warning should have been previously given if there is a 1018 * non-duplicate rule using the same key. 1019 */ 1020 if (existing->datum.data != res) { 1021 cil_log(CIL_ERR, "Conflicting type rules (scontext=%s tcontext=%s tclass=%s result=%s), existing=%s\n", 1022 pdb->p_type_val_to_name[src - 1], 1023 pdb->p_type_val_to_name[tgt - 1], 1024 pdb->p_class_val_to_name[obj - 1], 1025 pdb->p_type_val_to_name[res - 1], 1026 pdb->p_type_val_to_name[existing->datum.data - 1]); 1027 cil_log(CIL_ERR, "Expanded from type rule (scontext=%s tcontext=%s tclass=%s result=%s)\n", 1028 cil_rule->src_str, cil_rule->tgt_str, cil_rule->obj_str, cil_rule->result_str); 1029 rc = SEPOL_ERR; 1030 } 1031 goto exit; 1032 } 1033 1034 if (!cond_node) { 1035 rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum); 1036 } else { 1037 existing = avtab_search_node(&pdb->te_cond_avtab, &avtab_key); 1038 if (existing) { 1039 cond_av_list_t *this_list; 1040 cond_av_list_t *other_list; 1041 avtab_datum_t *search_datum; 1042 1043 if (cond_flavor == CIL_CONDTRUE) { 1044 this_list = cond_node->true_list; 1045 other_list = cond_node->false_list; 1046 } else { 1047 this_list = cond_node->false_list; 1048 other_list = cond_node->true_list; 1049 } 1050 1051 search_datum = cil_cond_av_list_search(&avtab_key, other_list); 1052 if (search_datum == NULL) { 1053 if (existing->datum.data != res) { 1054 cil_log(CIL_ERR, "Conflicting type rules (scontext=%s tcontext=%s tclass=%s result=%s), existing=%s\n", 1055 pdb->p_type_val_to_name[src - 1], 1056 pdb->p_type_val_to_name[tgt - 1], 1057 pdb->p_class_val_to_name[obj - 1], 1058 pdb->p_type_val_to_name[res - 1], 1059 pdb->p_type_val_to_name[existing->datum.data - 1]); 1060 cil_log(CIL_ERR, "Expanded from type rule (scontext=%s tcontext=%s tclass=%s result=%s)\n", 1061 cil_rule->src_str, cil_rule->tgt_str, cil_rule->obj_str, cil_rule->result_str); 1062 rc = SEPOL_ERR; 1063 goto exit; 1064 } 1065 1066 search_datum = cil_cond_av_list_search(&avtab_key, this_list); 1067 if (search_datum) { 1068 goto exit; 1069 } 1070 } 1071 } 1072 rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor); 1073 } 1074 1075 exit: 1076 return rc; 1077 } 1078 1079 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) 1080 { 1081 int rc = SEPOL_ERR; 1082 uint16_t kind = cil_rule->rule_kind; 1083 type_datum_t *sepol_src = NULL; 1084 type_datum_t *sepol_tgt = NULL; 1085 class_datum_t *sepol_obj = NULL; 1086 struct cil_list *class_list; 1087 type_datum_t *sepol_result = NULL; 1088 ebitmap_t src_bitmap, tgt_bitmap; 1089 ebitmap_node_t *node1, *node2; 1090 unsigned int i, j; 1091 struct cil_list_item *c; 1092 1093 rc = __cil_expand_type(cil_rule->src, &src_bitmap); 1094 if (rc != SEPOL_OK) goto exit; 1095 1096 rc = __cil_expand_type(cil_rule->tgt, &tgt_bitmap); 1097 if (rc != SEPOL_OK) goto exit; 1098 1099 class_list = cil_expand_class(cil_rule->obj); 1100 1101 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_rule->result), &sepol_result); 1102 if (rc != SEPOL_OK) goto exit; 1103 1104 ebitmap_for_each_bit(&src_bitmap, node1, i) { 1105 if (!ebitmap_get_bit(&src_bitmap, i)) continue; 1106 1107 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); 1108 if (rc != SEPOL_OK) goto exit; 1109 1110 ebitmap_for_each_bit(&tgt_bitmap, node2, j) { 1111 if (!ebitmap_get_bit(&tgt_bitmap, j)) continue; 1112 1113 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt); 1114 if (rc != SEPOL_OK) goto exit; 1115 1116 cil_list_for_each(c, class_list) { 1117 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); 1118 if (rc != SEPOL_OK) goto exit; 1119 1120 rc = __cil_insert_type_rule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, sepol_result->s.value, cil_rule, cond_node, cond_flavor); 1121 if (rc != SEPOL_OK) goto exit; 1122 } 1123 } 1124 } 1125 1126 rc = SEPOL_OK; 1127 1128 exit: 1129 ebitmap_destroy(&src_bitmap); 1130 ebitmap_destroy(&tgt_bitmap); 1131 cil_list_destroy(&class_list, CIL_FALSE); 1132 return rc; 1133 } 1134 1135 int cil_type_rule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_type_rule *cil_rule) 1136 { 1137 return __cil_type_rule_to_avtab(pdb, db, cil_rule, NULL, CIL_FALSE); 1138 } 1139 1140 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) 1141 { 1142 int rc = SEPOL_ERR; 1143 type_datum_t *sepol_src = NULL; 1144 type_datum_t *sepol_tgt = NULL; 1145 class_datum_t *sepol_obj = NULL; 1146 struct cil_list *class_list; 1147 type_datum_t *sepol_result = NULL; 1148 filename_trans_t *newkey = NULL; 1149 filename_trans_datum_t *newdatum = NULL, *otype = NULL; 1150 ebitmap_t src_bitmap, tgt_bitmap; 1151 ebitmap_node_t *node1, *node2; 1152 unsigned int i, j; 1153 struct cil_list_item *c; 1154 char *name = DATUM(typetrans->name)->name; 1155 1156 if (name == CIL_KEY_STAR) { 1157 struct cil_type_rule trans; 1158 trans.rule_kind = CIL_TYPE_TRANSITION; 1159 trans.src = typetrans->src; 1160 trans.tgt = typetrans->tgt; 1161 trans.obj = typetrans->obj; 1162 trans.result = typetrans->result; 1163 trans.src_str = typetrans->src_str; 1164 trans.tgt_str = typetrans->tgt_str; 1165 trans.obj_str = typetrans->obj_str; 1166 trans.result_str = typetrans->result_str; 1167 return __cil_type_rule_to_avtab(pdb, db, &trans, cond_node, cond_flavor); 1168 } 1169 1170 rc = __cil_expand_type(typetrans->src, &src_bitmap); 1171 if (rc != SEPOL_OK) goto exit; 1172 1173 rc = __cil_expand_type(typetrans->tgt, &tgt_bitmap); 1174 if (rc != SEPOL_OK) goto exit; 1175 1176 class_list = cil_expand_class(typetrans->obj); 1177 1178 rc = __cil_get_sepol_type_datum(pdb, DATUM(typetrans->result), &sepol_result); 1179 if (rc != SEPOL_OK) goto exit; 1180 1181 ebitmap_for_each_bit(&src_bitmap, node1, i) { 1182 if (!ebitmap_get_bit(&src_bitmap, i)) continue; 1183 1184 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); 1185 if (rc != SEPOL_OK) goto exit; 1186 1187 ebitmap_for_each_bit(&tgt_bitmap, node2, j) { 1188 if (!ebitmap_get_bit(&tgt_bitmap, j)) continue; 1189 1190 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt); 1191 if (rc != SEPOL_OK) goto exit; 1192 1193 cil_list_for_each(c, class_list) { 1194 int add = CIL_TRUE; 1195 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); 1196 if (rc != SEPOL_OK) goto exit; 1197 1198 newkey = cil_calloc(1, sizeof(*newkey)); 1199 newdatum = cil_calloc(1, sizeof(*newdatum)); 1200 newkey->stype = sepol_src->s.value; 1201 newkey->ttype = sepol_tgt->s.value; 1202 newkey->tclass = sepol_obj->s.value; 1203 newkey->name = cil_strdup(name); 1204 newdatum->otype = sepol_result->s.value; 1205 1206 rc = hashtab_insert(filename_trans_table, (hashtab_key_t)newkey, newdatum); 1207 if (rc != SEPOL_OK) { 1208 if (rc == SEPOL_EEXIST) { 1209 add = CIL_FALSE; 1210 otype = hashtab_search(filename_trans_table, (hashtab_key_t)newkey); 1211 if (newdatum->otype != otype->otype) { 1212 cil_log(CIL_ERR, "Conflicting name type transition rules\n"); 1213 } else { 1214 rc = SEPOL_OK; 1215 } 1216 } else { 1217 cil_log(CIL_ERR, "Out of memory\n"); 1218 } 1219 } 1220 1221 if (add == CIL_TRUE) { 1222 rc = hashtab_insert(pdb->filename_trans, 1223 (hashtab_key_t)newkey, 1224 newdatum); 1225 if (rc != SEPOL_OK) { 1226 cil_log(CIL_ERR, "Out of memory\n"); 1227 goto exit; 1228 } 1229 } else { 1230 free(newkey->name); 1231 free(newkey); 1232 free(newdatum); 1233 if (rc != SEPOL_OK) { 1234 goto exit; 1235 } 1236 } 1237 } 1238 } 1239 } 1240 1241 rc = SEPOL_OK; 1242 1243 exit: 1244 ebitmap_destroy(&src_bitmap); 1245 ebitmap_destroy(&tgt_bitmap); 1246 cil_list_destroy(&class_list, CIL_FALSE); 1247 return rc; 1248 } 1249 1250 int cil_typetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, hashtab_t filename_trans_table) 1251 { 1252 return __cil_typetransition_to_avtab(pdb, db, typetrans, NULL, CIL_FALSE, filename_trans_table); 1253 } 1254 1255 int __perm_str_to_datum(char *perm_str, class_datum_t *sepol_class, uint32_t *datum) 1256 { 1257 int rc; 1258 perm_datum_t *sepol_perm; 1259 common_datum_t *sepol_common; 1260 1261 sepol_perm = hashtab_search(sepol_class->permissions.table, perm_str); 1262 if (sepol_perm == NULL) { 1263 sepol_common = sepol_class->comdatum; 1264 sepol_perm = hashtab_search(sepol_common->permissions.table, perm_str); 1265 if (sepol_perm == NULL) { 1266 cil_log(CIL_ERR, "Failed to find datum for perm %s\n", perm_str); 1267 rc = SEPOL_ERR; 1268 goto exit; 1269 } 1270 } 1271 *datum |= 1 << (sepol_perm->s.value - 1); 1272 1273 return SEPOL_OK; 1274 1275 exit: 1276 return rc; 1277 } 1278 1279 int __cil_perms_to_datum(struct cil_list *perms, class_datum_t *sepol_class, uint32_t *datum) 1280 { 1281 int rc = SEPOL_ERR; 1282 char *key = NULL; 1283 struct cil_list_item *curr_perm; 1284 struct cil_perm *cil_perm; 1285 uint32_t data = 0; 1286 1287 cil_list_for_each(curr_perm, perms) { 1288 cil_perm = curr_perm->data; 1289 key = cil_perm->datum.fqn; 1290 1291 rc = __perm_str_to_datum(key, sepol_class, &data); 1292 if (rc != SEPOL_OK) { 1293 goto exit; 1294 } 1295 } 1296 1297 *datum = data; 1298 1299 return SEPOL_OK; 1300 1301 exit: 1302 return rc; 1303 } 1304 1305 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) 1306 { 1307 int rc = SEPOL_OK; 1308 avtab_key_t avtab_key; 1309 avtab_datum_t avtab_datum; 1310 avtab_datum_t *avtab_dup = NULL; 1311 1312 avtab_key.source_type = src; 1313 avtab_key.target_type = tgt; 1314 avtab_key.target_class = obj; 1315 1316 switch (kind) { 1317 case CIL_AVRULE_ALLOWED: 1318 avtab_key.specified = AVTAB_ALLOWED; 1319 break; 1320 case CIL_AVRULE_AUDITALLOW: 1321 avtab_key.specified = AVTAB_AUDITALLOW; 1322 break; 1323 case CIL_AVRULE_DONTAUDIT: 1324 avtab_key.specified = AVTAB_AUDITDENY; 1325 break; 1326 default: 1327 rc = SEPOL_ERR; 1328 goto exit; 1329 break; 1330 } 1331 1332 if (!cond_node) { 1333 avtab_dup = avtab_search(&pdb->te_avtab, &avtab_key); 1334 if (!avtab_dup) { 1335 avtab_datum.data = data; 1336 rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum); 1337 } else { 1338 if (kind == CIL_AVRULE_DONTAUDIT) 1339 avtab_dup->data &= data; 1340 else 1341 avtab_dup->data |= data; 1342 } 1343 } else { 1344 avtab_datum.data = data; 1345 rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor); 1346 } 1347 1348 exit: 1349 return rc; 1350 } 1351 1352 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, cond_node_t *cond_node, enum cil_flavor cond_flavor) 1353 { 1354 int rc = SEPOL_ERR; 1355 type_datum_t *sepol_src = NULL; 1356 type_datum_t *sepol_tgt = NULL; 1357 class_datum_t *sepol_class = NULL; 1358 uint32_t data = 0; 1359 1360 rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class); 1361 if (rc != SEPOL_OK) goto exit; 1362 1363 rc = __cil_perms_to_datum(cp->perms, sepol_class, &data); 1364 if (rc != SEPOL_OK) goto exit; 1365 1366 if (data == 0) { 1367 /* No permissions, so don't insert rule. Maybe should return an error? */ 1368 return SEPOL_OK; 1369 } 1370 1371 if (kind == CIL_AVRULE_DONTAUDIT) { 1372 data = ~data; 1373 } 1374 1375 rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src); 1376 if (rc != SEPOL_OK) goto exit; 1377 1378 rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt); 1379 if (rc != SEPOL_OK) goto exit; 1380 1381 rc = __cil_insert_avrule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_class->s.value, data, cond_node, cond_flavor); 1382 if (rc != SEPOL_OK) { 1383 goto exit; 1384 } 1385 1386 return SEPOL_OK; 1387 1388 exit: 1389 return rc; 1390 } 1391 1392 1393 int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms, cond_node_t *cond_node, enum cil_flavor cond_flavor) 1394 { 1395 int rc = SEPOL_ERR; 1396 struct cil_list_item *curr; 1397 1398 cil_list_for_each(curr, classperms) { 1399 if (curr->flavor == CIL_CLASSPERMS) { 1400 struct cil_classperms *cp = curr->data; 1401 if (FLAVOR(cp->class) == CIL_CLASS) { 1402 rc = __cil_avrule_expand_helper(pdb, kind, src, tgt, cp, cond_node, cond_flavor); 1403 if (rc != SEPOL_OK) { 1404 goto exit; 1405 } 1406 } else { /* MAP */ 1407 struct cil_list_item *i = NULL; 1408 cil_list_for_each(i, cp->perms) { 1409 struct cil_perm *cmp = i->data; 1410 rc = __cil_avrule_expand(pdb, kind, src, tgt, cmp->classperms, cond_node, cond_flavor); 1411 if (rc != SEPOL_OK) { 1412 goto exit; 1413 } 1414 } 1415 } 1416 } else { /* SET */ 1417 struct cil_classperms_set *cp_set = curr->data; 1418 struct cil_classpermission *cp = cp_set->set; 1419 rc = __cil_avrule_expand(pdb, kind, src, tgt, cp->classperms, cond_node, cond_flavor); 1420 if (rc != SEPOL_OK) { 1421 goto exit; 1422 } 1423 } 1424 } 1425 1426 return SEPOL_OK; 1427 1428 exit: 1429 return rc; 1430 } 1431 1432 static int __cil_should_expand_attribute( const struct cil_db *db, struct cil_symtab_datum *datum) 1433 { 1434 struct cil_tree_node *node; 1435 struct cil_typeattribute *attr; 1436 1437 node = NODE(datum); 1438 1439 if (node->flavor != CIL_TYPEATTRIBUTE) { 1440 return CIL_FALSE; 1441 } 1442 1443 attr = (struct cil_typeattribute *)datum; 1444 1445 return !attr->used || (ebitmap_cardinality(attr->types) < db->attrs_expand_size); 1446 } 1447 1448 int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, cond_node_t *cond_node, enum cil_flavor cond_flavor) 1449 { 1450 int rc = SEPOL_ERR; 1451 uint16_t kind = cil_avrule->rule_kind; 1452 struct cil_symtab_datum *src = NULL; 1453 struct cil_symtab_datum *tgt = NULL; 1454 struct cil_list *classperms = cil_avrule->perms.classperms; 1455 ebitmap_t src_bitmap, tgt_bitmap; 1456 ebitmap_node_t *snode, *tnode; 1457 unsigned int s,t; 1458 1459 if (cil_avrule->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) { 1460 // Do not add dontaudit rules to binary 1461 rc = SEPOL_OK; 1462 goto exit; 1463 } 1464 1465 src = cil_avrule->src; 1466 tgt = cil_avrule->tgt; 1467 1468 if (tgt->fqn == CIL_KEY_SELF) { 1469 rc = __cil_expand_type(src, &src_bitmap); 1470 if (rc != SEPOL_OK) { 1471 goto exit; 1472 } 1473 1474 ebitmap_for_each_bit(&src_bitmap, snode, s) { 1475 if (!ebitmap_get_bit(&src_bitmap, s)) continue; 1476 1477 src = DATUM(db->val_to_type[s]); 1478 rc = __cil_avrule_expand(pdb, kind, src, src, classperms, cond_node, cond_flavor); 1479 if (rc != SEPOL_OK) { 1480 ebitmap_destroy(&src_bitmap); 1481 goto exit; 1482 } 1483 } 1484 ebitmap_destroy(&src_bitmap); 1485 } else { 1486 int expand_src = __cil_should_expand_attribute(db, src); 1487 int expand_tgt = __cil_should_expand_attribute(db, tgt); 1488 if (!expand_src && !expand_tgt) { 1489 rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); 1490 if (rc != SEPOL_OK) { 1491 goto exit; 1492 } 1493 } else if (expand_src && expand_tgt) { 1494 rc = __cil_expand_type(src, &src_bitmap); 1495 if (rc != SEPOL_OK) { 1496 goto exit; 1497 } 1498 1499 rc = __cil_expand_type(tgt, &tgt_bitmap); 1500 if (rc != SEPOL_OK) { 1501 ebitmap_destroy(&src_bitmap); 1502 goto exit; 1503 } 1504 1505 ebitmap_for_each_bit(&src_bitmap, snode, s) { 1506 if (!ebitmap_get_bit(&src_bitmap, s)) continue; 1507 src = DATUM(db->val_to_type[s]); 1508 ebitmap_for_each_bit(&tgt_bitmap, tnode, t) { 1509 if (!ebitmap_get_bit(&tgt_bitmap, t)) continue; 1510 tgt = DATUM(db->val_to_type[t]); 1511 1512 rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); 1513 if (rc != SEPOL_OK) { 1514 ebitmap_destroy(&src_bitmap); 1515 ebitmap_destroy(&tgt_bitmap); 1516 goto exit; 1517 } 1518 } 1519 } 1520 ebitmap_destroy(&src_bitmap); 1521 ebitmap_destroy(&tgt_bitmap); 1522 } else if (expand_src) { 1523 rc = __cil_expand_type(src, &src_bitmap); 1524 if (rc != SEPOL_OK) { 1525 goto exit; 1526 } 1527 1528 ebitmap_for_each_bit(&src_bitmap, snode, s) { 1529 if (!ebitmap_get_bit(&src_bitmap, s)) continue; 1530 src = DATUM(db->val_to_type[s]); 1531 1532 rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); 1533 if (rc != SEPOL_OK) { 1534 ebitmap_destroy(&src_bitmap); 1535 goto exit; 1536 } 1537 } 1538 ebitmap_destroy(&src_bitmap); 1539 } else { /* expand_tgt */ 1540 rc = __cil_expand_type(tgt, &tgt_bitmap); 1541 if (rc != SEPOL_OK) { 1542 goto exit; 1543 } 1544 1545 ebitmap_for_each_bit(&tgt_bitmap, tnode, t) { 1546 if (!ebitmap_get_bit(&tgt_bitmap, t)) continue; 1547 tgt = DATUM(db->val_to_type[t]); 1548 1549 rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor); 1550 if (rc != SEPOL_OK) { 1551 ebitmap_destroy(&tgt_bitmap); 1552 goto exit; 1553 } 1554 } 1555 ebitmap_destroy(&tgt_bitmap); 1556 } 1557 } 1558 1559 return SEPOL_OK; 1560 1561 exit: 1562 return rc; 1563 } 1564 1565 int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule) 1566 { 1567 return __cil_avrule_to_avtab(pdb, db, cil_avrule, NULL, CIL_FALSE); 1568 } 1569 1570 // Copied from checkpolicy/policy_define.c 1571 1572 /* index of the u32 containing the permission */ 1573 #define XPERM_IDX(x) (x >> 5) 1574 /* set bits 0 through x-1 within the u32 */ 1575 #define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1) 1576 /* low value for this u32 */ 1577 #define XPERM_LOW(x) (x << 5) 1578 /* high value for this u32 */ 1579 #define XPERM_HIGH(x) (((x + 1) << 5) - 1) 1580 void __avrule_xperm_setrangebits(uint16_t low, uint16_t high, struct avtab_extended_perms *xperms) 1581 { 1582 unsigned int i; 1583 uint16_t h = high + 1; 1584 /* for each u32 that this low-high range touches, set driver permissions */ 1585 for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) { 1586 /* set all bits in u32 */ 1587 if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i))) 1588 xperms->perms[i] |= ~0U; 1589 /* set low bits */ 1590 else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i))) 1591 xperms->perms[i] |= XPERM_SETBITS(h); 1592 /* set high bits */ 1593 else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i))) 1594 xperms->perms[i] |= ~0U - XPERM_SETBITS(low); 1595 /* set middle bits */ 1596 else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i))) 1597 xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low); 1598 } 1599 } 1600 1601 1602 #define IOC_DRIV(x) (x >> 8) 1603 #define IOC_FUNC(x) (x & 0xff) 1604 1605 int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil_list **xperms_list) 1606 { 1607 ebitmap_node_t *node; 1608 unsigned int i; 1609 uint16_t low = 0, high = 0; 1610 struct avtab_extended_perms *partial = NULL; 1611 struct avtab_extended_perms *complete = NULL; 1612 int start_new_range; 1613 1614 cil_list_init(xperms_list, CIL_NONE); 1615 1616 start_new_range = 1; 1617 1618 ebitmap_for_each_bit(xperms, node, i) { 1619 if (!ebitmap_get_bit(xperms, i)) continue; 1620 1621 if (start_new_range) { 1622 low = i; 1623 start_new_range = 0; 1624 } 1625 1626 // continue if the current bit isn't the end of the driver function or the next bit is set 1627 if (IOC_FUNC(i) != 0xff && ebitmap_get_bit(xperms, i + 1)) { 1628 continue; 1629 } 1630 1631 // if we got here, i is the end of this range (either becuase the func 1632 // is 0xff or the next bit isn't set). The next time around we are 1633 // going to need a start a new range 1634 high = i; 1635 start_new_range = 1; 1636 1637 if (IOC_FUNC(low) == 0x00 && IOC_FUNC(high) == 0xff) { 1638 if (!complete) { 1639 complete = cil_calloc(1, sizeof(*complete)); 1640 complete->driver = 0x0; 1641 complete->specified = AVTAB_XPERMS_IOCTLDRIVER; 1642 } 1643 1644 __avrule_xperm_setrangebits(IOC_DRIV(low), IOC_DRIV(low), complete); 1645 } else { 1646 if (partial && partial->driver != IOC_DRIV(low)) { 1647 cil_list_append(*xperms_list, CIL_NONE, partial); 1648 partial = NULL; 1649 } 1650 1651 if (!partial) { 1652 partial = cil_calloc(1, sizeof(*partial)); 1653 partial->driver = IOC_DRIV(low); 1654 partial->specified = AVTAB_XPERMS_IOCTLFUNCTION; 1655 } 1656 1657 __avrule_xperm_setrangebits(IOC_FUNC(low), IOC_FUNC(high), partial); 1658 } 1659 } 1660 1661 if (partial) { 1662 cil_list_append(*xperms_list, CIL_NONE, partial); 1663 } 1664 1665 if (complete) { 1666 cil_list_append(*xperms_list, CIL_NONE, complete); 1667 } 1668 1669 return SEPOL_OK; 1670 } 1671 1672 int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args) 1673 { 1674 int rc = SEPOL_OK; 1675 struct policydb *pdb; 1676 avtab_key_t *avtab_key; 1677 avtab_datum_t avtab_datum; 1678 struct cil_list *xperms_list = NULL; 1679 struct cil_list_item *item; 1680 class_datum_t *sepol_obj; 1681 uint32_t data = 0; 1682 1683 avtab_key = (avtab_key_t *)k; 1684 pdb = args; 1685 1686 sepol_obj = pdb->class_val_to_struct[avtab_key->target_class - 1]; 1687 1688 // setting the data for an extended avtab isn't really neccessary because 1689 // it is ignored by the kernel. However, neverallow checking requires that 1690 // the data value be set, so set it for that to work. 1691 rc = __perm_str_to_datum(CIL_KEY_IOCTL, sepol_obj, &data); 1692 if (rc != SEPOL_OK) { 1693 goto exit; 1694 } 1695 avtab_datum.data = data; 1696 1697 rc = __cil_permx_bitmap_to_sepol_xperms_list(datum, &xperms_list); 1698 if (rc != SEPOL_OK) { 1699 goto exit; 1700 } 1701 1702 cil_list_for_each(item, xperms_list) { 1703 avtab_datum.xperms = item->data; 1704 rc = avtab_insert(&pdb->te_avtab, avtab_key, &avtab_datum); 1705 if (rc != SEPOL_OK) { 1706 goto exit; 1707 } 1708 } 1709 1710 rc = SEPOL_OK; 1711 1712 exit: 1713 if (xperms_list != NULL) { 1714 cil_list_for_each(item, xperms_list) { 1715 free(item->data); 1716 } 1717 cil_list_destroy(&xperms_list, CIL_FALSE); 1718 } 1719 1720 // hashtab_t does not have a way to free keys or datum since it doesn't 1721 // know what they are. We won't need the keys/datum after this function, so 1722 // clean them up here. 1723 free(avtab_key); 1724 ebitmap_destroy(datum); 1725 free(datum); 1726 1727 return rc; 1728 } 1729 1730 int __cil_avrulex_ioctl_to_hashtable(hashtab_t h, uint16_t kind, uint32_t src, uint32_t tgt, uint32_t obj, ebitmap_t *xperms) 1731 { 1732 uint16_t specified; 1733 avtab_key_t *avtab_key; 1734 ebitmap_t *hashtab_xperms; 1735 int rc = SEPOL_ERR; 1736 1737 switch (kind) { 1738 case CIL_AVRULE_ALLOWED: 1739 specified = AVTAB_XPERMS_ALLOWED; 1740 break; 1741 case CIL_AVRULE_AUDITALLOW: 1742 specified = AVTAB_XPERMS_AUDITALLOW; 1743 break; 1744 case CIL_AVRULE_DONTAUDIT: 1745 specified = AVTAB_XPERMS_DONTAUDIT; 1746 break; 1747 default: 1748 rc = SEPOL_ERR; 1749 goto exit; 1750 } 1751 1752 avtab_key = cil_malloc(sizeof(*avtab_key)); 1753 avtab_key->source_type = src; 1754 avtab_key->target_type = tgt; 1755 avtab_key->target_class = obj; 1756 avtab_key->specified = specified; 1757 1758 hashtab_xperms = (ebitmap_t *)hashtab_search(h, (hashtab_key_t)avtab_key); 1759 if (!hashtab_xperms) { 1760 hashtab_xperms = cil_malloc(sizeof(*hashtab_xperms)); 1761 rc = ebitmap_cpy(hashtab_xperms, xperms); 1762 if (rc != SEPOL_OK) { 1763 free(avtab_key); 1764 goto exit; 1765 } 1766 rc = hashtab_insert(h, (hashtab_key_t)avtab_key, hashtab_xperms); 1767 if (rc != SEPOL_OK) { 1768 free(avtab_key); 1769 goto exit; 1770 } 1771 } else { 1772 free(avtab_key); 1773 rc = ebitmap_union(hashtab_xperms, xperms); 1774 if (rc != SEPOL_OK) { 1775 goto exit; 1776 } 1777 } 1778 1779 return SEPOL_OK; 1780 1781 exit: 1782 return rc; 1783 } 1784 1785 int __cil_avrulex_to_hashtable_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_permissionx *permx, struct cil_args_binary *args) 1786 { 1787 int rc = SEPOL_ERR; 1788 type_datum_t *sepol_src = NULL; 1789 type_datum_t *sepol_tgt = NULL; 1790 class_datum_t *sepol_obj = NULL; 1791 struct cil_list *class_list = NULL; 1792 struct cil_list_item *c; 1793 1794 rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src); 1795 if (rc != SEPOL_OK) goto exit; 1796 1797 rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt); 1798 if (rc != SEPOL_OK) goto exit; 1799 1800 class_list = cil_expand_class(permx->obj); 1801 1802 cil_list_for_each(c, class_list) { 1803 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); 1804 if (rc != SEPOL_OK) goto exit; 1805 1806 switch (permx->kind) { 1807 case CIL_PERMX_KIND_IOCTL: 1808 rc = __cil_avrulex_ioctl_to_hashtable(args->avrulex_ioctl_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms); 1809 if (rc != SEPOL_OK) goto exit; 1810 break; 1811 default: 1812 rc = SEPOL_ERR; 1813 goto exit; 1814 } 1815 } 1816 1817 rc = SEPOL_OK; 1818 1819 exit: 1820 cil_list_destroy(&class_list, CIL_FALSE); 1821 1822 return rc; 1823 } 1824 1825 int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrulex, struct cil_args_binary *args) 1826 { 1827 int rc = SEPOL_ERR; 1828 uint16_t kind; 1829 struct cil_symtab_datum *src = NULL; 1830 struct cil_symtab_datum *tgt = NULL; 1831 ebitmap_t src_bitmap, tgt_bitmap; 1832 ebitmap_node_t *snode, *tnode; 1833 unsigned int s,t; 1834 1835 if (cil_avrulex->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) { 1836 // Do not add dontaudit rules to binary 1837 rc = SEPOL_OK; 1838 goto exit; 1839 } 1840 1841 kind = cil_avrulex->rule_kind; 1842 src = cil_avrulex->src; 1843 tgt = cil_avrulex->tgt; 1844 1845 if (tgt->fqn == CIL_KEY_SELF) { 1846 rc = __cil_expand_type(src, &src_bitmap); 1847 if (rc != SEPOL_OK) goto exit; 1848 1849 ebitmap_for_each_bit(&src_bitmap, snode, s) { 1850 if (!ebitmap_get_bit(&src_bitmap, s)) continue; 1851 1852 src = DATUM(db->val_to_type[s]); 1853 rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, src, cil_avrulex->perms.x.permx, args); 1854 if (rc != SEPOL_OK) { 1855 goto exit; 1856 } 1857 } 1858 ebitmap_destroy(&src_bitmap); 1859 } else { 1860 int expand_src = __cil_should_expand_attribute(db, src); 1861 int expand_tgt = __cil_should_expand_attribute(db, tgt); 1862 1863 if (!expand_src && !expand_tgt) { 1864 rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); 1865 if (rc != SEPOL_OK) { 1866 goto exit; 1867 } 1868 } else if (expand_src && expand_tgt) { 1869 rc = __cil_expand_type(src, &src_bitmap); 1870 if (rc != SEPOL_OK) { 1871 goto exit; 1872 } 1873 1874 rc = __cil_expand_type(tgt, &tgt_bitmap); 1875 if (rc != SEPOL_OK) { 1876 ebitmap_destroy(&src_bitmap); 1877 goto exit; 1878 } 1879 1880 ebitmap_for_each_bit(&src_bitmap, snode, s) { 1881 if (!ebitmap_get_bit(&src_bitmap, s)) continue; 1882 src = DATUM(db->val_to_type[s]); 1883 ebitmap_for_each_bit(&tgt_bitmap, tnode, t) { 1884 if (!ebitmap_get_bit(&tgt_bitmap, t)) continue; 1885 tgt = DATUM(db->val_to_type[t]); 1886 1887 rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); 1888 if (rc != SEPOL_OK) { 1889 ebitmap_destroy(&src_bitmap); 1890 ebitmap_destroy(&tgt_bitmap); 1891 goto exit; 1892 } 1893 } 1894 } 1895 ebitmap_destroy(&src_bitmap); 1896 ebitmap_destroy(&tgt_bitmap); 1897 } else if (expand_src) { 1898 rc = __cil_expand_type(src, &src_bitmap); 1899 if (rc != SEPOL_OK) { 1900 goto exit; 1901 } 1902 1903 ebitmap_for_each_bit(&src_bitmap, snode, s) { 1904 if (!ebitmap_get_bit(&src_bitmap, s)) continue; 1905 src = DATUM(db->val_to_type[s]); 1906 1907 rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); 1908 if (rc != SEPOL_OK) { 1909 ebitmap_destroy(&src_bitmap); 1910 goto exit; 1911 } 1912 } 1913 ebitmap_destroy(&src_bitmap); 1914 } else { /* expand_tgt */ 1915 rc = __cil_expand_type(tgt, &tgt_bitmap); 1916 if (rc != SEPOL_OK) { 1917 goto exit; 1918 } 1919 1920 ebitmap_for_each_bit(&tgt_bitmap, tnode, t) { 1921 if (!ebitmap_get_bit(&tgt_bitmap, t)) continue; 1922 tgt = DATUM(db->val_to_type[t]); 1923 1924 rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); 1925 if (rc != SEPOL_OK) { 1926 ebitmap_destroy(&tgt_bitmap); 1927 goto exit; 1928 } 1929 } 1930 ebitmap_destroy(&tgt_bitmap); 1931 } 1932 } 1933 1934 return SEPOL_OK; 1935 1936 exit: 1937 return rc; 1938 } 1939 1940 int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args) 1941 { 1942 int rc; 1943 enum cil_flavor flavor; 1944 struct cil_args_booleanif *args = extra_args; 1945 const struct cil_db *db = args->db; 1946 policydb_t *pdb = args->pdb; 1947 cond_node_t *cond_node = args->cond_node; 1948 enum cil_flavor cond_flavor = args->cond_flavor; 1949 struct cil_type_rule *cil_type_rule; 1950 struct cil_avrule *cil_avrule; 1951 struct cil_nametypetransition *cil_typetrans; 1952 hashtab_t filename_trans_table = args->filename_trans_table; 1953 1954 flavor = node->flavor; 1955 switch (flavor) { 1956 case CIL_NAMETYPETRANSITION: 1957 cil_typetrans = (struct cil_nametypetransition*)node->data; 1958 if (DATUM(cil_typetrans->name)->fqn != CIL_KEY_STAR) { 1959 cil_log(CIL_ERR, "typetransition with file name not allowed within a booleanif block.\n"); 1960 cil_tree_log(node, CIL_ERR,"Invalid typetransition statement"); 1961 goto exit; 1962 } 1963 rc = __cil_typetransition_to_avtab(pdb, db, cil_typetrans, cond_node, cond_flavor, filename_trans_table); 1964 if (rc != SEPOL_OK) { 1965 cil_tree_log(node, CIL_ERR, "Failed to insert type transition into avtab"); 1966 goto exit; 1967 } 1968 break; 1969 case CIL_TYPE_RULE: 1970 cil_type_rule = node->data; 1971 rc = __cil_type_rule_to_avtab(pdb, db, cil_type_rule, cond_node, cond_flavor); 1972 if (rc != SEPOL_OK) { 1973 cil_tree_log(node, CIL_ERR, "Failed to insert typerule into avtab"); 1974 goto exit; 1975 } 1976 break; 1977 case CIL_AVRULE: 1978 cil_avrule = node->data; 1979 rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, cond_node, cond_flavor); 1980 if (rc != SEPOL_OK) { 1981 cil_tree_log(node, CIL_ERR, "Failed to insert avrule into avtab"); 1982 goto exit; 1983 } 1984 break; 1985 case CIL_CALL: 1986 case CIL_TUNABLEIF: 1987 break; 1988 default: 1989 cil_tree_log(node, CIL_ERR, "Invalid statement within booleanif"); 1990 goto exit; 1991 } 1992 1993 return SEPOL_OK; 1994 1995 exit: 1996 return SEPOL_ERR; 1997 } 1998 1999 static void __cil_expr_to_string(struct cil_list *expr, enum cil_flavor flavor, char **out); 2000 2001 static void __cil_expr_to_string_helper(struct cil_list_item *curr, enum cil_flavor flavor, char **out) 2002 { 2003 char *c; 2004 2005 if (curr->flavor == CIL_DATUM) { 2006 *out = cil_strdup(DATUM(curr->data)->fqn); 2007 } else if (curr->flavor == CIL_LIST) { 2008 __cil_expr_to_string(curr->data, flavor, &c); 2009 cil_asprintf(out, "(%s)", c); 2010 free(c); 2011 } else if (flavor == CIL_PERMISSIONX) { 2012 // permissionx expressions aren't resolved into anything, so curr->flavor 2013 // is just a CIL_STRING, not a CIL_DATUM, so just check on flavor for those 2014 *out = cil_strdup(curr->data); 2015 } 2016 } 2017 2018 static void __cil_expr_to_string(struct cil_list *expr, enum cil_flavor flavor, char **out) 2019 { 2020 struct cil_list_item *curr; 2021 char *s1 = NULL; 2022 char *s2 = NULL; 2023 enum cil_flavor op; 2024 2025 if (expr == NULL || expr->head == NULL) { 2026 *out = cil_strdup(""); 2027 return; 2028 } 2029 2030 curr = expr->head; 2031 2032 if (curr->flavor == CIL_OP) { 2033 op = (enum cil_flavor)curr->data; 2034 2035 if (op == CIL_ALL) { 2036 *out = cil_strdup(CIL_KEY_ALL); 2037 } else if (op == CIL_RANGE) { 2038 __cil_expr_to_string_helper(curr->next, flavor, &s1); 2039 __cil_expr_to_string_helper(curr->next->next, flavor, &s2); 2040 cil_asprintf(out, "%s %s %s", CIL_KEY_RANGE, s1, s2); 2041 free(s1); 2042 free(s2); 2043 } else { 2044 __cil_expr_to_string_helper(curr->next, flavor, &s1); 2045 2046 if (op == CIL_NOT) { 2047 cil_asprintf(out, "%s %s", CIL_KEY_NOT, s1); 2048 free(s1); 2049 } else { 2050 const char *opstr = ""; 2051 2052 __cil_expr_to_string_helper(curr->next->next, flavor, &s2); 2053 2054 if (op == CIL_OR) { 2055 opstr = CIL_KEY_OR; 2056 } else if (op == CIL_AND) { 2057 opstr = CIL_KEY_AND; 2058 } else if (op == CIL_XOR) { 2059 opstr = CIL_KEY_XOR; 2060 } 2061 2062 cil_asprintf(out, "%s %s %s", opstr, s1, s2); 2063 free(s1); 2064 free(s2); 2065 } 2066 } 2067 } else { 2068 char *c1 = NULL; 2069 char *c2 = NULL; 2070 __cil_expr_to_string_helper(curr, flavor, &c1); 2071 for (curr = curr->next; curr; curr = curr->next) { 2072 __cil_expr_to_string_helper(curr, flavor, &s1); 2073 cil_asprintf(&c2, "%s %s", c1, s1); 2074 free(c1); 2075 free(s1); 2076 c1 = c2; 2077 } 2078 *out = c1; 2079 } 2080 } 2081 2082 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); 2083 2084 static int __cil_cond_item_to_sepol_expr(policydb_t *pdb, struct cil_list_item *item, cond_expr_t **head, cond_expr_t **tail) 2085 { 2086 if (item == NULL) { 2087 goto exit; 2088 } else if (item->flavor == CIL_DATUM) { 2089 char *key = DATUM(item->data)->fqn; 2090 cond_bool_datum_t *sepol_bool = hashtab_search(pdb->p_bools.table, key); 2091 if (sepol_bool == NULL) { 2092 cil_log(CIL_INFO, "Failed to find boolean\n"); 2093 goto exit; 2094 } 2095 *head = cil_malloc(sizeof(cond_expr_t)); 2096 (*head)->next = NULL; 2097 (*head)->expr_type = COND_BOOL; 2098 (*head)->bool = sepol_bool->s.value; 2099 *tail = *head; 2100 } else if (item->flavor == CIL_LIST) { 2101 struct cil_list *l = item->data; 2102 int rc = __cil_cond_expr_to_sepol_expr_helper(pdb, l, head, tail); 2103 if (rc != SEPOL_OK) { 2104 goto exit; 2105 } 2106 } else { 2107 goto exit; 2108 } 2109 2110 return SEPOL_OK; 2111 2112 exit: 2113 return SEPOL_ERR; 2114 } 2115 2116 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) 2117 { 2118 int rc = SEPOL_ERR; 2119 struct cil_list_item *item = cil_expr->head; 2120 enum cil_flavor flavor = cil_expr->flavor; 2121 cond_expr_t *op, *h1, *h2, *t1, *t2; 2122 2123 if (flavor != CIL_BOOL) { 2124 cil_log(CIL_INFO, "Expected boolean expression\n"); 2125 goto exit; 2126 } 2127 2128 if (item == NULL) { 2129 goto exit; 2130 } else if (item->flavor == CIL_OP) { 2131 enum cil_flavor cil_op = (enum cil_flavor)item->data; 2132 2133 op = cil_malloc(sizeof(*op)); 2134 op->bool = 0; 2135 op->next = NULL; 2136 2137 switch (cil_op) { 2138 case CIL_NOT: 2139 op->expr_type = COND_NOT; 2140 break; 2141 case CIL_OR: 2142 op->expr_type = COND_OR; 2143 break; 2144 case CIL_AND: 2145 op->expr_type = COND_AND; 2146 break; 2147 case CIL_XOR: 2148 op->expr_type = COND_XOR; 2149 break; 2150 case CIL_EQ: 2151 op->expr_type = COND_EQ; 2152 break; 2153 case CIL_NEQ: 2154 op->expr_type = COND_NEQ; 2155 break; 2156 default: 2157 goto exit; 2158 } 2159 2160 rc = __cil_cond_item_to_sepol_expr(pdb, item->next, &h1, &t1); 2161 if (rc != SEPOL_OK) { 2162 cil_log(CIL_INFO, "Failed to get first operand of conditional expression\n"); 2163 free(op); 2164 goto exit; 2165 } 2166 2167 if (cil_op == CIL_NOT) { 2168 *head = h1; 2169 t1->next = op; 2170 *tail = op; 2171 } else { 2172 rc = __cil_cond_item_to_sepol_expr(pdb, item->next->next, &h2, &t2); 2173 if (rc != SEPOL_OK) { 2174 cil_log(CIL_INFO, "Failed to get second operand of conditional expression\n"); 2175 free(op); 2176 cond_expr_destroy(h1); 2177 goto exit; 2178 } 2179 2180 *head = h1; 2181 t1->next = h2; 2182 t2->next = op; 2183 *tail = op; 2184 } 2185 } else { 2186 rc = __cil_cond_item_to_sepol_expr(pdb, item, &h1, &t1); 2187 if (rc != SEPOL_OK) { 2188 cil_log(CIL_INFO, "Failed to get initial item in conditional list\n"); 2189 goto exit; 2190 } 2191 *head = h1; 2192 for (item = item->next; item; item = item->next) { 2193 rc = __cil_cond_item_to_sepol_expr(pdb, item, &h2, &t2); 2194 if (rc != SEPOL_OK) { 2195 cil_log(CIL_INFO, "Failed to get item in conditional list\n"); 2196 cond_expr_destroy(*head); 2197 goto exit; 2198 } 2199 op = cil_malloc(sizeof(*op)); 2200 op->bool = 0; 2201 op->next = NULL; 2202 op->expr_type = COND_OR; 2203 t1->next = h2; 2204 t2->next = op; 2205 t1 = op; 2206 } 2207 *tail = t1; 2208 } 2209 2210 return SEPOL_OK; 2211 2212 exit: 2213 return SEPOL_ERR; 2214 } 2215 2216 static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **sepol_expr) 2217 { 2218 int rc; 2219 cond_expr_t *head, *tail; 2220 2221 rc = __cil_cond_expr_to_sepol_expr_helper(pdb, cil_expr, &head, &tail); 2222 if (rc != SEPOL_OK) { 2223 return SEPOL_ERR; 2224 } 2225 *sepol_expr = head; 2226 2227 return SEPOL_OK; 2228 } 2229 2230 int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, hashtab_t filename_trans_table) 2231 { 2232 int rc = SEPOL_ERR; 2233 struct cil_args_booleanif bool_args; 2234 struct cil_booleanif *cil_boolif = (struct cil_booleanif*)node->data; 2235 struct cil_tree_node *cb_node = node->cl_head; 2236 struct cil_tree_node *true_node = NULL; 2237 struct cil_tree_node *false_node = NULL; 2238 struct cil_tree_node *tmp_node = NULL; 2239 cond_node_t *tmp_cond = NULL; 2240 cond_node_t *cond_node = NULL; 2241 int was_created; 2242 int swapped = CIL_FALSE; 2243 cond_av_list_t tmp_cl; 2244 2245 tmp_cond = cond_node_create(pdb, NULL); 2246 if (tmp_cond == NULL) { 2247 rc = SEPOL_ERR; 2248 cil_tree_log(node, CIL_INFO, "Failed to create sepol conditional node"); 2249 goto exit; 2250 } 2251 2252 rc = __cil_cond_expr_to_sepol_expr(pdb, cil_boolif->datum_expr, &tmp_cond->expr); 2253 if (rc != SEPOL_OK) { 2254 cil_tree_log(node, CIL_INFO, "Failed to convert CIL conditional expression to sepol expression"); 2255 goto exit; 2256 } 2257 2258 tmp_cond->true_list = &tmp_cl; 2259 2260 rc = cond_normalize_expr(pdb, tmp_cond); 2261 if (rc != SEPOL_OK) { 2262 goto exit; 2263 } 2264 2265 if (tmp_cond->false_list != NULL) { 2266 tmp_cond->true_list = NULL; 2267 swapped = CIL_TRUE; 2268 } 2269 2270 cond_node = cond_node_find(pdb, tmp_cond, pdb->cond_list, &was_created); 2271 if (cond_node == NULL) { 2272 rc = SEPOL_ERR; 2273 goto exit; 2274 } 2275 2276 if (was_created) { 2277 cond_node->next = pdb->cond_list; 2278 pdb->cond_list = cond_node; 2279 } 2280 2281 cond_expr_destroy(tmp_cond->expr); 2282 free(tmp_cond); 2283 2284 for (cb_node = node->cl_head; cb_node != NULL; cb_node = cb_node->next) { 2285 if (cb_node->flavor == CIL_CONDBLOCK) { 2286 struct cil_condblock *cb = cb_node->data; 2287 if (cb->flavor == CIL_CONDTRUE) { 2288 true_node = cb_node; 2289 } else if (cb->flavor == CIL_CONDFALSE) { 2290 false_node = cb_node; 2291 } 2292 } 2293 } 2294 2295 if (swapped) { 2296 tmp_node = true_node; 2297 true_node = false_node; 2298 false_node = tmp_node; 2299 } 2300 2301 bool_args.db = db; 2302 bool_args.pdb = pdb; 2303 bool_args.cond_node = cond_node; 2304 bool_args.filename_trans_table = filename_trans_table; 2305 2306 if (true_node != NULL) { 2307 bool_args.cond_flavor = CIL_CONDTRUE; 2308 rc = cil_tree_walk(true_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args); 2309 if (rc != SEPOL_OK) { 2310 cil_tree_log(true_node, CIL_ERR, "Failure while walking true conditional block"); 2311 goto exit; 2312 } 2313 } 2314 2315 if (false_node != NULL) { 2316 bool_args.cond_flavor = CIL_CONDFALSE; 2317 rc = cil_tree_walk(false_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args); 2318 if (rc != SEPOL_OK) { 2319 cil_tree_log(false_node, CIL_ERR, "Failure while walking false conditional block"); 2320 goto exit; 2321 } 2322 } 2323 2324 return SEPOL_OK; 2325 2326 exit: 2327 return rc; 2328 } 2329 2330 int cil_roletrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roletransition *roletrans, hashtab_t role_trans_table) 2331 { 2332 int rc = SEPOL_ERR; 2333 role_datum_t *sepol_src = NULL; 2334 type_datum_t *sepol_tgt = NULL; 2335 class_datum_t *sepol_obj = NULL; 2336 struct cil_list *class_list; 2337 role_datum_t *sepol_result = NULL; 2338 role_trans_t *new = NULL; 2339 uint32_t *new_role = NULL; 2340 ebitmap_t role_bitmap, type_bitmap; 2341 ebitmap_node_t *rnode, *tnode; 2342 unsigned int i, j; 2343 struct cil_list_item *c; 2344 2345 rc = __cil_expand_role(DATUM(roletrans->src), &role_bitmap); 2346 if (rc != SEPOL_OK) goto exit; 2347 2348 rc = __cil_expand_type(roletrans->tgt, &type_bitmap); 2349 if (rc != SEPOL_OK) goto exit; 2350 2351 class_list = cil_expand_class(roletrans->obj); 2352 2353 rc = __cil_get_sepol_role_datum(pdb, DATUM(roletrans->result), &sepol_result); 2354 if (rc != SEPOL_OK) goto exit; 2355 2356 ebitmap_for_each_bit(&role_bitmap, rnode, i) { 2357 if (!ebitmap_get_bit(&role_bitmap, i)) continue; 2358 2359 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src); 2360 if (rc != SEPOL_OK) goto exit; 2361 2362 ebitmap_for_each_bit(&type_bitmap, tnode, j) { 2363 if (!ebitmap_get_bit(&type_bitmap, j)) continue; 2364 2365 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt); 2366 if (rc != SEPOL_OK) goto exit; 2367 2368 cil_list_for_each(c, class_list) { 2369 int add = CIL_TRUE; 2370 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); 2371 if (rc != SEPOL_OK) goto exit; 2372 2373 new = cil_malloc(sizeof(*new)); 2374 memset(new, 0, sizeof(*new)); 2375 new->role = sepol_src->s.value; 2376 new->type = sepol_tgt->s.value; 2377 new->tclass = sepol_obj->s.value; 2378 new->new_role = sepol_result->s.value; 2379 2380 rc = hashtab_insert(role_trans_table, (hashtab_key_t)new, &(new->new_role)); 2381 if (rc != SEPOL_OK) { 2382 if (rc == SEPOL_EEXIST) { 2383 add = CIL_FALSE; 2384 new_role = hashtab_search(role_trans_table, (hashtab_key_t)new); 2385 if (new->new_role != *new_role) { 2386 cil_log(CIL_ERR, "Conflicting role transition rules\n"); 2387 } else { 2388 rc = SEPOL_OK; 2389 } 2390 } else { 2391 cil_log(CIL_ERR, "Out of memory\n"); 2392 } 2393 } 2394 2395 if (add == CIL_TRUE) { 2396 new->next = pdb->role_tr; 2397 pdb->role_tr = new; 2398 } else { 2399 free(new); 2400 if (rc != SEPOL_OK) { 2401 goto exit; 2402 } 2403 } 2404 } 2405 } 2406 } 2407 2408 rc = SEPOL_OK; 2409 2410 exit: 2411 ebitmap_destroy(&role_bitmap); 2412 ebitmap_destroy(&type_bitmap); 2413 cil_list_destroy(&class_list, CIL_FALSE); 2414 return rc; 2415 } 2416 2417 int cil_roleallow_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roleallow *roleallow) 2418 { 2419 int rc = SEPOL_ERR; 2420 role_datum_t *sepol_src = NULL; 2421 role_datum_t *sepol_tgt = NULL; 2422 role_allow_t *sepol_roleallow = NULL; 2423 ebitmap_t src_bitmap, tgt_bitmap; 2424 ebitmap_node_t *node1, *node2; 2425 unsigned int i, j; 2426 2427 rc = __cil_expand_role(roleallow->src, &src_bitmap); 2428 if (rc != SEPOL_OK) goto exit; 2429 2430 rc = __cil_expand_role(roleallow->tgt, &tgt_bitmap); 2431 if (rc != SEPOL_OK) goto exit; 2432 2433 ebitmap_for_each_bit(&src_bitmap, node1, i) { 2434 if (!ebitmap_get_bit(&src_bitmap, i)) continue; 2435 2436 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src); 2437 if (rc != SEPOL_OK) goto exit; 2438 2439 ebitmap_for_each_bit(&tgt_bitmap, node2, j) { 2440 if (!ebitmap_get_bit(&tgt_bitmap, j)) continue; 2441 2442 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[j]), &sepol_tgt); 2443 if (rc != SEPOL_OK) goto exit; 2444 2445 sepol_roleallow = cil_malloc(sizeof(*sepol_roleallow)); 2446 memset(sepol_roleallow, 0, sizeof(role_allow_t)); 2447 sepol_roleallow->role = sepol_src->s.value; 2448 sepol_roleallow->new_role = sepol_tgt->s.value; 2449 2450 sepol_roleallow->next = pdb->role_allow; 2451 pdb->role_allow = sepol_roleallow; 2452 } 2453 } 2454 2455 rc = SEPOL_OK; 2456 2457 exit: 2458 ebitmap_destroy(&src_bitmap); 2459 ebitmap_destroy(&tgt_bitmap); 2460 return rc; 2461 } 2462 2463 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) 2464 { 2465 int rc = SEPOL_ERR; 2466 2467 if (expr_flavor == CIL_USER) { 2468 user_datum_t *sepol_user = NULL; 2469 ebitmap_t user_bitmap; 2470 ebitmap_node_t *unode; 2471 unsigned int i; 2472 2473 rc = __cil_expand_user(item->data, &user_bitmap); 2474 if (rc != SEPOL_OK) goto exit; 2475 2476 ebitmap_for_each_bit(&user_bitmap, unode, i) { 2477 if (!ebitmap_get_bit(&user_bitmap, i)) { 2478 continue; 2479 } 2480 2481 rc = __cil_get_sepol_user_datum(pdb, DATUM(db->val_to_user[i]), &sepol_user); 2482 if (rc != SEPOL_OK) { 2483 ebitmap_destroy(&user_bitmap); 2484 goto exit; 2485 } 2486 2487 if (ebitmap_set_bit(&expr->names, sepol_user->s.value - 1, 1)) { 2488 ebitmap_destroy(&user_bitmap); 2489 goto exit; 2490 } 2491 } 2492 ebitmap_destroy(&user_bitmap); 2493 } else if (expr_flavor == CIL_ROLE) { 2494 role_datum_t *sepol_role = NULL; 2495 ebitmap_t role_bitmap; 2496 ebitmap_node_t *rnode; 2497 unsigned int i; 2498 2499 rc = __cil_expand_role(item->data, &role_bitmap); 2500 if (rc != SEPOL_OK) goto exit; 2501 2502 ebitmap_for_each_bit(&role_bitmap, rnode, i) { 2503 if (!ebitmap_get_bit(&role_bitmap, i)) continue; 2504 2505 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role); 2506 if (rc != SEPOL_OK) { 2507 ebitmap_destroy(&role_bitmap); 2508 goto exit; 2509 } 2510 2511 if (ebitmap_set_bit(&expr->names, sepol_role->s.value - 1, 1)) { 2512 ebitmap_destroy(&role_bitmap); 2513 goto exit; 2514 } 2515 } 2516 ebitmap_destroy(&role_bitmap); 2517 } else if (expr_flavor == CIL_TYPE) { 2518 type_datum_t *sepol_type = NULL; 2519 ebitmap_t type_bitmap; 2520 ebitmap_node_t *tnode; 2521 unsigned int i; 2522 2523 if (pdb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) { 2524 rc = __cil_get_sepol_type_datum(pdb, item->data, &sepol_type); 2525 if (rc != SEPOL_OK) { 2526 if (FLAVOR(item->data) == CIL_TYPEATTRIBUTE) { 2527 struct cil_typeattribute *attr = item->data; 2528 if (!attr->used) { 2529 rc = 0; 2530 } 2531 } 2532 } 2533 2534 if (sepol_type) { 2535 rc = ebitmap_set_bit(&expr->type_names->types, sepol_type->s.value - 1, 1); 2536 } 2537 2538 if (rc != SEPOL_OK) { 2539 goto exit; 2540 } 2541 } 2542 2543 rc = __cil_expand_type(item->data, &type_bitmap); 2544 if (rc != SEPOL_OK) goto exit; 2545 2546 ebitmap_for_each_bit(&type_bitmap, tnode, i) { 2547 if (!ebitmap_get_bit(&type_bitmap, i)) continue; 2548 2549 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type); 2550 if (rc != SEPOL_OK) { 2551 ebitmap_destroy(&type_bitmap); 2552 goto exit; 2553 } 2554 2555 if (ebitmap_set_bit(&expr->names, sepol_type->s.value - 1, 1)) { 2556 ebitmap_destroy(&type_bitmap); 2557 goto exit; 2558 } 2559 } 2560 ebitmap_destroy(&type_bitmap); 2561 } else { 2562 goto exit; 2563 } 2564 2565 return SEPOL_OK; 2566 2567 exit: 2568 return SEPOL_ERR; 2569 } 2570 2571 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) 2572 { 2573 int rc = SEPOL_ERR; 2574 struct cil_list_item *l_item = op_item->next; 2575 struct cil_list_item *r_item = op_item->next->next; 2576 2577 enum cil_flavor l_operand = (enum cil_flavor)l_item->data; 2578 2579 switch (l_operand) { 2580 case CIL_CONS_U1: 2581 expr->attr = CEXPR_USER; 2582 break; 2583 case CIL_CONS_U2: 2584 expr->attr = CEXPR_USER | CEXPR_TARGET; 2585 break; 2586 case CIL_CONS_U3: 2587 expr->attr = CEXPR_USER | CEXPR_XTARGET; 2588 break; 2589 case CIL_CONS_R1: 2590 expr->attr = CEXPR_ROLE; 2591 break; 2592 case CIL_CONS_R2: 2593 expr->attr = CEXPR_ROLE | CEXPR_TARGET; 2594 break; 2595 case CIL_CONS_R3: 2596 expr->attr = CEXPR_ROLE | CEXPR_XTARGET; 2597 break; 2598 case CIL_CONS_T1: 2599 expr->attr = CEXPR_TYPE; 2600 break; 2601 case CIL_CONS_T2: 2602 expr->attr = CEXPR_TYPE | CEXPR_TARGET; 2603 break; 2604 case CIL_CONS_T3: 2605 expr->attr = CEXPR_TYPE | CEXPR_XTARGET; 2606 break; 2607 case CIL_CONS_L1: { 2608 enum cil_flavor r_operand = (enum cil_flavor)r_item->data; 2609 2610 if (r_operand == CIL_CONS_L2) { 2611 expr->attr = CEXPR_L1L2; 2612 } else if (r_operand == CIL_CONS_H1) { 2613 expr->attr = CEXPR_L1H1; 2614 } else { 2615 expr->attr = CEXPR_L1H2; 2616 } 2617 break; 2618 } 2619 case CIL_CONS_L2: 2620 expr->attr = CEXPR_L2H2; 2621 break; 2622 case CIL_CONS_H1: { 2623 enum cil_flavor r_operand = (enum cil_flavor)r_item->data; 2624 if (r_operand == CIL_CONS_L2) { 2625 expr->attr = CEXPR_H1L2; 2626 } else { 2627 expr->attr = CEXPR_H1H2; 2628 } 2629 break; 2630 } 2631 default: 2632 goto exit; 2633 break; 2634 } 2635 2636 if (r_item->flavor == CIL_CONS_OPERAND) { 2637 expr->expr_type = CEXPR_ATTR; 2638 } else { 2639 expr->expr_type = CEXPR_NAMES; 2640 if (r_item->flavor == CIL_DATUM) { 2641 rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, r_item, expr_flavor, expr); 2642 if (rc != SEPOL_OK) { 2643 goto exit; 2644 } 2645 } else if (r_item->flavor == CIL_LIST) { 2646 struct cil_list *r_expr = r_item->data; 2647 struct cil_list_item *curr; 2648 cil_list_for_each(curr, r_expr) { 2649 rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, curr, expr_flavor, expr); 2650 if (rc != SEPOL_OK) { 2651 goto exit; 2652 } 2653 } 2654 } else { 2655 rc = SEPOL_ERR; 2656 goto exit; 2657 } 2658 } 2659 2660 return SEPOL_OK; 2661 2662 exit: 2663 return rc; 2664 } 2665 2666 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) 2667 { 2668 int rc = SEPOL_ERR; 2669 struct cil_list_item *item; 2670 enum cil_flavor flavor; 2671 constraint_expr_t *op, *h1, *h2, *t1, *t2; 2672 int is_leaf = CIL_FALSE; 2673 2674 if (cil_expr == NULL) { 2675 return SEPOL_ERR; 2676 } 2677 2678 item = cil_expr->head; 2679 flavor = cil_expr->flavor; 2680 2681 op = cil_malloc(sizeof(constraint_expr_t)); 2682 rc = constraint_expr_init(op); 2683 if (rc != SEPOL_OK) { 2684 goto exit; 2685 } 2686 2687 enum cil_flavor cil_op = (enum cil_flavor)item->data; 2688 switch (cil_op) { 2689 case CIL_NOT: 2690 op->expr_type = CEXPR_NOT; 2691 break; 2692 case CIL_AND: 2693 op->expr_type = CEXPR_AND; 2694 break; 2695 case CIL_OR: 2696 op->expr_type = CEXPR_OR; 2697 break; 2698 case CIL_EQ: 2699 op->op = CEXPR_EQ; 2700 is_leaf = CIL_TRUE; 2701 break; 2702 case CIL_NEQ: 2703 op->op = CEXPR_NEQ; 2704 is_leaf = CIL_TRUE; 2705 break; 2706 case CIL_CONS_DOM: 2707 op->op = CEXPR_DOM; 2708 is_leaf = CIL_TRUE; 2709 break; 2710 case CIL_CONS_DOMBY: 2711 op->op = CEXPR_DOMBY; 2712 is_leaf = CIL_TRUE; 2713 break; 2714 case CIL_CONS_INCOMP: 2715 op->op = CEXPR_INCOMP; 2716 is_leaf = CIL_TRUE; 2717 break; 2718 default: 2719 goto exit; 2720 } 2721 2722 if (is_leaf == CIL_TRUE) { 2723 rc = __cil_constrain_expr_leaf_to_sepol_expr(pdb, db, item, flavor, op); 2724 if (rc != SEPOL_OK) { 2725 goto exit; 2726 } 2727 *head = op; 2728 *tail = op; 2729 } else if (cil_op == CIL_NOT) { 2730 struct cil_list *l_expr = item->next->data; 2731 rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1); 2732 if (rc != SEPOL_OK) { 2733 goto exit; 2734 } 2735 t1->next = op; 2736 *head = h1; 2737 *tail = op; 2738 } else { 2739 struct cil_list *l_expr = item->next->data; 2740 struct cil_list *r_expr = item->next->next->data; 2741 rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1); 2742 if (rc != SEPOL_OK) { 2743 goto exit; 2744 } 2745 rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, r_expr, &h2, &t2); 2746 if (rc != SEPOL_OK) { 2747 constraint_expr_destroy(h1); 2748 goto exit; 2749 } 2750 t1->next = h2; 2751 t2->next = op; 2752 *head = h1; 2753 *tail = op; 2754 } 2755 2756 return SEPOL_OK; 2757 2758 exit: 2759 constraint_expr_destroy(op); 2760 return SEPOL_ERR; 2761 } 2762 2763 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) 2764 { 2765 int rc; 2766 constraint_expr_t *head, *tail; 2767 2768 rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, cil_expr, &head, &tail); 2769 if (rc != SEPOL_OK) { 2770 return SEPOL_ERR; 2771 } 2772 2773 *sepol_expr = head; 2774 2775 return SEPOL_OK; 2776 } 2777 2778 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) 2779 { 2780 int rc = SEPOL_ERR; 2781 constraint_node_t *sepol_constrain = NULL; 2782 constraint_expr_t *sepol_expr = NULL; 2783 class_datum_t *sepol_class = NULL; 2784 2785 sepol_constrain = cil_malloc(sizeof(*sepol_constrain)); 2786 memset(sepol_constrain, 0, sizeof(constraint_node_t)); 2787 2788 rc = __cil_get_sepol_class_datum(pdb, class, &sepol_class); 2789 if (rc != SEPOL_OK) goto exit; 2790 2791 rc = __cil_perms_to_datum(perms, sepol_class, &sepol_constrain->permissions); 2792 if (rc != SEPOL_OK) { 2793 goto exit; 2794 } 2795 2796 rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr); 2797 if (rc != SEPOL_OK) { 2798 goto exit; 2799 } 2800 2801 sepol_constrain->expr = sepol_expr; 2802 sepol_constrain->next = sepol_class->constraints; 2803 sepol_class->constraints = sepol_constrain; 2804 2805 return SEPOL_OK; 2806 2807 exit: 2808 free(sepol_constrain); 2809 return rc; 2810 } 2811 2812 int cil_constrain_expand(policydb_t *pdb, const struct cil_db *db, struct cil_list *classperms, struct cil_list *expr) 2813 { 2814 int rc = SEPOL_ERR; 2815 struct cil_list_item *curr; 2816 2817 cil_list_for_each(curr, classperms) { 2818 if (curr->flavor == CIL_CLASSPERMS) { 2819 struct cil_classperms *cp = curr->data; 2820 if (FLAVOR(cp->class) == CIL_CLASS) { 2821 rc = cil_constrain_to_policydb_helper(pdb, db, DATUM(cp->class), cp->perms, expr); 2822 if (rc != SEPOL_OK) { 2823 goto exit; 2824 } 2825 } else { /* MAP */ 2826 struct cil_list_item *i = NULL; 2827 cil_list_for_each(i, cp->perms) { 2828 struct cil_perm *cmp = i->data; 2829 rc = cil_constrain_expand(pdb, db, cmp->classperms, expr); 2830 if (rc != SEPOL_OK) { 2831 goto exit; 2832 } 2833 } 2834 } 2835 } else { /* SET */ 2836 struct cil_classperms_set *cp_set = curr->data; 2837 struct cil_classpermission *cp = cp_set->set; 2838 rc = cil_constrain_expand(pdb, db, cp->classperms, expr); 2839 if (rc != SEPOL_OK) { 2840 goto exit; 2841 } 2842 } 2843 } 2844 2845 return SEPOL_OK; 2846 2847 exit: 2848 return rc; 2849 } 2850 2851 int cil_constrain_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_constrain *cil_constrain) 2852 { 2853 int rc = SEPOL_ERR; 2854 rc = cil_constrain_expand(pdb, db, cil_constrain->classperms, cil_constrain->datum_expr); 2855 if (rc != SEPOL_OK) { 2856 goto exit; 2857 } 2858 2859 return SEPOL_OK; 2860 2861 exit: 2862 cil_log(CIL_ERR, "Failed to insert constraint into policydb\n"); 2863 return rc; 2864 } 2865 2866 int cil_validatetrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_validatetrans *cil_validatetrans) 2867 { 2868 int rc = SEPOL_ERR; 2869 struct cil_list *expr = cil_validatetrans->datum_expr; 2870 class_datum_t *sepol_class = NULL; 2871 struct cil_list *class_list; 2872 constraint_node_t *sepol_validatetrans = NULL; 2873 constraint_expr_t *sepol_expr = NULL; 2874 struct cil_list_item *c; 2875 2876 class_list = cil_expand_class(cil_validatetrans->class); 2877 2878 cil_list_for_each(c, class_list) { 2879 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); 2880 if (rc != SEPOL_OK) goto exit; 2881 2882 sepol_validatetrans = cil_malloc(sizeof(*sepol_validatetrans)); 2883 memset(sepol_validatetrans, 0, sizeof(constraint_node_t)); 2884 2885 rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr); 2886 if (rc != SEPOL_OK) { 2887 free(sepol_validatetrans); 2888 goto exit; 2889 } 2890 sepol_validatetrans->expr = sepol_expr; 2891 2892 sepol_validatetrans->next = sepol_class->validatetrans; 2893 sepol_class->validatetrans = sepol_validatetrans; 2894 } 2895 2896 rc = SEPOL_OK; 2897 2898 exit: 2899 cil_list_destroy(&class_list, CIL_FALSE); 2900 return rc; 2901 } 2902 2903 int __cil_cats_to_mls_level(policydb_t *pdb, struct cil_cats *cats, mls_level_t *mls_level) 2904 { 2905 int rc = SEPOL_ERR; 2906 struct cil_list_item *i; 2907 cat_datum_t *sepol_cat = NULL; 2908 2909 cil_list_for_each(i, cats->datum_expr) { 2910 struct cil_tree_node *node = DATUM(i->data)->nodes->head->data; 2911 if (node->flavor == CIL_CATSET) { 2912 struct cil_list_item *j; 2913 struct cil_catset *cs = i->data; 2914 cil_list_for_each(j, cs->cats->datum_expr) { 2915 rc = __cil_get_sepol_cat_datum(pdb, j->data, &sepol_cat); 2916 if (rc != SEPOL_OK) goto exit; 2917 2918 rc = ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1); 2919 if (rc != SEPOL_OK) goto exit; 2920 } 2921 } else { 2922 rc = __cil_get_sepol_cat_datum(pdb, i->data, &sepol_cat); 2923 if (rc != SEPOL_OK) goto exit; 2924 2925 rc = ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1); 2926 if (rc != SEPOL_OK) goto exit; 2927 } 2928 } 2929 2930 return SEPOL_OK; 2931 2932 exit: 2933 return SEPOL_ERR; 2934 } 2935 2936 int cil_sepol_level_define(policydb_t *pdb, struct cil_sens *cil_sens) 2937 { 2938 int rc = SEPOL_ERR; 2939 struct cil_list_item *curr; 2940 level_datum_t *sepol_level = NULL; 2941 mls_level_t *mls_level = NULL; 2942 2943 rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level); 2944 if (rc != SEPOL_OK) goto exit; 2945 2946 mls_level = sepol_level->level; 2947 2948 ebitmap_init(&mls_level->cat); 2949 2950 if (cil_sens->cats_list) { 2951 cil_list_for_each(curr, cil_sens->cats_list) { 2952 struct cil_cats *cats = curr->data; 2953 rc = __cil_cats_to_mls_level(pdb, cats, mls_level); 2954 if (rc != SEPOL_OK) { 2955 cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n"); 2956 goto exit; 2957 } 2958 } 2959 } 2960 2961 sepol_level->defined = 1; 2962 2963 return SEPOL_OK; 2964 2965 exit: 2966 return rc; 2967 } 2968 2969 int cil_level_to_mls_level(policydb_t *pdb, struct cil_level *cil_level, mls_level_t *mls_level) 2970 { 2971 int rc = SEPOL_ERR; 2972 struct cil_sens *cil_sens = cil_level->sens; 2973 struct cil_cats *cats = cil_level->cats; 2974 level_datum_t *sepol_level = NULL; 2975 2976 rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level); 2977 if (rc != SEPOL_OK) goto exit; 2978 2979 mls_level->sens = sepol_level->level->sens; 2980 2981 ebitmap_init(&mls_level->cat); 2982 2983 if (cats != NULL) { 2984 rc = __cil_cats_to_mls_level(pdb, cats, mls_level); 2985 if (rc != SEPOL_OK) { 2986 cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n"); 2987 goto exit; 2988 } 2989 } 2990 2991 rc = SEPOL_OK; 2992 exit: 2993 return rc; 2994 } 2995 2996 int __cil_levelrange_to_mls_range(policydb_t *pdb, struct cil_levelrange *cil_lvlrange, mls_range_t *mls_range) 2997 { 2998 int rc = SEPOL_ERR; 2999 struct cil_level *low = cil_lvlrange->low; 3000 struct cil_level *high = cil_lvlrange->high; 3001 mls_level_t *mls_level = NULL; 3002 3003 mls_level = &mls_range->level[0]; 3004 3005 rc = cil_level_to_mls_level(pdb, low, mls_level); 3006 if (rc != SEPOL_OK) { 3007 goto exit; 3008 } 3009 3010 mls_level = &mls_range->level[1]; 3011 3012 rc = cil_level_to_mls_level(pdb, high, mls_level); 3013 if (rc != SEPOL_OK) { 3014 goto exit; 3015 } 3016 3017 return SEPOL_OK; 3018 3019 exit: 3020 return rc; 3021 } 3022 3023 int cil_userlevel_userrange_to_policydb(policydb_t *pdb, struct cil_user *cil_user) 3024 { 3025 int rc = SEPOL_ERR; 3026 struct cil_level *cil_level = cil_user->dftlevel; 3027 struct cil_levelrange *cil_levelrange = cil_user->range; 3028 user_datum_t *sepol_user = NULL; 3029 3030 rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user); 3031 if (rc != SEPOL_OK) goto exit; 3032 3033 rc = cil_level_to_mls_level(pdb, cil_level, &sepol_user->exp_dfltlevel); 3034 if (rc != SEPOL_OK) { 3035 goto exit; 3036 } 3037 3038 rc = __cil_levelrange_to_mls_range(pdb, cil_levelrange, &sepol_user->exp_range); 3039 if (rc != SEPOL_OK) { 3040 goto exit; 3041 } 3042 3043 return SEPOL_OK; 3044 3045 exit: 3046 return rc; 3047 } 3048 3049 int __cil_context_to_sepol_context(policydb_t *pdb, struct cil_context *cil_context, context_struct_t *sepol_context) 3050 { 3051 int rc = SEPOL_ERR; 3052 struct cil_levelrange *cil_lvlrange = cil_context->range; 3053 user_datum_t *sepol_user = NULL; 3054 role_datum_t *sepol_role = NULL; 3055 type_datum_t *sepol_type = NULL; 3056 3057 rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_context->user), &sepol_user); 3058 if (rc != SEPOL_OK) goto exit; 3059 3060 rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_context->role), &sepol_role); 3061 if (rc != SEPOL_OK) goto exit; 3062 3063 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_context->type), &sepol_type); 3064 if (rc != SEPOL_OK) goto exit; 3065 3066 sepol_context->user = sepol_user->s.value; 3067 sepol_context->role = sepol_role->s.value; 3068 sepol_context->type = sepol_type->s.value; 3069 3070 if (pdb->mls == CIL_TRUE) { 3071 mls_context_init(sepol_context); 3072 3073 rc = __cil_levelrange_to_mls_range(pdb, cil_lvlrange, &sepol_context->range); 3074 if (rc != SEPOL_OK) { 3075 cil_log(CIL_ERR,"Problem with MLS\n"); 3076 mls_context_destroy(sepol_context); 3077 goto exit; 3078 } 3079 } 3080 3081 return SEPOL_OK; 3082 3083 exit: 3084 return rc; 3085 } 3086 3087 int cil_sidorder_to_policydb(policydb_t *pdb, const struct cil_db *db) 3088 { 3089 int rc = SEPOL_ERR; 3090 struct cil_list_item *curr; 3091 unsigned count = 0; 3092 ocontext_t *tail = NULL; 3093 3094 if (db->sidorder == NULL || db->sidorder->head == NULL) { 3095 cil_log(CIL_WARN, "No sidorder statement in policy\n"); 3096 return SEPOL_OK; 3097 } 3098 3099 cil_list_for_each(curr, db->sidorder) { 3100 struct cil_sid *cil_sid = (struct cil_sid*)curr->data; 3101 struct cil_context *cil_context = cil_sid->context; 3102 3103 if (cil_context != NULL) { 3104 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_ISID], &tail); 3105 count++; 3106 new_ocon->sid[0] = count; 3107 new_ocon->u.name = cil_strdup(cil_sid->datum.fqn); 3108 rc = __cil_context_to_sepol_context(pdb, cil_context, &new_ocon->context[0]); 3109 if (rc != SEPOL_OK) { 3110 cil_log(CIL_ERR,"Problem with context for SID %s\n",cil_sid->datum.fqn); 3111 goto exit; 3112 } 3113 } 3114 } 3115 3116 return SEPOL_OK; 3117 3118 exit: 3119 return rc; 3120 } 3121 3122 int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans, hashtab_t range_trans_table) 3123 { 3124 int rc = SEPOL_ERR; 3125 type_datum_t *sepol_src = NULL; 3126 type_datum_t *sepol_tgt = NULL; 3127 class_datum_t *sepol_class = NULL; 3128 struct cil_list *class_list; 3129 range_trans_t *newkey = NULL; 3130 struct mls_range *newdatum = NULL; 3131 ebitmap_t src_bitmap, tgt_bitmap; 3132 ebitmap_node_t *node1, *node2; 3133 unsigned int i, j; 3134 struct cil_list_item *c; 3135 struct mls_range *o_range = NULL; 3136 3137 rc = __cil_expand_type(rangetrans->src, &src_bitmap); 3138 if (rc != SEPOL_OK) goto exit; 3139 3140 rc = __cil_expand_type(rangetrans->exec, &tgt_bitmap); 3141 if (rc != SEPOL_OK) goto exit; 3142 3143 class_list = cil_expand_class(rangetrans->obj); 3144 3145 ebitmap_for_each_bit(&src_bitmap, node1, i) { 3146 if (!ebitmap_get_bit(&src_bitmap, i)) continue; 3147 3148 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src); 3149 if (rc != SEPOL_OK) goto exit; 3150 3151 ebitmap_for_each_bit(&tgt_bitmap, node2, j) { 3152 if (!ebitmap_get_bit(&tgt_bitmap, j)) continue; 3153 3154 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt); 3155 if (rc != SEPOL_OK) goto exit; 3156 3157 cil_list_for_each(c, class_list) { 3158 int add = CIL_TRUE; 3159 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); 3160 if (rc != SEPOL_OK) goto exit; 3161 3162 newkey = cil_calloc(1, sizeof(*newkey)); 3163 newdatum = cil_calloc(1, sizeof(*newdatum)); 3164 newkey->source_type = sepol_src->s.value; 3165 newkey->target_type = sepol_tgt->s.value; 3166 newkey->target_class = sepol_class->s.value; 3167 rc = __cil_levelrange_to_mls_range(pdb, rangetrans->range, newdatum); 3168 if (rc != SEPOL_OK) { 3169 free(newkey); 3170 free(newdatum); 3171 goto exit; 3172 } 3173 3174 rc = hashtab_insert(range_trans_table, (hashtab_key_t)newkey, newdatum); 3175 if (rc != SEPOL_OK) { 3176 if (rc == SEPOL_EEXIST) { 3177 add = CIL_FALSE; 3178 o_range = hashtab_search(range_trans_table, (hashtab_key_t)newkey); 3179 if (!mls_range_eq(newdatum, o_range)) { 3180 cil_log(CIL_ERR, "Conflicting Range transition rules\n"); 3181 } else { 3182 rc = SEPOL_OK; 3183 } 3184 } else { 3185 cil_log(CIL_ERR, "Out of memory\n"); 3186 } 3187 } 3188 3189 if (add == CIL_TRUE) { 3190 rc = hashtab_insert(pdb->range_tr, 3191 (hashtab_key_t)newkey, 3192 newdatum); 3193 if (rc != SEPOL_OK) { 3194 mls_range_destroy(newdatum); 3195 free(newdatum); 3196 free(newkey); 3197 cil_log(CIL_ERR, "Out of memory\n"); 3198 goto exit; 3199 } 3200 } else { 3201 mls_range_destroy(newdatum); 3202 free(newdatum); 3203 free(newkey); 3204 if (rc != SEPOL_OK) { 3205 goto exit; 3206 } 3207 } 3208 } 3209 } 3210 } 3211 3212 rc = SEPOL_OK; 3213 3214 exit: 3215 ebitmap_destroy(&src_bitmap); 3216 ebitmap_destroy(&tgt_bitmap); 3217 cil_list_destroy(&class_list, CIL_FALSE); 3218 return rc; 3219 } 3220 3221 int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons) 3222 { 3223 int rc = SEPOL_ERR; 3224 uint32_t i = 0; 3225 ocontext_t *tail = NULL; 3226 3227 for (i = 0; i < portcons->count; i++) { 3228 struct cil_portcon *cil_portcon = portcons->array[i]; 3229 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_PORT], &tail); 3230 3231 switch (cil_portcon->proto) { 3232 case CIL_PROTOCOL_UDP: 3233 new_ocon->u.port.protocol = IPPROTO_UDP; 3234 break; 3235 case CIL_PROTOCOL_TCP: 3236 new_ocon->u.port.protocol = IPPROTO_TCP; 3237 break; 3238 case CIL_PROTOCOL_DCCP: 3239 new_ocon->u.port.protocol = IPPROTO_DCCP; 3240 break; 3241 default: 3242 /* should not get here */ 3243 rc = SEPOL_ERR; 3244 goto exit; 3245 } 3246 3247 new_ocon->u.port.low_port = cil_portcon->port_low; 3248 new_ocon->u.port.high_port = cil_portcon->port_high; 3249 3250 rc = __cil_context_to_sepol_context(pdb, cil_portcon->context, &new_ocon->context[0]); 3251 if (rc != SEPOL_OK) { 3252 goto exit; 3253 } 3254 } 3255 3256 return SEPOL_OK; 3257 3258 exit: 3259 return rc; 3260 } 3261 3262 int cil_netifcon_to_policydb(policydb_t *pdb, struct cil_sort *netifcons) 3263 { 3264 int rc = SEPOL_ERR; 3265 uint32_t i = 0; 3266 ocontext_t *tail = NULL; 3267 3268 for (i = 0; i < netifcons->count; i++) { 3269 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NETIF], &tail); 3270 struct cil_netifcon *cil_netifcon = netifcons->array[i]; 3271 3272 new_ocon->u.name = cil_strdup(cil_netifcon->interface_str); 3273 3274 rc = __cil_context_to_sepol_context(pdb, cil_netifcon->if_context, &new_ocon->context[0]); 3275 if (rc != SEPOL_OK) { 3276 goto exit; 3277 } 3278 3279 rc = __cil_context_to_sepol_context(pdb, cil_netifcon->packet_context, &new_ocon->context[1]); 3280 if (rc != SEPOL_OK) { 3281 context_destroy(&new_ocon->context[0]); 3282 goto exit; 3283 } 3284 } 3285 3286 return SEPOL_OK; 3287 3288 exit: 3289 return rc; 3290 } 3291 3292 int cil_nodecon_to_policydb(policydb_t *pdb, struct cil_sort *nodecons) 3293 { 3294 int rc = SEPOL_ERR; 3295 uint32_t i = 0; 3296 ocontext_t *tail = NULL; 3297 ocontext_t *tail6 = NULL; 3298 3299 for (i = 0; i < nodecons->count; i++) { 3300 ocontext_t *new_ocon = NULL; 3301 struct cil_nodecon *cil_nodecon = nodecons->array[i]; 3302 3303 if (cil_nodecon->addr->family == AF_INET) { 3304 new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE], &tail); 3305 new_ocon->u.node.addr = cil_nodecon->addr->ip.v4.s_addr; 3306 new_ocon->u.node.mask = cil_nodecon->mask->ip.v4.s_addr; 3307 } else if (cil_nodecon->addr->family == AF_INET6) { 3308 new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE6], &tail6); 3309 memcpy(new_ocon->u.node6.addr, &cil_nodecon->addr->ip.v6.s6_addr[0], 16); 3310 memcpy(new_ocon->u.node6.mask, &cil_nodecon->mask->ip.v6.s6_addr[0], 16); 3311 } else { 3312 /* should not get here */ 3313 rc = SEPOL_ERR; 3314 goto exit; 3315 } 3316 3317 rc = __cil_context_to_sepol_context(pdb, cil_nodecon->context, &new_ocon->context[0]); 3318 if (rc != SEPOL_OK) { 3319 goto exit; 3320 } 3321 } 3322 3323 return SEPOL_OK; 3324 3325 exit: 3326 return rc; 3327 } 3328 3329 int cil_fsuse_to_policydb(policydb_t *pdb, struct cil_sort *fsuses) 3330 { 3331 int rc = SEPOL_ERR; 3332 uint32_t i = 0; 3333 ocontext_t *tail = NULL; 3334 3335 for (i = 0; i < fsuses->count; i++) { 3336 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_FSUSE], &tail); 3337 struct cil_fsuse *cil_fsuse = fsuses->array[i]; 3338 3339 new_ocon->u.name = cil_strdup(cil_fsuse->fs_str); 3340 new_ocon->v.behavior = cil_fsuse->type; 3341 3342 rc = __cil_context_to_sepol_context(pdb, cil_fsuse->context, &new_ocon->context[0]); 3343 if (rc != SEPOL_OK) { 3344 goto exit; 3345 } 3346 } 3347 3348 return SEPOL_OK; 3349 3350 exit: 3351 return rc; 3352 } 3353 3354 int cil_genfscon_to_policydb(policydb_t *pdb, struct cil_sort *genfscons) 3355 { 3356 int rc = SEPOL_ERR; 3357 uint32_t i = 0; 3358 genfs_t *genfs_tail = NULL; 3359 ocontext_t *ocon_tail = NULL; 3360 3361 for (i = 0; i < genfscons->count; i++) { 3362 struct cil_genfscon *cil_genfscon = genfscons->array[i]; 3363 ocontext_t *new_ocon = cil_malloc(sizeof(ocontext_t)); 3364 memset(new_ocon, 0, sizeof(ocontext_t)); 3365 3366 if (genfs_tail && strcmp(genfs_tail->fstype, cil_genfscon->fs_str) == 0) { 3367 ocon_tail->next = new_ocon; 3368 } else { 3369 genfs_t *new_genfs = cil_malloc(sizeof(genfs_t)); 3370 memset(new_genfs, 0, sizeof(genfs_t)); 3371 new_genfs->fstype = cil_strdup(cil_genfscon->fs_str); 3372 new_genfs->head = new_ocon; 3373 3374 if (genfs_tail) { 3375 genfs_tail->next = new_genfs; 3376 } else { 3377 pdb->genfs = new_genfs; 3378 } 3379 genfs_tail = new_genfs; 3380 } 3381 3382 ocon_tail = new_ocon; 3383 3384 new_ocon->u.name = cil_strdup(cil_genfscon->path_str); 3385 3386 rc = __cil_context_to_sepol_context(pdb, cil_genfscon->context, &new_ocon->context[0]); 3387 if (rc != SEPOL_OK) { 3388 goto exit; 3389 } 3390 } 3391 3392 return SEPOL_OK; 3393 3394 exit: 3395 return rc; 3396 } 3397 3398 int cil_pirqcon_to_policydb(policydb_t *pdb, struct cil_sort *pirqcons) 3399 { 3400 int rc = SEPOL_ERR; 3401 uint32_t i = 0; 3402 ocontext_t *tail = NULL; 3403 3404 for (i = 0; i < pirqcons->count; i++) { 3405 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PIRQ], &tail); 3406 struct cil_pirqcon *cil_pirqcon = pirqcons->array[i]; 3407 3408 new_ocon->u.pirq = cil_pirqcon->pirq; 3409 3410 rc = __cil_context_to_sepol_context(pdb, cil_pirqcon->context, &new_ocon->context[0]); 3411 if (rc != SEPOL_OK) { 3412 goto exit; 3413 } 3414 } 3415 3416 return SEPOL_OK; 3417 3418 exit: 3419 return rc; 3420 } 3421 3422 int cil_iomemcon_to_policydb(policydb_t *pdb, struct cil_sort *iomemcons) 3423 { 3424 int rc = SEPOL_ERR; 3425 uint32_t i = 0; 3426 ocontext_t *tail = NULL; 3427 3428 for (i = 0; i < iomemcons->count; i++) { 3429 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOMEM], &tail); 3430 struct cil_iomemcon *cil_iomemcon = iomemcons->array[i]; 3431 3432 new_ocon->u.iomem.low_iomem = cil_iomemcon->iomem_low; 3433 new_ocon->u.iomem.high_iomem = cil_iomemcon->iomem_high; 3434 3435 rc = __cil_context_to_sepol_context(pdb, cil_iomemcon->context, &new_ocon->context[0]); 3436 if (rc != SEPOL_OK) { 3437 goto exit; 3438 } 3439 } 3440 3441 return SEPOL_OK; 3442 3443 exit: 3444 return rc; 3445 } 3446 3447 int cil_ioportcon_to_policydb(policydb_t *pdb, struct cil_sort *ioportcons) 3448 { 3449 int rc = SEPOL_ERR; 3450 uint32_t i = 0; 3451 ocontext_t *tail = NULL; 3452 3453 for (i = 0; i < ioportcons->count; i++) { 3454 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOPORT], &tail); 3455 struct cil_ioportcon *cil_ioportcon = ioportcons->array[i]; 3456 3457 new_ocon->u.ioport.low_ioport = cil_ioportcon->ioport_low; 3458 new_ocon->u.ioport.high_ioport = cil_ioportcon->ioport_high; 3459 3460 rc = __cil_context_to_sepol_context(pdb, cil_ioportcon->context, &new_ocon->context[0]); 3461 if (rc != SEPOL_OK) { 3462 goto exit; 3463 } 3464 } 3465 3466 return SEPOL_OK; 3467 3468 exit: 3469 return rc; 3470 } 3471 3472 int cil_pcidevicecon_to_policydb(policydb_t *pdb, struct cil_sort *pcidevicecons) 3473 { 3474 int rc = SEPOL_ERR; 3475 uint32_t i = 0; 3476 ocontext_t *tail = NULL; 3477 3478 for (i = 0; i < pcidevicecons->count; i++) { 3479 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PCIDEVICE], &tail); 3480 struct cil_pcidevicecon *cil_pcidevicecon = pcidevicecons->array[i]; 3481 3482 new_ocon->u.device = cil_pcidevicecon->dev; 3483 3484 rc = __cil_context_to_sepol_context(pdb, cil_pcidevicecon->context, &new_ocon->context[0]); 3485 if (rc != SEPOL_OK) { 3486 goto exit; 3487 } 3488 } 3489 3490 return SEPOL_OK; 3491 3492 exit: 3493 return rc; 3494 } 3495 3496 int cil_devicetreecon_to_policydb(policydb_t *pdb, struct cil_sort *devicetreecons) 3497 { 3498 int rc = SEPOL_ERR; 3499 uint32_t i = 0; 3500 ocontext_t *tail = NULL; 3501 3502 for (i = 0; i < devicetreecons->count; i++) { 3503 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_DEVICETREE], &tail); 3504 struct cil_devicetreecon *cil_devicetreecon = devicetreecons->array[i]; 3505 3506 new_ocon->u.name = cil_strdup(cil_devicetreecon->path); 3507 3508 rc = __cil_context_to_sepol_context(pdb, cil_devicetreecon->context, &new_ocon->context[0]); 3509 if (rc != SEPOL_OK) { 3510 goto exit; 3511 } 3512 } 3513 3514 return SEPOL_OK; 3515 3516 exit: 3517 return rc; 3518 } 3519 3520 int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def) 3521 { 3522 struct cil_list_item *curr; 3523 class_datum_t *sepol_class; 3524 struct cil_list *class_list; 3525 3526 cil_list_for_each(curr, def->class_datums) { 3527 struct cil_list_item *c; 3528 3529 class_list = cil_expand_class(curr->data); 3530 3531 cil_list_for_each(c, class_list) { 3532 int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); 3533 if (rc != SEPOL_OK) goto exit; 3534 3535 switch (def->flavor) { 3536 case CIL_DEFAULTUSER: 3537 if (!sepol_class->default_user) { 3538 sepol_class->default_user = def->object; 3539 } else if (sepol_class->default_user != (char)def->object) { 3540 cil_log(CIL_ERR,"User default labeling for class %s already specified\n",DATUM(c->data)->fqn); 3541 goto exit; 3542 } 3543 break; 3544 case CIL_DEFAULTROLE: 3545 if (!sepol_class->default_role) { 3546 sepol_class->default_role = def->object; 3547 } else if (sepol_class->default_role != (char)def->object) { 3548 cil_log(CIL_ERR,"Role default labeling for class %s already specified\n",DATUM(c->data)->fqn); 3549 goto exit; 3550 } 3551 break; 3552 case CIL_DEFAULTTYPE: 3553 if (!sepol_class->default_type) { 3554 sepol_class->default_type = def->object; 3555 } else if (sepol_class->default_type != (char)def->object) { 3556 cil_log(CIL_ERR,"Type default labeling for class %s already specified\n",DATUM(c->data)->fqn); 3557 goto exit; 3558 } 3559 break; 3560 default: 3561 goto exit; 3562 } 3563 } 3564 3565 cil_list_destroy(&class_list, CIL_FALSE); 3566 } 3567 3568 return SEPOL_OK; 3569 3570 exit: 3571 cil_list_destroy(&class_list, CIL_FALSE); 3572 return SEPOL_ERR; 3573 } 3574 3575 int cil_defaultrange_to_policydb(policydb_t *pdb, struct cil_defaultrange *def) 3576 { 3577 struct cil_list_item *curr; 3578 class_datum_t *sepol_class; 3579 struct cil_list *class_list; 3580 3581 cil_list_for_each(curr, def->class_datums) { 3582 struct cil_list_item *c; 3583 3584 class_list = cil_expand_class(curr->data); 3585 3586 cil_list_for_each(c, class_list) { 3587 int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); 3588 if (rc != SEPOL_OK) goto exit; 3589 3590 if (!sepol_class->default_range) { 3591 sepol_class->default_range = def->object_range; 3592 } else if (sepol_class->default_range != (char)def->object_range) { 3593 cil_log(CIL_ERR,"Range default labeling for class %s already specified\n", DATUM(curr->data)->fqn); 3594 goto exit; 3595 } 3596 } 3597 3598 cil_list_destroy(&class_list, CIL_FALSE); 3599 } 3600 3601 return SEPOL_OK; 3602 3603 exit: 3604 cil_list_destroy(&class_list, CIL_FALSE); 3605 return SEPOL_ERR; 3606 } 3607 3608 int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args) 3609 { 3610 int rc = SEPOL_OK; 3611 int pass; 3612 struct cil_args_binary *args = extra_args; 3613 const struct cil_db *db; 3614 policydb_t *pdb; 3615 hashtab_t filename_trans_table; 3616 hashtab_t range_trans_table; 3617 hashtab_t role_trans_table; 3618 void **type_value_to_cil; 3619 3620 db = args->db; 3621 pdb = args->pdb; 3622 pass = args->pass; 3623 filename_trans_table = args->filename_trans_table; 3624 range_trans_table = args->range_trans_table; 3625 role_trans_table = args->role_trans_table; 3626 type_value_to_cil = args->type_value_to_cil; 3627 3628 if (node->flavor >= CIL_MIN_DECLARATIVE) { 3629 if (node != DATUM(node->data)->nodes->head->data) { 3630 goto exit; 3631 } 3632 } 3633 3634 switch (pass) { 3635 case 1: 3636 switch (node->flavor) { 3637 case CIL_ROLE: 3638 rc = cil_role_to_policydb(pdb, node->data); 3639 break; 3640 case CIL_TYPE: 3641 rc = cil_type_to_policydb(pdb, node->data, type_value_to_cil); 3642 break; 3643 case CIL_TYPEATTRIBUTE: 3644 rc = cil_typeattribute_to_policydb(pdb, node->data, type_value_to_cil); 3645 break; 3646 case CIL_POLICYCAP: 3647 rc = cil_policycap_to_policydb(pdb, node->data); 3648 break; 3649 case CIL_USER: 3650 rc = cil_user_to_policydb(pdb, node->data); 3651 break; 3652 case CIL_BOOL: 3653 rc = cil_bool_to_policydb(pdb, node->data); 3654 break; 3655 case CIL_CATALIAS: 3656 if (pdb->mls == CIL_TRUE) { 3657 rc = cil_catalias_to_policydb(pdb, node->data); 3658 } 3659 break; 3660 case CIL_SENS: 3661 if (pdb->mls == CIL_TRUE) { 3662 rc = cil_sepol_level_define(pdb, node->data); 3663 } 3664 break; 3665 default: 3666 break; 3667 } 3668 break; 3669 case 2: 3670 switch (node->flavor) { 3671 case CIL_TYPE: 3672 rc = cil_type_bounds_to_policydb(pdb, node->data); 3673 break; 3674 case CIL_TYPEALIAS: 3675 rc = cil_typealias_to_policydb(pdb, node->data); 3676 break; 3677 case CIL_TYPEPERMISSIVE: 3678 rc = cil_typepermissive_to_policydb(pdb, node->data); 3679 break; 3680 case CIL_TYPEATTRIBUTE: 3681 rc = cil_typeattribute_to_bitmap(pdb, db, node->data); 3682 break; 3683 case CIL_SENSALIAS: 3684 if (pdb->mls == CIL_TRUE) { 3685 rc = cil_sensalias_to_policydb(pdb, node->data); 3686 } 3687 break; 3688 case CIL_ROLE: 3689 rc = cil_role_bounds_to_policydb(pdb, node->data); 3690 if (rc != SEPOL_OK) goto exit; 3691 rc = cil_roletype_to_policydb(pdb, db, node->data); 3692 break; 3693 case CIL_USER: 3694 rc = cil_user_bounds_to_policydb(pdb, node->data); 3695 if (rc != SEPOL_OK) goto exit; 3696 if (pdb->mls == CIL_TRUE) { 3697 rc = cil_userlevel_userrange_to_policydb(pdb, node->data); 3698 if (rc != SEPOL_OK) { 3699 goto exit; 3700 } 3701 } 3702 rc = cil_userrole_to_policydb(pdb, db, node->data); 3703 break; 3704 case CIL_TYPE_RULE: 3705 rc = cil_type_rule_to_policydb(pdb, db, node->data); 3706 break; 3707 case CIL_AVRULE: 3708 case CIL_AVRULEX: { 3709 struct cil_avrule *rule = node->data; 3710 if (db->disable_neverallow != CIL_TRUE && rule->rule_kind == CIL_AVRULE_NEVERALLOW) { 3711 struct cil_list *neverallows = args->neverallows; 3712 cil_list_prepend(neverallows, CIL_LIST_ITEM, node); 3713 } 3714 break; 3715 } 3716 case CIL_ROLETRANSITION: 3717 rc = cil_roletrans_to_policydb(pdb, db, node->data, role_trans_table); 3718 break; 3719 case CIL_ROLEATTRIBUTESET: 3720 /*rc = cil_roleattributeset_to_policydb(pdb, node->data);*/ 3721 break; 3722 case CIL_NAMETYPETRANSITION: 3723 rc = cil_typetransition_to_policydb(pdb, db, node->data, filename_trans_table); 3724 break; 3725 case CIL_CONSTRAIN: 3726 rc = cil_constrain_to_policydb(pdb, db, node->data); 3727 break; 3728 case CIL_MLSCONSTRAIN: 3729 if (pdb->mls == CIL_TRUE) { 3730 rc = cil_constrain_to_policydb(pdb, db, node->data); 3731 } 3732 break; 3733 case CIL_VALIDATETRANS: 3734 rc = cil_validatetrans_to_policydb(pdb, db, node->data); 3735 break; 3736 case CIL_MLSVALIDATETRANS: 3737 if (pdb->mls == CIL_TRUE) { 3738 rc = cil_validatetrans_to_policydb(pdb, db, node->data); 3739 } 3740 break; 3741 case CIL_RANGETRANSITION: 3742 if (pdb->mls == CIL_TRUE) { 3743 rc = cil_rangetransition_to_policydb(pdb, db, node->data, range_trans_table); 3744 } 3745 break; 3746 case CIL_DEFAULTUSER: 3747 case CIL_DEFAULTROLE: 3748 case CIL_DEFAULTTYPE: 3749 rc = cil_default_to_policydb(pdb, node->data); 3750 break; 3751 case CIL_DEFAULTRANGE: 3752 rc = cil_defaultrange_to_policydb(pdb, node->data); 3753 break; 3754 default: 3755 break; 3756 } 3757 break; 3758 case 3: 3759 switch (node->flavor) { 3760 case CIL_BOOLEANIF: 3761 rc = cil_booleanif_to_policydb(pdb, db, node, filename_trans_table); 3762 break; 3763 case CIL_AVRULE: { 3764 struct cil_avrule *rule = node->data; 3765 if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) { 3766 rc = cil_avrule_to_policydb(pdb, db, node->data); 3767 } 3768 } 3769 break; 3770 case CIL_AVRULEX: { 3771 struct cil_avrule *rule = node->data; 3772 if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) { 3773 rc = cil_avrulex_to_hashtable(pdb, db, node->data, args); 3774 } 3775 } 3776 break; 3777 case CIL_ROLEALLOW: 3778 rc = cil_roleallow_to_policydb(pdb, db, node->data); 3779 break; 3780 default: 3781 break; 3782 } 3783 default: 3784 break; 3785 } 3786 3787 exit: 3788 if (rc != SEPOL_OK) { 3789 cil_tree_log(node, CIL_ERR, "Binary policy creation failed"); 3790 } 3791 return rc; 3792 } 3793 3794 int __cil_binary_create_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 3795 { 3796 int rc = SEPOL_ERR; 3797 3798 if (node->flavor == CIL_BLOCK) { 3799 struct cil_block *blk = node->data; 3800 if (blk->is_abstract == CIL_TRUE) { 3801 *finished = CIL_TREE_SKIP_HEAD; 3802 rc = SEPOL_OK; 3803 goto exit; 3804 } 3805 } else if (node->flavor == CIL_MACRO) { 3806 *finished = CIL_TREE_SKIP_HEAD; 3807 rc = SEPOL_OK; 3808 goto exit; 3809 } else if (node->flavor == CIL_BOOLEANIF) { 3810 *finished = CIL_TREE_SKIP_HEAD; 3811 } 3812 3813 rc = __cil_node_to_policydb(node, extra_args); 3814 if (rc != SEPOL_OK) { 3815 goto exit; 3816 } 3817 3818 exit: 3819 return rc; 3820 } 3821 3822 int __cil_contexts_to_policydb(policydb_t *pdb, const struct cil_db *db) 3823 { 3824 int rc = SEPOL_ERR; 3825 3826 rc = cil_portcon_to_policydb(pdb, db->portcon); 3827 if (rc != SEPOL_OK) { 3828 goto exit; 3829 } 3830 3831 rc = cil_netifcon_to_policydb(pdb, db->netifcon); 3832 if (rc != SEPOL_OK) { 3833 goto exit; 3834 } 3835 3836 rc = cil_nodecon_to_policydb(pdb, db->nodecon); 3837 if (rc != SEPOL_OK) { 3838 goto exit; 3839 } 3840 3841 rc = cil_fsuse_to_policydb(pdb, db->fsuse); 3842 if (rc != SEPOL_OK) { 3843 goto exit; 3844 } 3845 3846 rc = cil_genfscon_to_policydb(pdb, db->genfscon); 3847 if (rc != SEPOL_OK) { 3848 goto exit; 3849 } 3850 3851 if (db->target_platform == SEPOL_TARGET_XEN) { 3852 rc = cil_pirqcon_to_policydb(pdb, db->pirqcon); 3853 if (rc != SEPOL_OK) { 3854 goto exit; 3855 } 3856 3857 rc = cil_iomemcon_to_policydb(pdb, db->iomemcon); 3858 if (rc != SEPOL_OK) { 3859 goto exit; 3860 } 3861 3862 rc = cil_ioportcon_to_policydb(pdb, db->ioportcon); 3863 if (rc != SEPOL_OK) { 3864 goto exit; 3865 } 3866 3867 rc = cil_pcidevicecon_to_policydb(pdb, db->pcidevicecon); 3868 if (rc != SEPOL_OK) { 3869 goto exit; 3870 } 3871 3872 rc = cil_devicetreecon_to_policydb(pdb, db->devicetreecon); 3873 if (rc != SEPOL_OK) { 3874 goto exit; 3875 } 3876 } 3877 return SEPOL_OK; 3878 exit: 3879 return rc; 3880 } 3881 3882 int __cil_common_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3883 { 3884 policydb_t *pdb = data; 3885 common_datum_t *common = (common_datum_t *)datum; 3886 3887 if (common->s.value < 1 || common->s.value > pdb->p_commons.nprim) { 3888 return -EINVAL; 3889 } 3890 pdb->p_common_val_to_name[common->s.value - 1] = (char *)key; 3891 3892 return 0; 3893 } 3894 3895 int __cil_class_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3896 { 3897 policydb_t *pdb = data; 3898 class_datum_t *class = (class_datum_t *)datum; 3899 3900 if (class->s.value < 1 || class->s.value > pdb->p_classes.nprim) { 3901 return -EINVAL; 3902 } 3903 pdb->p_class_val_to_name[class->s.value - 1] = (char *)key; 3904 pdb->class_val_to_struct[class->s.value - 1] = class; 3905 3906 return 0; 3907 } 3908 3909 int __cil_role_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3910 { 3911 policydb_t *pdb = data; 3912 role_datum_t *role = (role_datum_t *)datum; 3913 3914 if (role->s.value < 1 || role->s.value > pdb->p_roles.nprim) { 3915 return -EINVAL; 3916 } 3917 pdb->p_role_val_to_name[role->s.value - 1] = (char *)key; 3918 pdb->role_val_to_struct[role->s.value - 1] = role; 3919 3920 return 0; 3921 } 3922 3923 int __cil_type_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3924 { 3925 policydb_t *pdb = data; 3926 type_datum_t *type = (type_datum_t *)datum; 3927 3928 if (type->s.value < 1 || type->s.value > pdb->p_types.nprim) { 3929 return -EINVAL; 3930 } 3931 pdb->p_type_val_to_name[type->s.value - 1] = (char *)key; 3932 pdb->type_val_to_struct[type->s.value - 1] = type; 3933 3934 return 0; 3935 } 3936 3937 int __cil_user_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3938 { 3939 policydb_t *pdb = data; 3940 user_datum_t *user = (user_datum_t *)datum; 3941 3942 if (user->s.value < 1 || user->s.value > pdb->p_users.nprim) { 3943 return -EINVAL; 3944 } 3945 pdb->p_user_val_to_name[user->s.value - 1] = (char *)key; 3946 pdb->user_val_to_struct[user->s.value - 1] = user; 3947 3948 return 0; 3949 } 3950 3951 int __cil_bool_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3952 { 3953 policydb_t *pdb = data; 3954 cond_bool_datum_t *bool = (cond_bool_datum_t *)datum; 3955 3956 if (bool->s.value < 1 || bool->s.value > pdb->p_bools.nprim) { 3957 return -EINVAL; 3958 } 3959 pdb->p_bool_val_to_name[bool->s.value - 1] = (char *)key; 3960 pdb->bool_val_to_struct[bool->s.value - 1] = bool; 3961 3962 return 0; 3963 } 3964 3965 int __cil_level_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3966 { 3967 policydb_t *pdb = data; 3968 level_datum_t *level = (level_datum_t *)datum; 3969 3970 if (level->level->sens < 1 || level->level->sens > pdb->p_levels.nprim) { 3971 return -EINVAL; 3972 } 3973 pdb->p_sens_val_to_name[level->level->sens - 1] = (char *)key; 3974 3975 return 0; 3976 } 3977 3978 int __cil_cat_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3979 { 3980 policydb_t *pdb = data; 3981 cat_datum_t *cat = (cat_datum_t *)datum; 3982 3983 if (cat->s.value < 1 || cat->s.value > pdb->p_cats.nprim) { 3984 return -EINVAL; 3985 } 3986 pdb->p_cat_val_to_name[cat->s.value - 1] = (char *)key; 3987 3988 return 0; 3989 } 3990 3991 int __cil_policydb_val_arrays_create(policydb_t *policydb) 3992 { 3993 int rc = SEPOL_ERR; 3994 3995 policydb->p_common_val_to_name = cil_malloc(sizeof(char *) * policydb->p_commons.nprim); 3996 rc = hashtab_map(policydb->p_commons.table, &__cil_common_val_array_insert, policydb); 3997 if (rc != SEPOL_OK) { 3998 goto exit; 3999 } 4000 4001 policydb->p_class_val_to_name = cil_malloc(sizeof(char *) * policydb->p_classes.nprim); 4002 policydb->class_val_to_struct = cil_malloc(sizeof(class_datum_t *) * policydb->p_classes.nprim); 4003 rc = hashtab_map(policydb->p_classes.table, &__cil_class_val_array_insert, policydb); 4004 if (rc != SEPOL_OK) { 4005 goto exit; 4006 } 4007 4008 policydb->p_role_val_to_name = cil_malloc(sizeof(char *) * policydb->p_roles.nprim); 4009 policydb->role_val_to_struct = cil_malloc(sizeof(role_datum_t *) * policydb->p_roles.nprim); 4010 rc = hashtab_map(policydb->p_roles.table, &__cil_role_val_array_insert, policydb); 4011 if (rc != SEPOL_OK) { 4012 goto exit; 4013 } 4014 4015 policydb->p_type_val_to_name = cil_malloc(sizeof(char *) * policydb->p_types.nprim); 4016 policydb->type_val_to_struct = cil_malloc(sizeof(type_datum_t *) * policydb->p_types.nprim); 4017 rc = hashtab_map(policydb->p_types.table, &__cil_type_val_array_insert, policydb); 4018 if (rc != SEPOL_OK) { 4019 goto exit; 4020 } 4021 4022 policydb->p_user_val_to_name = cil_malloc(sizeof(char *) * policydb->p_users.nprim); 4023 policydb->user_val_to_struct = cil_malloc(sizeof(user_datum_t *) * policydb->p_users.nprim); 4024 rc = hashtab_map(policydb->p_users.table, &__cil_user_val_array_insert, policydb); 4025 if (rc != SEPOL_OK) { 4026 goto exit; 4027 } 4028 4029 policydb->p_bool_val_to_name = cil_malloc(sizeof(char *) * policydb->p_bools.nprim); 4030 policydb->bool_val_to_struct = cil_malloc(sizeof(cond_bool_datum_t *) * policydb->p_bools.nprim); 4031 rc = hashtab_map(policydb->p_bools.table, &__cil_bool_val_array_insert, policydb); 4032 if (rc != SEPOL_OK) { 4033 goto exit; 4034 } 4035 4036 policydb->p_sens_val_to_name = cil_malloc(sizeof(char *) * policydb->p_levels.nprim); 4037 rc = hashtab_map(policydb->p_levels.table, &__cil_level_val_array_insert, policydb); 4038 if (rc != SEPOL_OK) { 4039 goto exit; 4040 } 4041 4042 policydb->p_cat_val_to_name = cil_malloc(sizeof(char *) * policydb->p_cats.nprim); 4043 rc = hashtab_map(policydb->p_cats.table, &__cil_cat_val_array_insert, policydb); 4044 if (rc != SEPOL_OK) { 4045 goto exit; 4046 } 4047 4048 exit: 4049 return rc; 4050 } 4051 4052 static void __cil_set_conditional_state_and_flags(policydb_t *pdb) 4053 { 4054 cond_node_t *cur; 4055 4056 for (cur = pdb->cond_list; cur != NULL; cur = cur->next) { 4057 int new_state; 4058 cond_av_list_t *c; 4059 4060 new_state = cond_evaluate_expr(pdb, cur->expr); 4061 4062 cur->cur_state = new_state; 4063 4064 if (new_state == -1) { 4065 cil_log(CIL_WARN, "Expression result was undefined - disabling all rules\n"); 4066 } 4067 4068 for (c = cur->true_list; c != NULL; c = c->next) { 4069 if (new_state <= 0) { 4070 c->node->key.specified &= ~AVTAB_ENABLED; 4071 } else { 4072 c->node->key.specified |= AVTAB_ENABLED; 4073 } 4074 } 4075 4076 for (c = cur->false_list; c != NULL; c = c->next) { 4077 if (new_state) { /* -1 or 1 */ 4078 c->node->key.specified &= ~AVTAB_ENABLED; 4079 } else { 4080 c->node->key.specified |= AVTAB_ENABLED; 4081 } 4082 } 4083 } 4084 } 4085 4086 int __cil_policydb_create(const struct cil_db *db, struct sepol_policydb **spdb) 4087 { 4088 int rc; 4089 struct policydb *pdb = NULL; 4090 4091 rc = sepol_policydb_create(spdb); 4092 if (rc < 0) { 4093 cil_log(CIL_ERR, "Failed to create policy db\n"); 4094 // spdb could be a dangling pointer at this point, so reset it so 4095 // callers of this function don't need to worry about freeing garbage 4096 *spdb = NULL; 4097 goto exit; 4098 } 4099 4100 pdb = &(*spdb)->p; 4101 4102 pdb->policy_type = POLICY_KERN; 4103 pdb->target_platform = db->target_platform; 4104 pdb->policyvers = db->policy_version; 4105 pdb->handle_unknown = db->handle_unknown; 4106 pdb->mls = db->mls; 4107 4108 return SEPOL_OK; 4109 4110 exit: 4111 return rc; 4112 } 4113 4114 4115 int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) 4116 { 4117 int rc = SEPOL_ERR; 4118 4119 // these flags should get set in __cil_policydb_create. However, for 4120 // backwards compatability, it is possible that __cil_policydb_create is 4121 // never called. So, they must also be set here. 4122 pdb->handle_unknown = db->handle_unknown; 4123 pdb->mls = db->mls; 4124 4125 rc = cil_classorder_to_policydb(pdb, db, class_value_to_cil, perm_value_to_cil); 4126 if (rc != SEPOL_OK) { 4127 goto exit; 4128 } 4129 4130 if (pdb->mls == CIL_TRUE) { 4131 rc = cil_catorder_to_policydb(pdb, db); 4132 if (rc != SEPOL_OK) { 4133 goto exit; 4134 } 4135 4136 rc = cil_sensitivityorder_to_policydb(pdb, db); 4137 if (rc != SEPOL_OK) { 4138 goto exit; 4139 } 4140 } 4141 4142 rc = avtab_alloc(&pdb->te_avtab, MAX_AVTAB_SIZE); 4143 if (rc != SEPOL_OK) { 4144 goto exit; 4145 } 4146 4147 rc = avtab_alloc(&pdb->te_cond_avtab, MAX_AVTAB_SIZE); 4148 if (rc != SEPOL_OK) { 4149 goto exit; 4150 } 4151 4152 return SEPOL_OK; 4153 4154 exit: 4155 4156 return rc; 4157 } 4158 4159 static unsigned int filename_trans_hash(hashtab_t h, const_hashtab_key_t key) 4160 { 4161 const filename_trans_t *k = (const filename_trans_t *)key; 4162 return ((k->tclass + (k->ttype << 2) + 4163 (k->stype << 9)) & (h->size - 1)); 4164 } 4165 4166 static int filename_trans_compare(hashtab_t h 4167 __attribute__ ((unused)), const_hashtab_key_t key1, 4168 const_hashtab_key_t key2) 4169 { 4170 const filename_trans_t *a = (const filename_trans_t *)key1; 4171 const filename_trans_t *b = (const filename_trans_t *)key2; 4172 4173 return a->stype != b->stype || a->ttype != b->ttype || a->tclass != b->tclass || strcmp(a->name, b->name); 4174 } 4175 4176 static unsigned int range_trans_hash(hashtab_t h, const_hashtab_key_t key) 4177 { 4178 const range_trans_t *k = (const range_trans_t *)key; 4179 return ((k->target_class + (k->target_type << 2) + 4180 (k->source_type << 5)) & (h->size - 1)); 4181 } 4182 4183 static int range_trans_compare(hashtab_t h 4184 __attribute__ ((unused)), const_hashtab_key_t key1, 4185 const_hashtab_key_t key2) 4186 { 4187 const range_trans_t *a = (const range_trans_t *)key1; 4188 const range_trans_t *b = (const range_trans_t *)key2; 4189 4190 return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class; 4191 } 4192 4193 static unsigned int role_trans_hash(hashtab_t h, const_hashtab_key_t key) 4194 { 4195 const role_trans_t *k = (const role_trans_t *)key; 4196 return ((k->role + (k->type << 2) + 4197 (k->tclass << 5)) & (h->size - 1)); 4198 } 4199 4200 static int role_trans_compare(hashtab_t h 4201 __attribute__ ((unused)), const_hashtab_key_t key1, 4202 const_hashtab_key_t key2) 4203 { 4204 const role_trans_t *a = (const role_trans_t *)key1; 4205 const role_trans_t *b = (const role_trans_t *)key2; 4206 4207 return a->role != b->role || a->type != b->type || a->tclass != b->tclass; 4208 } 4209 4210 /* Based on MurmurHash3, written by Austin Appleby and placed in the 4211 * public domain. 4212 */ 4213 static unsigned int avrulex_hash(__attribute__((unused)) hashtab_t h, const_hashtab_key_t key) 4214 { 4215 const avtab_key_t *k = (const avtab_key_t *)key; 4216 4217 static const uint32_t c1 = 0xcc9e2d51; 4218 static const uint32_t c2 = 0x1b873593; 4219 static const uint32_t r1 = 15; 4220 static const uint32_t r2 = 13; 4221 static const uint32_t m = 5; 4222 static const uint32_t n = 0xe6546b64; 4223 4224 uint32_t hash = 0; 4225 4226 #define mix(input) { \ 4227 uint32_t v = input; \ 4228 v *= c1; \ 4229 v = (v << r1) | (v >> (32 - r1)); \ 4230 v *= c2; \ 4231 hash ^= v; \ 4232 hash = (hash << r2) | (hash >> (32 - r2)); \ 4233 hash = hash * m + n; \ 4234 } 4235 4236 mix(k->target_class); 4237 mix(k->target_type); 4238 mix(k->source_type); 4239 mix(k->specified); 4240 4241 #undef mix 4242 4243 hash ^= hash >> 16; 4244 hash *= 0x85ebca6b; 4245 hash ^= hash >> 13; 4246 hash *= 0xc2b2ae35; 4247 hash ^= hash >> 16; 4248 4249 return hash & (AVRULEX_TABLE_SIZE - 1); 4250 } 4251 4252 static int avrulex_compare(hashtab_t h 4253 __attribute__ ((unused)), const_hashtab_key_t key1, 4254 const_hashtab_key_t key2) 4255 { 4256 const avtab_key_t *a = (const avtab_key_t *)key1; 4257 const avtab_key_t *b = (const avtab_key_t *)key2; 4258 4259 return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class || a->specified != b->specified; 4260 } 4261 4262 int cil_binary_create(const struct cil_db *db, sepol_policydb_t **policydb) 4263 { 4264 int rc = SEPOL_ERR; 4265 struct sepol_policydb *pdb = NULL; 4266 4267 rc = __cil_policydb_create(db, &pdb); 4268 if (rc != SEPOL_OK) { 4269 goto exit; 4270 } 4271 4272 rc = cil_binary_create_allocated_pdb(db, pdb); 4273 if (rc != SEPOL_OK) { 4274 goto exit; 4275 } 4276 4277 *policydb = pdb; 4278 4279 return SEPOL_OK; 4280 4281 exit: 4282 sepol_policydb_free(pdb); 4283 4284 return rc; 4285 } 4286 4287 static void __cil_destroy_sepol_class_perms(class_perm_node_t *curr) 4288 { 4289 class_perm_node_t *next; 4290 4291 while (curr) { 4292 next = curr->next; 4293 free(curr); 4294 curr = next; 4295 } 4296 } 4297 4298 static int __cil_rule_to_sepol_class_perms(policydb_t *pdb, struct cil_list *classperms, class_perm_node_t **sepol_class_perms) 4299 { 4300 int rc = SEPOL_ERR; 4301 struct cil_list_item *i; 4302 cil_list_for_each(i, classperms) { 4303 if (i->flavor == CIL_CLASSPERMS) { 4304 struct cil_classperms *cp = i->data; 4305 if (FLAVOR(cp->class) == CIL_CLASS) { 4306 class_perm_node_t *cpn = NULL; 4307 class_datum_t *sepol_class = NULL; 4308 uint32_t data = 0; 4309 4310 rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class); 4311 if (rc != SEPOL_OK) goto exit; 4312 4313 rc = __cil_perms_to_datum(cp->perms, sepol_class, &data); 4314 if (rc != SEPOL_OK) goto exit; 4315 if (data == 0) { 4316 /* No permissions */ 4317 return SEPOL_OK; 4318 } 4319 cpn = cil_malloc(sizeof(class_perm_node_t)); 4320 cpn->tclass = sepol_class->s.value; 4321 cpn->data = data; 4322 cpn->next = *sepol_class_perms; 4323 *sepol_class_perms = cpn; 4324 } else { /* MAP */ 4325 struct cil_list_item *j = NULL; 4326 cil_list_for_each(j, cp->perms) { 4327 struct cil_perm *cmp = j->data; 4328 rc = __cil_rule_to_sepol_class_perms(pdb, cmp->classperms, sepol_class_perms); 4329 if (rc != SEPOL_OK) { 4330 goto exit; 4331 } 4332 } 4333 } 4334 } else { /* SET */ 4335 struct cil_classperms_set *cp_set = i->data; 4336 struct cil_classpermission *cp = cp_set->set; 4337 rc = __cil_rule_to_sepol_class_perms(pdb, cp->classperms, sepol_class_perms); 4338 if (rc != SEPOL_OK) { 4339 goto exit; 4340 } 4341 } 4342 } 4343 return SEPOL_OK; 4344 4345 exit: 4346 return rc; 4347 } 4348 4349 static int __cil_permx_to_sepol_class_perms(policydb_t *pdb, struct cil_permissionx *permx, class_perm_node_t **sepol_class_perms) 4350 { 4351 int rc = SEPOL_OK; 4352 struct cil_list *class_list = NULL; 4353 struct cil_list_item *c; 4354 class_datum_t *sepol_obj = NULL; 4355 class_perm_node_t *cpn; 4356 uint32_t data = 0; 4357 char *perm_str = NULL; 4358 4359 class_list = cil_expand_class(permx->obj); 4360 4361 cil_list_for_each(c, class_list) { 4362 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); 4363 if (rc != SEPOL_OK) { 4364 goto exit; 4365 } 4366 4367 switch (permx->kind) { 4368 case CIL_PERMX_KIND_IOCTL: 4369 perm_str = CIL_KEY_IOCTL; 4370 break; 4371 default: 4372 rc = SEPOL_ERR; 4373 goto exit; 4374 } 4375 4376 rc = __perm_str_to_datum(perm_str, sepol_obj, &data); 4377 if (rc != SEPOL_OK) { 4378 goto exit; 4379 } 4380 4381 cpn = cil_malloc(sizeof(*cpn)); 4382 cpn->tclass = sepol_obj->s.value; 4383 cpn->data = data; 4384 cpn->next = *sepol_class_perms; 4385 *sepol_class_perms = cpn; 4386 } 4387 4388 exit: 4389 cil_list_destroy(&class_list, CIL_FALSE); 4390 4391 return rc; 4392 } 4393 4394 static void __cil_init_sepol_type_set(type_set_t *t) 4395 { 4396 ebitmap_init(&t->types); 4397 ebitmap_init(&t->negset); 4398 t->flags = 0; 4399 } 4400 4401 static int __cil_add_sepol_type(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *datum, ebitmap_t *map) 4402 { 4403 int rc = SEPOL_ERR; 4404 struct cil_tree_node *n = datum->nodes->head->data; 4405 type_datum_t *sepol_datum = NULL; 4406 4407 if (n->flavor == CIL_TYPEATTRIBUTE) { 4408 ebitmap_node_t *tnode; 4409 unsigned int i; 4410 struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; 4411 ebitmap_for_each_bit(attr->types, tnode, i) { 4412 if (!ebitmap_get_bit(attr->types, i)) continue; 4413 datum = DATUM(db->val_to_type[i]); 4414 rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum); 4415 if (rc != SEPOL_OK) goto exit; 4416 ebitmap_set_bit(map, sepol_datum->s.value - 1, 1); 4417 } 4418 } else { 4419 rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum); 4420 if (rc != SEPOL_OK) goto exit; 4421 ebitmap_set_bit(map, sepol_datum->s.value - 1, 1); 4422 } 4423 4424 return SEPOL_OK; 4425 4426 exit: 4427 return rc; 4428 } 4429 4430 static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *node) 4431 { 4432 avrule_t *avrule; 4433 struct cil_tree_node *source_node; 4434 char *source_path; 4435 int is_cil; 4436 4437 avrule = cil_malloc(sizeof(avrule_t)); 4438 avrule->specified = kind; 4439 avrule->flags = 0; 4440 __cil_init_sepol_type_set(&avrule->stypes); 4441 __cil_init_sepol_type_set(&avrule->ttypes); 4442 avrule->perms = NULL; 4443 avrule->line = node->line; 4444 4445 avrule->source_filename = NULL; 4446 avrule->source_line = node->line; 4447 source_node = cil_tree_get_next_path(node, &source_path, &is_cil); 4448 if (source_node) { 4449 avrule->source_filename = source_path; 4450 if (!is_cil) { 4451 avrule->source_line = node->hll_line; 4452 } 4453 } 4454 4455 avrule->next = NULL; 4456 return avrule; 4457 } 4458 4459 static void __cil_destroy_sepol_avrules(avrule_t *curr) 4460 { 4461 avrule_t *next; 4462 4463 while (curr) { 4464 next = curr->next; 4465 ebitmap_destroy(&curr->stypes.types); 4466 ebitmap_destroy(&curr->stypes.negset); 4467 ebitmap_destroy(&curr->ttypes.types); 4468 ebitmap_destroy(&curr->ttypes.negset); 4469 __cil_destroy_sepol_class_perms(curr->perms); 4470 free(curr); 4471 curr = next; 4472 } 4473 } 4474 4475 static void __cil_print_parents(const char *pad, struct cil_tree_node *n) 4476 { 4477 if (!n) return; 4478 4479 __cil_print_parents(pad, n->parent); 4480 4481 if (n->flavor != CIL_SRC_INFO) { 4482 cil_tree_log(n, CIL_ERR,"%s%s", pad, cil_node_to_string(n)); 4483 } 4484 } 4485 4486 static void __cil_print_classperm(struct cil_list *cp_list) 4487 { 4488 struct cil_list_item *i1, *i2; 4489 4490 i1 = cp_list->head; 4491 if (i1->flavor == CIL_CLASSPERMS) { 4492 struct cil_classperms *cp = i1->data; 4493 cil_log(CIL_ERR,"(%s (", DATUM(cp->class)->fqn); 4494 cil_list_for_each(i2, cp->perms) { 4495 cil_log(CIL_ERR,"%s",DATUM(i2->data)->fqn); 4496 if (i2 != cp->perms->tail) { 4497 cil_log(CIL_ERR," "); 4498 } else { 4499 cil_log(CIL_ERR,"))"); 4500 } 4501 } 4502 } else { 4503 struct cil_classperms_set *cp_set = i1->data; 4504 cil_log(CIL_ERR,"%s", DATUM(cp_set->set)->fqn); 4505 } 4506 } 4507 4508 static void __cil_print_permissionx(struct cil_permissionx *px) 4509 { 4510 const char *kind_str = ""; 4511 char *expr_str; 4512 4513 switch (px->kind) { 4514 case CIL_PERMX_KIND_IOCTL: 4515 kind_str = CIL_KEY_IOCTL; 4516 break; 4517 default: 4518 kind_str = "unknown"; 4519 break; 4520 } 4521 4522 __cil_expr_to_string(px->expr_str, CIL_PERMISSIONX, &expr_str); 4523 4524 cil_log(CIL_ERR, "%s %s (%s)", kind_str, DATUM(px->obj)->fqn, expr_str); 4525 4526 free(expr_str); 4527 } 4528 4529 static void __cil_print_rule(const char *pad, const char *kind, struct cil_avrule *avrule) 4530 { 4531 cil_log(CIL_ERR,"%s(%s ", pad, kind); 4532 cil_log(CIL_ERR,"%s %s ", DATUM(avrule->src)->fqn, DATUM(avrule->tgt)->fqn); 4533 4534 if (!avrule->is_extended) { 4535 __cil_print_classperm(avrule->perms.classperms); 4536 } else { 4537 cil_log(CIL_ERR, "("); 4538 __cil_print_permissionx(avrule->perms.x.permx); 4539 cil_log(CIL_ERR, ")"); 4540 } 4541 4542 cil_log(CIL_ERR,")\n"); 4543 } 4544 4545 static int __cil_print_neverallow_failure(const struct cil_db *db, struct cil_tree_node *node) 4546 { 4547 int rc; 4548 struct cil_list_item *i2; 4549 struct cil_list *matching; 4550 struct cil_avrule *cil_rule = node->data; 4551 struct cil_avrule target; 4552 struct cil_tree_node *n2; 4553 struct cil_avrule *r2; 4554 char *neverallow_str; 4555 char *allow_str; 4556 enum cil_flavor avrule_flavor; 4557 4558 target.rule_kind = CIL_AVRULE_ALLOWED; 4559 target.is_extended = cil_rule->is_extended; 4560 target.src = cil_rule->src; 4561 target.tgt = cil_rule->tgt; 4562 target.perms = cil_rule->perms; 4563 4564 if (!cil_rule->is_extended) { 4565 neverallow_str = CIL_KEY_NEVERALLOW; 4566 allow_str = CIL_KEY_ALLOW; 4567 avrule_flavor = CIL_AVRULE; 4568 } else { 4569 neverallow_str = CIL_KEY_NEVERALLOWX; 4570 allow_str = CIL_KEY_ALLOWX; 4571 avrule_flavor = CIL_AVRULEX; 4572 } 4573 cil_tree_log(node, CIL_ERR, "%s check failed", neverallow_str); 4574 __cil_print_rule(" ", neverallow_str, cil_rule); 4575 cil_list_init(&matching, CIL_NODE); 4576 rc = cil_find_matching_avrule_in_ast(db->ast->root, avrule_flavor, &target, matching, CIL_FALSE); 4577 if (rc) { 4578 cil_log(CIL_ERR, "Error occurred while checking %s rules\n", neverallow_str); 4579 cil_list_destroy(&matching, CIL_FALSE); 4580 goto exit; 4581 } 4582 4583 cil_list_for_each(i2, matching) { 4584 n2 = i2->data; 4585 r2 = n2->data; 4586 __cil_print_parents(" ", n2); 4587 __cil_print_rule(" ", allow_str, r2); 4588 } 4589 cil_log(CIL_ERR,"\n"); 4590 cil_list_destroy(&matching, CIL_FALSE); 4591 4592 exit: 4593 return rc; 4594 } 4595 4596 static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node, int *violation) 4597 { 4598 int rc = SEPOL_OK; 4599 struct cil_avrule *cil_rule = node->data; 4600 struct cil_symtab_datum *tgt = cil_rule->tgt; 4601 uint32_t kind; 4602 avrule_t *rule; 4603 struct cil_list *xperms = NULL; 4604 struct cil_list_item *item; 4605 4606 if (!cil_rule->is_extended) { 4607 kind = AVRULE_NEVERALLOW; 4608 } else { 4609 kind = AVRULE_XPERMS_NEVERALLOW; 4610 } 4611 4612 rule = __cil_init_sepol_avrule(kind, node); 4613 rule->next = NULL; 4614 4615 rc = __cil_add_sepol_type(pdb, db, cil_rule->src, &rule->stypes.types); 4616 if (rc != SEPOL_OK) { 4617 goto exit; 4618 } 4619 4620 if (tgt->fqn == CIL_KEY_SELF) { 4621 rule->flags = RULE_SELF; 4622 } else { 4623 rc = __cil_add_sepol_type(pdb, db, cil_rule->tgt, &rule->ttypes.types); 4624 if (rc != SEPOL_OK) { 4625 goto exit; 4626 } 4627 } 4628 4629 if (!cil_rule->is_extended) { 4630 rc = __cil_rule_to_sepol_class_perms(pdb, cil_rule->perms.classperms, &rule->perms); 4631 if (rc != SEPOL_OK) { 4632 goto exit; 4633 } 4634 4635 rc = check_assertion(pdb, rule); 4636 if (rc == CIL_TRUE) { 4637 *violation = CIL_TRUE; 4638 rc = __cil_print_neverallow_failure(db, node); 4639 if (rc != SEPOL_OK) { 4640 goto exit; 4641 } 4642 } 4643 4644 } else { 4645 rc = __cil_permx_to_sepol_class_perms(pdb, cil_rule->perms.x.permx, &rule->perms); 4646 if (rc != SEPOL_OK) { 4647 goto exit; 4648 } 4649 4650 rc = __cil_permx_bitmap_to_sepol_xperms_list(cil_rule->perms.x.permx->perms, &xperms); 4651 if (rc != SEPOL_OK) { 4652 goto exit; 4653 } 4654 4655 cil_list_for_each(item, xperms) { 4656 rule->xperms = item->data; 4657 rc = check_assertion(pdb, rule); 4658 if (rc == CIL_TRUE) { 4659 *violation = CIL_TRUE; 4660 rc = __cil_print_neverallow_failure(db, node); 4661 if (rc != SEPOL_OK) { 4662 goto exit; 4663 } 4664 } 4665 } 4666 } 4667 4668 exit: 4669 if (xperms != NULL) { 4670 cil_list_for_each(item, xperms) { 4671 free(item->data); 4672 item->data = NULL; 4673 } 4674 cil_list_destroy(&xperms, CIL_FALSE); 4675 } 4676 4677 rule->xperms = NULL; 4678 __cil_destroy_sepol_avrules(rule); 4679 4680 return rc; 4681 } 4682 4683 static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows, int *violation) 4684 { 4685 int rc = SEPOL_OK; 4686 struct cil_list_item *item; 4687 4688 cil_list_for_each(item, neverallows) { 4689 rc = cil_check_neverallow(db, pdb, item->data, violation); 4690 if (rc != SEPOL_OK) { 4691 goto exit; 4692 } 4693 } 4694 4695 exit: 4696 return rc; 4697 } 4698 4699 static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t class, uint32_t data, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) 4700 { 4701 struct cil_classperms *cp; 4702 struct cil_list *cp_list; 4703 class_datum_t *sepol_class = pdb->class_val_to_struct[class - 1]; 4704 unsigned i; 4705 4706 cil_classperms_init(&cp); 4707 4708 cp->class = class_value_to_cil[class]; 4709 if (!cp->class) goto exit; 4710 4711 cil_list_init(&cp->perms, CIL_PERM); 4712 for (i = 0; i < sepol_class->permissions.nprim; i++) { 4713 struct cil_perm *perm; 4714 if ((data & (1 << i)) == 0) continue; 4715 perm = perm_value_to_cil[class][i+1]; 4716 if (!perm) goto exit; 4717 cil_list_append(cp->perms, CIL_PERM, perm); 4718 } 4719 4720 cil_list_init(&cp_list, CIL_CLASSPERMS); 4721 cil_list_append(cp_list, CIL_CLASSPERMS, cp); 4722 4723 return cp_list; 4724 4725 exit: 4726 cil_log(CIL_ERR,"Failed to create CIL class-permissions from sepol values\n"); 4727 return NULL; 4728 } 4729 4730 static int cil_avrule_from_sepol(policydb_t *pdb, avtab_ptr_t sepol_rule, struct cil_avrule *cil_rule, void *type_value_to_cil[], struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) 4731 { 4732 int rc = SEPOL_ERR; 4733 avtab_key_t *k = &sepol_rule->key; 4734 avtab_datum_t *d = &sepol_rule->datum; 4735 cil_rule->src = type_value_to_cil[k->source_type]; 4736 if (!cil_rule->src) goto exit; 4737 4738 cil_rule->tgt = type_value_to_cil[k->target_type]; 4739 if (!cil_rule->tgt) goto exit; 4740 4741 cil_rule->perms.classperms = cil_classperms_from_sepol(pdb, k->target_class, d->data, class_value_to_cil, perm_value_to_cil); 4742 if (!cil_rule->perms.classperms) goto exit; 4743 4744 return SEPOL_OK; 4745 4746 exit: 4747 cil_log(CIL_ERR,"Failed to create CIL AV rule from sepol values\n"); 4748 return rc; 4749 } 4750 4751 static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void *type_value_to_cil, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[], int *violation) 4752 { 4753 int rc = SEPOL_OK; 4754 int i; 4755 4756 for (i = 0; i < db->num_types; i++) { 4757 type_datum_t *child; 4758 type_datum_t *parent; 4759 avtab_ptr_t bad = NULL; 4760 int numbad = 0; 4761 struct cil_type *t = db->val_to_type[i]; 4762 4763 if (!t->bounds) continue; 4764 4765 rc = __cil_get_sepol_type_datum(pdb, DATUM(t), &child); 4766 if (rc != SEPOL_OK) goto exit; 4767 4768 rc = __cil_get_sepol_type_datum(pdb, DATUM(t->bounds), &parent); 4769 if (rc != SEPOL_OK) goto exit; 4770 4771 rc = bounds_check_type(NULL, pdb, child->s.value, parent->s.value, &bad, &numbad); 4772 if (rc != SEPOL_OK) goto exit; 4773 4774 if (bad) { 4775 avtab_ptr_t cur; 4776 struct cil_avrule target; 4777 struct cil_tree_node *n1 = NULL; 4778 4779 *violation = CIL_TRUE; 4780 4781 target.is_extended = 0; 4782 target.rule_kind = CIL_AVRULE_ALLOWED; 4783 target.src_str = NULL; 4784 target.tgt_str = NULL; 4785 4786 cil_log(CIL_ERR, "Child type %s exceeds bounds of parent %s\n", 4787 t->datum.fqn, t->bounds->datum.fqn); 4788 for (cur = bad; cur; cur = cur->next) { 4789 struct cil_list_item *i2; 4790 struct cil_list *matching; 4791 4792 rc = cil_avrule_from_sepol(pdb, cur, &target, type_value_to_cil, class_value_to_cil, perm_value_to_cil); 4793 if (rc != SEPOL_OK) { 4794 cil_log(CIL_ERR, "Failed to convert sepol avrule to CIL\n"); 4795 goto exit; 4796 } 4797 __cil_print_rule(" ", "allow", &target); 4798 cil_list_init(&matching, CIL_NODE); 4799 rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_TRUE); 4800 if (rc) { 4801 cil_log(CIL_ERR, "Error occurred while checking type bounds\n"); 4802 cil_list_destroy(&matching, CIL_FALSE); 4803 cil_list_destroy(&target.perms.classperms, CIL_TRUE); 4804 bounds_destroy_bad(bad); 4805 goto exit; 4806 } 4807 cil_list_for_each(i2, matching) { 4808 struct cil_tree_node *n2 = i2->data; 4809 struct cil_avrule *r2 = n2->data; 4810 if (n1 == n2) { 4811 cil_log(CIL_ERR, " <See previous>\n"); 4812 } else { 4813 n1 = n2; 4814 __cil_print_parents(" ", n2); 4815 __cil_print_rule(" ", "allow", r2); 4816 } 4817 } 4818 cil_list_destroy(&matching, CIL_FALSE); 4819 cil_list_destroy(&target.perms.classperms, CIL_TRUE); 4820 } 4821 bounds_destroy_bad(bad); 4822 } 4823 } 4824 4825 exit: 4826 return rc; 4827 } 4828 4829 // assumes policydb is already allocated and initialized properly with things 4830 // like policy type set to kernel and version set appropriately 4831 int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *policydb) 4832 { 4833 int rc = SEPOL_ERR; 4834 int i; 4835 struct cil_args_binary extra_args; 4836 policydb_t *pdb = &policydb->p; 4837 struct cil_list *neverallows = NULL; 4838 hashtab_t filename_trans_table = NULL; 4839 hashtab_t range_trans_table = NULL; 4840 hashtab_t role_trans_table = NULL; 4841 hashtab_t avrulex_ioctl_table = NULL; 4842 void **type_value_to_cil = NULL; 4843 struct cil_class **class_value_to_cil = NULL; 4844 struct cil_perm ***perm_value_to_cil = NULL; 4845 4846 if (db == NULL || policydb == NULL) { 4847 if (db == NULL) { 4848 cil_log(CIL_ERR,"db == NULL\n"); 4849 } else if (policydb == NULL) { 4850 cil_log(CIL_ERR,"policydb == NULL\n"); 4851 } 4852 return SEPOL_ERR; 4853 } 4854 4855 /* libsepol values start at 1. Just allocate extra memory rather than 4856 * subtract 1 from the sepol value. 4857 */ 4858 type_value_to_cil = calloc(db->num_types_and_attrs+1, sizeof(*type_value_to_cil)); 4859 if (!type_value_to_cil) goto exit; 4860 4861 class_value_to_cil = calloc(db->num_classes+1, sizeof(*class_value_to_cil)); 4862 if (!class_value_to_cil) goto exit; 4863 4864 perm_value_to_cil = calloc(db->num_classes+1, sizeof(*perm_value_to_cil)); 4865 if (!perm_value_to_cil) goto exit; 4866 for (i=1; i < db->num_classes+1; i++) { 4867 perm_value_to_cil[i] = calloc(PERMS_PER_CLASS+1, sizeof(*perm_value_to_cil[i])); 4868 if (!perm_value_to_cil[i]) goto exit; 4869 } 4870 4871 rc = __cil_policydb_init(pdb, db, class_value_to_cil, perm_value_to_cil); 4872 if (rc != SEPOL_OK) { 4873 cil_log(CIL_ERR,"Problem in policydb_init\n"); 4874 goto exit; 4875 } 4876 4877 filename_trans_table = hashtab_create(filename_trans_hash, filename_trans_compare, FILENAME_TRANS_TABLE_SIZE); 4878 if (!filename_trans_table) { 4879 cil_log(CIL_INFO, "Failure to create hashtab for filename_trans\n"); 4880 goto exit; 4881 } 4882 4883 range_trans_table = hashtab_create(range_trans_hash, range_trans_compare, RANGE_TRANS_TABLE_SIZE); 4884 if (!range_trans_table) { 4885 cil_log(CIL_INFO, "Failure to create hashtab for range_trans\n"); 4886 goto exit; 4887 } 4888 4889 role_trans_table = hashtab_create(role_trans_hash, role_trans_compare, ROLE_TRANS_TABLE_SIZE); 4890 if (!role_trans_table) { 4891 cil_log(CIL_INFO, "Failure to create hashtab for role_trans\n"); 4892 goto exit; 4893 } 4894 4895 avrulex_ioctl_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE); 4896 if (!avrulex_ioctl_table) { 4897 cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n"); 4898 goto exit; 4899 } 4900 4901 cil_list_init(&neverallows, CIL_LIST_ITEM); 4902 4903 extra_args.db = db; 4904 extra_args.pdb = pdb; 4905 extra_args.neverallows = neverallows; 4906 extra_args.filename_trans_table = filename_trans_table; 4907 extra_args.range_trans_table = range_trans_table; 4908 extra_args.role_trans_table = role_trans_table; 4909 extra_args.avrulex_ioctl_table = avrulex_ioctl_table; 4910 extra_args.type_value_to_cil = type_value_to_cil; 4911 4912 for (i = 1; i <= 3; i++) { 4913 extra_args.pass = i; 4914 4915 rc = cil_tree_walk(db->ast->root, __cil_binary_create_helper, NULL, NULL, &extra_args); 4916 if (rc != SEPOL_OK) { 4917 cil_log(CIL_INFO, "Failure while walking cil database\n"); 4918 goto exit; 4919 } 4920 4921 if (i == 1) { 4922 rc = __cil_policydb_val_arrays_create(pdb); 4923 if (rc != SEPOL_OK) { 4924 cil_log(CIL_INFO, "Failure creating val_to_{struct,name} arrays\n"); 4925 goto exit; 4926 } 4927 } 4928 4929 if (i == 3) { 4930 rc = hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_to_policydb, pdb); 4931 if (rc != SEPOL_OK) { 4932 cil_log(CIL_INFO, "Failure creating avrulex rules\n"); 4933 goto exit; 4934 } 4935 } 4936 } 4937 4938 rc = cil_sidorder_to_policydb(pdb, db); 4939 if (rc != SEPOL_OK) { 4940 goto exit; 4941 } 4942 4943 rc = __cil_contexts_to_policydb(pdb, db); 4944 if (rc != SEPOL_OK) { 4945 cil_log(CIL_INFO, "Failure while inserting cil contexts into sepol policydb\n"); 4946 goto exit; 4947 } 4948 4949 if (pdb->type_attr_map == NULL) { 4950 rc = __cil_typeattr_bitmap_init(pdb); 4951 if (rc != SEPOL_OK) { 4952 cil_log(CIL_INFO, "Failure while initializing typeattribute bitmap\n"); 4953 goto exit; 4954 } 4955 } 4956 4957 cond_optimize_lists(pdb->cond_list); 4958 __cil_set_conditional_state_and_flags(pdb); 4959 4960 if (db->disable_neverallow != CIL_TRUE) { 4961 int violation = CIL_FALSE; 4962 cil_log(CIL_INFO, "Checking Neverallows\n"); 4963 rc = cil_check_neverallows(db, pdb, neverallows, &violation); 4964 if (rc != SEPOL_OK) goto exit; 4965 4966 cil_log(CIL_INFO, "Checking User Bounds\n"); 4967 rc = bounds_check_users(NULL, pdb); 4968 if (rc) { 4969 violation = CIL_TRUE; 4970 } 4971 4972 cil_log(CIL_INFO, "Checking Role Bounds\n"); 4973 rc = bounds_check_roles(NULL, pdb); 4974 if (rc) { 4975 violation = CIL_TRUE; 4976 } 4977 4978 cil_log(CIL_INFO, "Checking Type Bounds\n"); 4979 rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil, &violation); 4980 if (rc != SEPOL_OK) goto exit; 4981 4982 if (violation == CIL_TRUE) { 4983 rc = SEPOL_ERR; 4984 goto exit; 4985 } 4986 4987 } 4988 4989 /* This pre-expands the roles and users for context validity checking */ 4990 if (hashtab_map(pdb->p_roles.table, policydb_role_cache, pdb)) { 4991 cil_log(CIL_INFO, "Failure creating roles cache"); 4992 rc = SEPOL_ERR; 4993 goto exit; 4994 } 4995 4996 if (hashtab_map(pdb->p_users.table, policydb_user_cache, pdb)) { 4997 cil_log(CIL_INFO, "Failure creating users cache"); 4998 rc = SEPOL_ERR; 4999 goto exit; 5000 } 5001 5002 rc = SEPOL_OK; 5003 5004 exit: 5005 hashtab_destroy(filename_trans_table); 5006 hashtab_destroy(range_trans_table); 5007 hashtab_destroy(role_trans_table); 5008 hashtab_destroy(avrulex_ioctl_table); 5009 free(type_value_to_cil); 5010 free(class_value_to_cil); 5011 /* Range is because libsepol values start at 1. */ 5012 for (i=1; i < db->num_classes+1; i++) { 5013 free(perm_value_to_cil[i]); 5014 } 5015 free(perm_value_to_cil); 5016 cil_list_destroy(&neverallows, CIL_FALSE); 5017 5018 return rc; 5019 } 5020