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->keep) { 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->keep) { 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->keep || (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->keep) { 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_ibpkeycon_to_policydb(policydb_t *pdb, struct cil_sort *ibpkeycons) 3222 { 3223 int rc = SEPOL_ERR; 3224 uint32_t i = 0; 3225 ocontext_t *tail = NULL; 3226 struct in6_addr subnet_prefix; 3227 3228 for (i = 0; i < ibpkeycons->count; i++) { 3229 struct cil_ibpkeycon *cil_ibpkeycon = ibpkeycons->array[i]; 3230 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_IBPKEY], &tail); 3231 3232 rc = inet_pton(AF_INET6, cil_ibpkeycon->subnet_prefix_str, &subnet_prefix); 3233 if (rc != 1) { 3234 cil_log(CIL_ERR, "ibpkeycon subnet prefix not in valid IPV6 format\n"); 3235 rc = SEPOL_ERR; 3236 goto exit; 3237 } 3238 3239 memcpy(&new_ocon->u.ibpkey.subnet_prefix, &subnet_prefix.s6_addr[0], 3240 sizeof(new_ocon->u.ibpkey.subnet_prefix)); 3241 new_ocon->u.ibpkey.low_pkey = cil_ibpkeycon->pkey_low; 3242 new_ocon->u.ibpkey.high_pkey = cil_ibpkeycon->pkey_high; 3243 3244 rc = __cil_context_to_sepol_context(pdb, cil_ibpkeycon->context, &new_ocon->context[0]); 3245 if (rc != SEPOL_OK) 3246 goto exit; 3247 } 3248 3249 return SEPOL_OK; 3250 3251 exit: 3252 return rc; 3253 } 3254 3255 int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons) 3256 { 3257 int rc = SEPOL_ERR; 3258 uint32_t i = 0; 3259 ocontext_t *tail = NULL; 3260 3261 for (i = 0; i < portcons->count; i++) { 3262 struct cil_portcon *cil_portcon = portcons->array[i]; 3263 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_PORT], &tail); 3264 3265 switch (cil_portcon->proto) { 3266 case CIL_PROTOCOL_UDP: 3267 new_ocon->u.port.protocol = IPPROTO_UDP; 3268 break; 3269 case CIL_PROTOCOL_TCP: 3270 new_ocon->u.port.protocol = IPPROTO_TCP; 3271 break; 3272 case CIL_PROTOCOL_DCCP: 3273 new_ocon->u.port.protocol = IPPROTO_DCCP; 3274 break; 3275 default: 3276 /* should not get here */ 3277 rc = SEPOL_ERR; 3278 goto exit; 3279 } 3280 3281 new_ocon->u.port.low_port = cil_portcon->port_low; 3282 new_ocon->u.port.high_port = cil_portcon->port_high; 3283 3284 rc = __cil_context_to_sepol_context(pdb, cil_portcon->context, &new_ocon->context[0]); 3285 if (rc != SEPOL_OK) { 3286 goto exit; 3287 } 3288 } 3289 3290 return SEPOL_OK; 3291 3292 exit: 3293 return rc; 3294 } 3295 3296 int cil_netifcon_to_policydb(policydb_t *pdb, struct cil_sort *netifcons) 3297 { 3298 int rc = SEPOL_ERR; 3299 uint32_t i = 0; 3300 ocontext_t *tail = NULL; 3301 3302 for (i = 0; i < netifcons->count; i++) { 3303 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NETIF], &tail); 3304 struct cil_netifcon *cil_netifcon = netifcons->array[i]; 3305 3306 new_ocon->u.name = cil_strdup(cil_netifcon->interface_str); 3307 3308 rc = __cil_context_to_sepol_context(pdb, cil_netifcon->if_context, &new_ocon->context[0]); 3309 if (rc != SEPOL_OK) { 3310 goto exit; 3311 } 3312 3313 rc = __cil_context_to_sepol_context(pdb, cil_netifcon->packet_context, &new_ocon->context[1]); 3314 if (rc != SEPOL_OK) { 3315 context_destroy(&new_ocon->context[0]); 3316 goto exit; 3317 } 3318 } 3319 3320 return SEPOL_OK; 3321 3322 exit: 3323 return rc; 3324 } 3325 3326 int cil_ibendportcon_to_policydb(policydb_t *pdb, struct cil_sort *ibendportcons) 3327 { 3328 int rc = SEPOL_ERR; 3329 uint32_t i; 3330 ocontext_t *tail = NULL; 3331 3332 for (i = 0; i < ibendportcons->count; i++) { 3333 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_IBENDPORT], &tail); 3334 struct cil_ibendportcon *cil_ibendportcon = ibendportcons->array[i]; 3335 3336 new_ocon->u.ibendport.dev_name = cil_strdup(cil_ibendportcon->dev_name_str); 3337 new_ocon->u.ibendport.port = cil_ibendportcon->port; 3338 3339 rc = __cil_context_to_sepol_context(pdb, cil_ibendportcon->context, &new_ocon->context[0]); 3340 if (rc != SEPOL_OK) 3341 goto exit; 3342 } 3343 3344 return SEPOL_OK; 3345 3346 exit: 3347 return rc; 3348 } 3349 3350 int cil_nodecon_to_policydb(policydb_t *pdb, struct cil_sort *nodecons) 3351 { 3352 int rc = SEPOL_ERR; 3353 uint32_t i = 0; 3354 ocontext_t *tail = NULL; 3355 ocontext_t *tail6 = NULL; 3356 3357 for (i = 0; i < nodecons->count; i++) { 3358 ocontext_t *new_ocon = NULL; 3359 struct cil_nodecon *cil_nodecon = nodecons->array[i]; 3360 3361 if (cil_nodecon->addr->family == AF_INET) { 3362 new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE], &tail); 3363 new_ocon->u.node.addr = cil_nodecon->addr->ip.v4.s_addr; 3364 new_ocon->u.node.mask = cil_nodecon->mask->ip.v4.s_addr; 3365 } else if (cil_nodecon->addr->family == AF_INET6) { 3366 new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE6], &tail6); 3367 memcpy(new_ocon->u.node6.addr, &cil_nodecon->addr->ip.v6.s6_addr[0], 16); 3368 memcpy(new_ocon->u.node6.mask, &cil_nodecon->mask->ip.v6.s6_addr[0], 16); 3369 } else { 3370 /* should not get here */ 3371 rc = SEPOL_ERR; 3372 goto exit; 3373 } 3374 3375 rc = __cil_context_to_sepol_context(pdb, cil_nodecon->context, &new_ocon->context[0]); 3376 if (rc != SEPOL_OK) { 3377 goto exit; 3378 } 3379 } 3380 3381 return SEPOL_OK; 3382 3383 exit: 3384 return rc; 3385 } 3386 3387 int cil_fsuse_to_policydb(policydb_t *pdb, struct cil_sort *fsuses) 3388 { 3389 int rc = SEPOL_ERR; 3390 uint32_t i = 0; 3391 ocontext_t *tail = NULL; 3392 3393 for (i = 0; i < fsuses->count; i++) { 3394 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_FSUSE], &tail); 3395 struct cil_fsuse *cil_fsuse = fsuses->array[i]; 3396 3397 new_ocon->u.name = cil_strdup(cil_fsuse->fs_str); 3398 new_ocon->v.behavior = cil_fsuse->type; 3399 3400 rc = __cil_context_to_sepol_context(pdb, cil_fsuse->context, &new_ocon->context[0]); 3401 if (rc != SEPOL_OK) { 3402 goto exit; 3403 } 3404 } 3405 3406 return SEPOL_OK; 3407 3408 exit: 3409 return rc; 3410 } 3411 3412 int cil_genfscon_to_policydb(policydb_t *pdb, struct cil_sort *genfscons) 3413 { 3414 int rc = SEPOL_ERR; 3415 uint32_t i = 0; 3416 genfs_t *genfs_tail = NULL; 3417 ocontext_t *ocon_tail = NULL; 3418 3419 for (i = 0; i < genfscons->count; i++) { 3420 struct cil_genfscon *cil_genfscon = genfscons->array[i]; 3421 ocontext_t *new_ocon = cil_malloc(sizeof(ocontext_t)); 3422 memset(new_ocon, 0, sizeof(ocontext_t)); 3423 3424 if (genfs_tail && strcmp(genfs_tail->fstype, cil_genfscon->fs_str) == 0) { 3425 ocon_tail->next = new_ocon; 3426 } else { 3427 genfs_t *new_genfs = cil_malloc(sizeof(genfs_t)); 3428 memset(new_genfs, 0, sizeof(genfs_t)); 3429 new_genfs->fstype = cil_strdup(cil_genfscon->fs_str); 3430 new_genfs->head = new_ocon; 3431 3432 if (genfs_tail) { 3433 genfs_tail->next = new_genfs; 3434 } else { 3435 pdb->genfs = new_genfs; 3436 } 3437 genfs_tail = new_genfs; 3438 } 3439 3440 ocon_tail = new_ocon; 3441 3442 new_ocon->u.name = cil_strdup(cil_genfscon->path_str); 3443 3444 rc = __cil_context_to_sepol_context(pdb, cil_genfscon->context, &new_ocon->context[0]); 3445 if (rc != SEPOL_OK) { 3446 goto exit; 3447 } 3448 } 3449 3450 return SEPOL_OK; 3451 3452 exit: 3453 return rc; 3454 } 3455 3456 int cil_pirqcon_to_policydb(policydb_t *pdb, struct cil_sort *pirqcons) 3457 { 3458 int rc = SEPOL_ERR; 3459 uint32_t i = 0; 3460 ocontext_t *tail = NULL; 3461 3462 for (i = 0; i < pirqcons->count; i++) { 3463 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PIRQ], &tail); 3464 struct cil_pirqcon *cil_pirqcon = pirqcons->array[i]; 3465 3466 new_ocon->u.pirq = cil_pirqcon->pirq; 3467 3468 rc = __cil_context_to_sepol_context(pdb, cil_pirqcon->context, &new_ocon->context[0]); 3469 if (rc != SEPOL_OK) { 3470 goto exit; 3471 } 3472 } 3473 3474 return SEPOL_OK; 3475 3476 exit: 3477 return rc; 3478 } 3479 3480 int cil_iomemcon_to_policydb(policydb_t *pdb, struct cil_sort *iomemcons) 3481 { 3482 int rc = SEPOL_ERR; 3483 uint32_t i = 0; 3484 ocontext_t *tail = NULL; 3485 3486 for (i = 0; i < iomemcons->count; i++) { 3487 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOMEM], &tail); 3488 struct cil_iomemcon *cil_iomemcon = iomemcons->array[i]; 3489 3490 new_ocon->u.iomem.low_iomem = cil_iomemcon->iomem_low; 3491 new_ocon->u.iomem.high_iomem = cil_iomemcon->iomem_high; 3492 3493 rc = __cil_context_to_sepol_context(pdb, cil_iomemcon->context, &new_ocon->context[0]); 3494 if (rc != SEPOL_OK) { 3495 goto exit; 3496 } 3497 } 3498 3499 return SEPOL_OK; 3500 3501 exit: 3502 return rc; 3503 } 3504 3505 int cil_ioportcon_to_policydb(policydb_t *pdb, struct cil_sort *ioportcons) 3506 { 3507 int rc = SEPOL_ERR; 3508 uint32_t i = 0; 3509 ocontext_t *tail = NULL; 3510 3511 for (i = 0; i < ioportcons->count; i++) { 3512 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOPORT], &tail); 3513 struct cil_ioportcon *cil_ioportcon = ioportcons->array[i]; 3514 3515 new_ocon->u.ioport.low_ioport = cil_ioportcon->ioport_low; 3516 new_ocon->u.ioport.high_ioport = cil_ioportcon->ioport_high; 3517 3518 rc = __cil_context_to_sepol_context(pdb, cil_ioportcon->context, &new_ocon->context[0]); 3519 if (rc != SEPOL_OK) { 3520 goto exit; 3521 } 3522 } 3523 3524 return SEPOL_OK; 3525 3526 exit: 3527 return rc; 3528 } 3529 3530 int cil_pcidevicecon_to_policydb(policydb_t *pdb, struct cil_sort *pcidevicecons) 3531 { 3532 int rc = SEPOL_ERR; 3533 uint32_t i = 0; 3534 ocontext_t *tail = NULL; 3535 3536 for (i = 0; i < pcidevicecons->count; i++) { 3537 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PCIDEVICE], &tail); 3538 struct cil_pcidevicecon *cil_pcidevicecon = pcidevicecons->array[i]; 3539 3540 new_ocon->u.device = cil_pcidevicecon->dev; 3541 3542 rc = __cil_context_to_sepol_context(pdb, cil_pcidevicecon->context, &new_ocon->context[0]); 3543 if (rc != SEPOL_OK) { 3544 goto exit; 3545 } 3546 } 3547 3548 return SEPOL_OK; 3549 3550 exit: 3551 return rc; 3552 } 3553 3554 int cil_devicetreecon_to_policydb(policydb_t *pdb, struct cil_sort *devicetreecons) 3555 { 3556 int rc = SEPOL_ERR; 3557 uint32_t i = 0; 3558 ocontext_t *tail = NULL; 3559 3560 for (i = 0; i < devicetreecons->count; i++) { 3561 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_DEVICETREE], &tail); 3562 struct cil_devicetreecon *cil_devicetreecon = devicetreecons->array[i]; 3563 3564 new_ocon->u.name = cil_strdup(cil_devicetreecon->path); 3565 3566 rc = __cil_context_to_sepol_context(pdb, cil_devicetreecon->context, &new_ocon->context[0]); 3567 if (rc != SEPOL_OK) { 3568 goto exit; 3569 } 3570 } 3571 3572 return SEPOL_OK; 3573 3574 exit: 3575 return rc; 3576 } 3577 3578 int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def) 3579 { 3580 struct cil_list_item *curr; 3581 class_datum_t *sepol_class; 3582 struct cil_list *class_list; 3583 3584 cil_list_for_each(curr, def->class_datums) { 3585 struct cil_list_item *c; 3586 3587 class_list = cil_expand_class(curr->data); 3588 3589 cil_list_for_each(c, class_list) { 3590 int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); 3591 if (rc != SEPOL_OK) goto exit; 3592 3593 switch (def->flavor) { 3594 case CIL_DEFAULTUSER: 3595 if (!sepol_class->default_user) { 3596 sepol_class->default_user = def->object; 3597 } else if (sepol_class->default_user != (char)def->object) { 3598 cil_log(CIL_ERR,"User default labeling for class %s already specified\n",DATUM(c->data)->fqn); 3599 goto exit; 3600 } 3601 break; 3602 case CIL_DEFAULTROLE: 3603 if (!sepol_class->default_role) { 3604 sepol_class->default_role = def->object; 3605 } else if (sepol_class->default_role != (char)def->object) { 3606 cil_log(CIL_ERR,"Role default labeling for class %s already specified\n",DATUM(c->data)->fqn); 3607 goto exit; 3608 } 3609 break; 3610 case CIL_DEFAULTTYPE: 3611 if (!sepol_class->default_type) { 3612 sepol_class->default_type = def->object; 3613 } else if (sepol_class->default_type != (char)def->object) { 3614 cil_log(CIL_ERR,"Type default labeling for class %s already specified\n",DATUM(c->data)->fqn); 3615 goto exit; 3616 } 3617 break; 3618 default: 3619 goto exit; 3620 } 3621 } 3622 3623 cil_list_destroy(&class_list, CIL_FALSE); 3624 } 3625 3626 return SEPOL_OK; 3627 3628 exit: 3629 cil_list_destroy(&class_list, CIL_FALSE); 3630 return SEPOL_ERR; 3631 } 3632 3633 int cil_defaultrange_to_policydb(policydb_t *pdb, struct cil_defaultrange *def) 3634 { 3635 struct cil_list_item *curr; 3636 class_datum_t *sepol_class; 3637 struct cil_list *class_list; 3638 3639 cil_list_for_each(curr, def->class_datums) { 3640 struct cil_list_item *c; 3641 3642 class_list = cil_expand_class(curr->data); 3643 3644 cil_list_for_each(c, class_list) { 3645 int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); 3646 if (rc != SEPOL_OK) goto exit; 3647 3648 if (!sepol_class->default_range) { 3649 sepol_class->default_range = def->object_range; 3650 } else if (sepol_class->default_range != (char)def->object_range) { 3651 cil_log(CIL_ERR,"Range default labeling for class %s already specified\n", DATUM(curr->data)->fqn); 3652 goto exit; 3653 } 3654 } 3655 3656 cil_list_destroy(&class_list, CIL_FALSE); 3657 } 3658 3659 return SEPOL_OK; 3660 3661 exit: 3662 cil_list_destroy(&class_list, CIL_FALSE); 3663 return SEPOL_ERR; 3664 } 3665 3666 int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args) 3667 { 3668 int rc = SEPOL_OK; 3669 int pass; 3670 struct cil_args_binary *args = extra_args; 3671 const struct cil_db *db; 3672 policydb_t *pdb; 3673 hashtab_t filename_trans_table; 3674 hashtab_t range_trans_table; 3675 hashtab_t role_trans_table; 3676 void **type_value_to_cil; 3677 3678 db = args->db; 3679 pdb = args->pdb; 3680 pass = args->pass; 3681 filename_trans_table = args->filename_trans_table; 3682 range_trans_table = args->range_trans_table; 3683 role_trans_table = args->role_trans_table; 3684 type_value_to_cil = args->type_value_to_cil; 3685 3686 if (node->flavor >= CIL_MIN_DECLARATIVE) { 3687 if (node != DATUM(node->data)->nodes->head->data) { 3688 goto exit; 3689 } 3690 } 3691 3692 switch (pass) { 3693 case 1: 3694 switch (node->flavor) { 3695 case CIL_ROLE: 3696 rc = cil_role_to_policydb(pdb, node->data); 3697 break; 3698 case CIL_TYPE: 3699 rc = cil_type_to_policydb(pdb, node->data, type_value_to_cil); 3700 break; 3701 case CIL_TYPEATTRIBUTE: 3702 rc = cil_typeattribute_to_policydb(pdb, node->data, type_value_to_cil); 3703 break; 3704 case CIL_POLICYCAP: 3705 rc = cil_policycap_to_policydb(pdb, node->data); 3706 break; 3707 case CIL_USER: 3708 rc = cil_user_to_policydb(pdb, node->data); 3709 break; 3710 case CIL_BOOL: 3711 rc = cil_bool_to_policydb(pdb, node->data); 3712 break; 3713 case CIL_CATALIAS: 3714 if (pdb->mls == CIL_TRUE) { 3715 rc = cil_catalias_to_policydb(pdb, node->data); 3716 } 3717 break; 3718 case CIL_SENS: 3719 if (pdb->mls == CIL_TRUE) { 3720 rc = cil_sepol_level_define(pdb, node->data); 3721 } 3722 break; 3723 default: 3724 break; 3725 } 3726 break; 3727 case 2: 3728 switch (node->flavor) { 3729 case CIL_TYPE: 3730 rc = cil_type_bounds_to_policydb(pdb, node->data); 3731 break; 3732 case CIL_TYPEALIAS: 3733 rc = cil_typealias_to_policydb(pdb, node->data); 3734 break; 3735 case CIL_TYPEPERMISSIVE: 3736 rc = cil_typepermissive_to_policydb(pdb, node->data); 3737 break; 3738 case CIL_TYPEATTRIBUTE: 3739 rc = cil_typeattribute_to_bitmap(pdb, db, node->data); 3740 break; 3741 case CIL_SENSALIAS: 3742 if (pdb->mls == CIL_TRUE) { 3743 rc = cil_sensalias_to_policydb(pdb, node->data); 3744 } 3745 break; 3746 case CIL_ROLE: 3747 rc = cil_role_bounds_to_policydb(pdb, node->data); 3748 if (rc != SEPOL_OK) goto exit; 3749 rc = cil_roletype_to_policydb(pdb, db, node->data); 3750 break; 3751 case CIL_USER: 3752 rc = cil_user_bounds_to_policydb(pdb, node->data); 3753 if (rc != SEPOL_OK) goto exit; 3754 if (pdb->mls == CIL_TRUE) { 3755 rc = cil_userlevel_userrange_to_policydb(pdb, node->data); 3756 if (rc != SEPOL_OK) { 3757 goto exit; 3758 } 3759 } 3760 rc = cil_userrole_to_policydb(pdb, db, node->data); 3761 break; 3762 case CIL_TYPE_RULE: 3763 rc = cil_type_rule_to_policydb(pdb, db, node->data); 3764 break; 3765 case CIL_AVRULE: 3766 case CIL_AVRULEX: { 3767 struct cil_avrule *rule = node->data; 3768 if (db->disable_neverallow != CIL_TRUE && rule->rule_kind == CIL_AVRULE_NEVERALLOW) { 3769 struct cil_list *neverallows = args->neverallows; 3770 cil_list_prepend(neverallows, CIL_LIST_ITEM, node); 3771 } 3772 break; 3773 } 3774 case CIL_ROLETRANSITION: 3775 rc = cil_roletrans_to_policydb(pdb, db, node->data, role_trans_table); 3776 break; 3777 case CIL_ROLEATTRIBUTESET: 3778 /*rc = cil_roleattributeset_to_policydb(pdb, node->data);*/ 3779 break; 3780 case CIL_NAMETYPETRANSITION: 3781 rc = cil_typetransition_to_policydb(pdb, db, node->data, filename_trans_table); 3782 break; 3783 case CIL_CONSTRAIN: 3784 rc = cil_constrain_to_policydb(pdb, db, node->data); 3785 break; 3786 case CIL_MLSCONSTRAIN: 3787 if (pdb->mls == CIL_TRUE) { 3788 rc = cil_constrain_to_policydb(pdb, db, node->data); 3789 } 3790 break; 3791 case CIL_VALIDATETRANS: 3792 rc = cil_validatetrans_to_policydb(pdb, db, node->data); 3793 break; 3794 case CIL_MLSVALIDATETRANS: 3795 if (pdb->mls == CIL_TRUE) { 3796 rc = cil_validatetrans_to_policydb(pdb, db, node->data); 3797 } 3798 break; 3799 case CIL_RANGETRANSITION: 3800 if (pdb->mls == CIL_TRUE) { 3801 rc = cil_rangetransition_to_policydb(pdb, db, node->data, range_trans_table); 3802 } 3803 break; 3804 case CIL_DEFAULTUSER: 3805 case CIL_DEFAULTROLE: 3806 case CIL_DEFAULTTYPE: 3807 rc = cil_default_to_policydb(pdb, node->data); 3808 break; 3809 case CIL_DEFAULTRANGE: 3810 rc = cil_defaultrange_to_policydb(pdb, node->data); 3811 break; 3812 default: 3813 break; 3814 } 3815 break; 3816 case 3: 3817 switch (node->flavor) { 3818 case CIL_BOOLEANIF: 3819 rc = cil_booleanif_to_policydb(pdb, db, node, filename_trans_table); 3820 break; 3821 case CIL_AVRULE: { 3822 struct cil_avrule *rule = node->data; 3823 if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) { 3824 rc = cil_avrule_to_policydb(pdb, db, node->data); 3825 } 3826 } 3827 break; 3828 case CIL_AVRULEX: { 3829 struct cil_avrule *rule = node->data; 3830 if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) { 3831 rc = cil_avrulex_to_hashtable(pdb, db, node->data, args); 3832 } 3833 } 3834 break; 3835 case CIL_ROLEALLOW: 3836 rc = cil_roleallow_to_policydb(pdb, db, node->data); 3837 break; 3838 default: 3839 break; 3840 } 3841 default: 3842 break; 3843 } 3844 3845 exit: 3846 if (rc != SEPOL_OK) { 3847 cil_tree_log(node, CIL_ERR, "Binary policy creation failed"); 3848 } 3849 return rc; 3850 } 3851 3852 int __cil_binary_create_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) 3853 { 3854 int rc = SEPOL_ERR; 3855 3856 if (node->flavor == CIL_BLOCK) { 3857 struct cil_block *blk = node->data; 3858 if (blk->is_abstract == CIL_TRUE) { 3859 *finished = CIL_TREE_SKIP_HEAD; 3860 rc = SEPOL_OK; 3861 goto exit; 3862 } 3863 } else if (node->flavor == CIL_MACRO) { 3864 *finished = CIL_TREE_SKIP_HEAD; 3865 rc = SEPOL_OK; 3866 goto exit; 3867 } else if (node->flavor == CIL_BOOLEANIF) { 3868 *finished = CIL_TREE_SKIP_HEAD; 3869 } 3870 3871 rc = __cil_node_to_policydb(node, extra_args); 3872 if (rc != SEPOL_OK) { 3873 goto exit; 3874 } 3875 3876 exit: 3877 return rc; 3878 } 3879 3880 int __cil_contexts_to_policydb(policydb_t *pdb, const struct cil_db *db) 3881 { 3882 int rc = SEPOL_ERR; 3883 3884 rc = cil_portcon_to_policydb(pdb, db->portcon); 3885 if (rc != SEPOL_OK) { 3886 goto exit; 3887 } 3888 3889 rc = cil_netifcon_to_policydb(pdb, db->netifcon); 3890 if (rc != SEPOL_OK) { 3891 goto exit; 3892 } 3893 3894 rc = cil_nodecon_to_policydb(pdb, db->nodecon); 3895 if (rc != SEPOL_OK) { 3896 goto exit; 3897 } 3898 3899 rc = cil_fsuse_to_policydb(pdb, db->fsuse); 3900 if (rc != SEPOL_OK) { 3901 goto exit; 3902 } 3903 3904 rc = cil_genfscon_to_policydb(pdb, db->genfscon); 3905 if (rc != SEPOL_OK) { 3906 goto exit; 3907 } 3908 3909 rc = cil_ibpkeycon_to_policydb(pdb, db->ibpkeycon); 3910 if (rc != SEPOL_OK) { 3911 goto exit; 3912 } 3913 3914 rc = cil_ibendportcon_to_policydb(pdb, db->ibendportcon); 3915 if (rc != SEPOL_OK) { 3916 goto exit; 3917 } 3918 3919 if (db->target_platform == SEPOL_TARGET_XEN) { 3920 rc = cil_pirqcon_to_policydb(pdb, db->pirqcon); 3921 if (rc != SEPOL_OK) { 3922 goto exit; 3923 } 3924 3925 rc = cil_iomemcon_to_policydb(pdb, db->iomemcon); 3926 if (rc != SEPOL_OK) { 3927 goto exit; 3928 } 3929 3930 rc = cil_ioportcon_to_policydb(pdb, db->ioportcon); 3931 if (rc != SEPOL_OK) { 3932 goto exit; 3933 } 3934 3935 rc = cil_pcidevicecon_to_policydb(pdb, db->pcidevicecon); 3936 if (rc != SEPOL_OK) { 3937 goto exit; 3938 } 3939 3940 rc = cil_devicetreecon_to_policydb(pdb, db->devicetreecon); 3941 if (rc != SEPOL_OK) { 3942 goto exit; 3943 } 3944 } 3945 return SEPOL_OK; 3946 exit: 3947 return rc; 3948 } 3949 3950 int __cil_common_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3951 { 3952 policydb_t *pdb = data; 3953 common_datum_t *common = (common_datum_t *)datum; 3954 3955 if (common->s.value < 1 || common->s.value > pdb->p_commons.nprim) { 3956 return -EINVAL; 3957 } 3958 pdb->p_common_val_to_name[common->s.value - 1] = (char *)key; 3959 3960 return 0; 3961 } 3962 3963 int __cil_class_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3964 { 3965 policydb_t *pdb = data; 3966 class_datum_t *class = (class_datum_t *)datum; 3967 3968 if (class->s.value < 1 || class->s.value > pdb->p_classes.nprim) { 3969 return -EINVAL; 3970 } 3971 pdb->p_class_val_to_name[class->s.value - 1] = (char *)key; 3972 pdb->class_val_to_struct[class->s.value - 1] = class; 3973 3974 return 0; 3975 } 3976 3977 int __cil_role_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3978 { 3979 policydb_t *pdb = data; 3980 role_datum_t *role = (role_datum_t *)datum; 3981 3982 if (role->s.value < 1 || role->s.value > pdb->p_roles.nprim) { 3983 return -EINVAL; 3984 } 3985 pdb->p_role_val_to_name[role->s.value - 1] = (char *)key; 3986 pdb->role_val_to_struct[role->s.value - 1] = role; 3987 3988 return 0; 3989 } 3990 3991 int __cil_type_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 3992 { 3993 policydb_t *pdb = data; 3994 type_datum_t *type = (type_datum_t *)datum; 3995 3996 if (type->s.value < 1 || type->s.value > pdb->p_types.nprim) { 3997 return -EINVAL; 3998 } 3999 pdb->p_type_val_to_name[type->s.value - 1] = (char *)key; 4000 pdb->type_val_to_struct[type->s.value - 1] = type; 4001 4002 return 0; 4003 } 4004 4005 int __cil_user_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 4006 { 4007 policydb_t *pdb = data; 4008 user_datum_t *user = (user_datum_t *)datum; 4009 4010 if (user->s.value < 1 || user->s.value > pdb->p_users.nprim) { 4011 return -EINVAL; 4012 } 4013 pdb->p_user_val_to_name[user->s.value - 1] = (char *)key; 4014 pdb->user_val_to_struct[user->s.value - 1] = user; 4015 4016 return 0; 4017 } 4018 4019 int __cil_bool_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 4020 { 4021 policydb_t *pdb = data; 4022 cond_bool_datum_t *bool = (cond_bool_datum_t *)datum; 4023 4024 if (bool->s.value < 1 || bool->s.value > pdb->p_bools.nprim) { 4025 return -EINVAL; 4026 } 4027 pdb->p_bool_val_to_name[bool->s.value - 1] = (char *)key; 4028 pdb->bool_val_to_struct[bool->s.value - 1] = bool; 4029 4030 return 0; 4031 } 4032 4033 int __cil_level_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 4034 { 4035 policydb_t *pdb = data; 4036 level_datum_t *level = (level_datum_t *)datum; 4037 4038 if (level->level->sens < 1 || level->level->sens > pdb->p_levels.nprim) { 4039 return -EINVAL; 4040 } 4041 pdb->p_sens_val_to_name[level->level->sens - 1] = (char *)key; 4042 4043 return 0; 4044 } 4045 4046 int __cil_cat_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data) 4047 { 4048 policydb_t *pdb = data; 4049 cat_datum_t *cat = (cat_datum_t *)datum; 4050 4051 if (cat->s.value < 1 || cat->s.value > pdb->p_cats.nprim) { 4052 return -EINVAL; 4053 } 4054 pdb->p_cat_val_to_name[cat->s.value - 1] = (char *)key; 4055 4056 return 0; 4057 } 4058 4059 int __cil_policydb_val_arrays_create(policydb_t *policydb) 4060 { 4061 int rc = SEPOL_ERR; 4062 4063 policydb->p_common_val_to_name = cil_malloc(sizeof(char *) * policydb->p_commons.nprim); 4064 rc = hashtab_map(policydb->p_commons.table, &__cil_common_val_array_insert, policydb); 4065 if (rc != SEPOL_OK) { 4066 goto exit; 4067 } 4068 4069 policydb->p_class_val_to_name = cil_malloc(sizeof(char *) * policydb->p_classes.nprim); 4070 policydb->class_val_to_struct = cil_malloc(sizeof(class_datum_t *) * policydb->p_classes.nprim); 4071 rc = hashtab_map(policydb->p_classes.table, &__cil_class_val_array_insert, policydb); 4072 if (rc != SEPOL_OK) { 4073 goto exit; 4074 } 4075 4076 policydb->p_role_val_to_name = cil_malloc(sizeof(char *) * policydb->p_roles.nprim); 4077 policydb->role_val_to_struct = cil_malloc(sizeof(role_datum_t *) * policydb->p_roles.nprim); 4078 rc = hashtab_map(policydb->p_roles.table, &__cil_role_val_array_insert, policydb); 4079 if (rc != SEPOL_OK) { 4080 goto exit; 4081 } 4082 4083 policydb->p_type_val_to_name = cil_malloc(sizeof(char *) * policydb->p_types.nprim); 4084 policydb->type_val_to_struct = cil_malloc(sizeof(type_datum_t *) * policydb->p_types.nprim); 4085 rc = hashtab_map(policydb->p_types.table, &__cil_type_val_array_insert, policydb); 4086 if (rc != SEPOL_OK) { 4087 goto exit; 4088 } 4089 4090 policydb->p_user_val_to_name = cil_malloc(sizeof(char *) * policydb->p_users.nprim); 4091 policydb->user_val_to_struct = cil_malloc(sizeof(user_datum_t *) * policydb->p_users.nprim); 4092 rc = hashtab_map(policydb->p_users.table, &__cil_user_val_array_insert, policydb); 4093 if (rc != SEPOL_OK) { 4094 goto exit; 4095 } 4096 4097 policydb->p_bool_val_to_name = cil_malloc(sizeof(char *) * policydb->p_bools.nprim); 4098 policydb->bool_val_to_struct = cil_malloc(sizeof(cond_bool_datum_t *) * policydb->p_bools.nprim); 4099 rc = hashtab_map(policydb->p_bools.table, &__cil_bool_val_array_insert, policydb); 4100 if (rc != SEPOL_OK) { 4101 goto exit; 4102 } 4103 4104 policydb->p_sens_val_to_name = cil_malloc(sizeof(char *) * policydb->p_levels.nprim); 4105 rc = hashtab_map(policydb->p_levels.table, &__cil_level_val_array_insert, policydb); 4106 if (rc != SEPOL_OK) { 4107 goto exit; 4108 } 4109 4110 policydb->p_cat_val_to_name = cil_malloc(sizeof(char *) * policydb->p_cats.nprim); 4111 rc = hashtab_map(policydb->p_cats.table, &__cil_cat_val_array_insert, policydb); 4112 if (rc != SEPOL_OK) { 4113 goto exit; 4114 } 4115 4116 exit: 4117 return rc; 4118 } 4119 4120 static void __cil_set_conditional_state_and_flags(policydb_t *pdb) 4121 { 4122 cond_node_t *cur; 4123 4124 for (cur = pdb->cond_list; cur != NULL; cur = cur->next) { 4125 int new_state; 4126 cond_av_list_t *c; 4127 4128 new_state = cond_evaluate_expr(pdb, cur->expr); 4129 4130 cur->cur_state = new_state; 4131 4132 if (new_state == -1) { 4133 cil_log(CIL_WARN, "Expression result was undefined - disabling all rules\n"); 4134 } 4135 4136 for (c = cur->true_list; c != NULL; c = c->next) { 4137 if (new_state <= 0) { 4138 c->node->key.specified &= ~AVTAB_ENABLED; 4139 } else { 4140 c->node->key.specified |= AVTAB_ENABLED; 4141 } 4142 } 4143 4144 for (c = cur->false_list; c != NULL; c = c->next) { 4145 if (new_state) { /* -1 or 1 */ 4146 c->node->key.specified &= ~AVTAB_ENABLED; 4147 } else { 4148 c->node->key.specified |= AVTAB_ENABLED; 4149 } 4150 } 4151 } 4152 } 4153 4154 int __cil_policydb_create(const struct cil_db *db, struct sepol_policydb **spdb) 4155 { 4156 int rc; 4157 struct policydb *pdb = NULL; 4158 4159 rc = sepol_policydb_create(spdb); 4160 if (rc < 0) { 4161 cil_log(CIL_ERR, "Failed to create policy db\n"); 4162 // spdb could be a dangling pointer at this point, so reset it so 4163 // callers of this function don't need to worry about freeing garbage 4164 *spdb = NULL; 4165 goto exit; 4166 } 4167 4168 pdb = &(*spdb)->p; 4169 4170 pdb->policy_type = POLICY_KERN; 4171 pdb->target_platform = db->target_platform; 4172 pdb->policyvers = db->policy_version; 4173 pdb->handle_unknown = db->handle_unknown; 4174 pdb->mls = db->mls; 4175 4176 return SEPOL_OK; 4177 4178 exit: 4179 return rc; 4180 } 4181 4182 4183 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[]) 4184 { 4185 int rc = SEPOL_ERR; 4186 4187 // these flags should get set in __cil_policydb_create. However, for 4188 // backwards compatability, it is possible that __cil_policydb_create is 4189 // never called. So, they must also be set here. 4190 pdb->handle_unknown = db->handle_unknown; 4191 pdb->mls = db->mls; 4192 4193 rc = cil_classorder_to_policydb(pdb, db, class_value_to_cil, perm_value_to_cil); 4194 if (rc != SEPOL_OK) { 4195 goto exit; 4196 } 4197 4198 if (pdb->mls == CIL_TRUE) { 4199 rc = cil_catorder_to_policydb(pdb, db); 4200 if (rc != SEPOL_OK) { 4201 goto exit; 4202 } 4203 4204 rc = cil_sensitivityorder_to_policydb(pdb, db); 4205 if (rc != SEPOL_OK) { 4206 goto exit; 4207 } 4208 } 4209 4210 rc = avtab_alloc(&pdb->te_avtab, MAX_AVTAB_SIZE); 4211 if (rc != SEPOL_OK) { 4212 goto exit; 4213 } 4214 4215 rc = avtab_alloc(&pdb->te_cond_avtab, MAX_AVTAB_SIZE); 4216 if (rc != SEPOL_OK) { 4217 goto exit; 4218 } 4219 4220 return SEPOL_OK; 4221 4222 exit: 4223 4224 return rc; 4225 } 4226 4227 static unsigned int filename_trans_hash(hashtab_t h, const_hashtab_key_t key) 4228 { 4229 const filename_trans_t *k = (const filename_trans_t *)key; 4230 return ((k->tclass + (k->ttype << 2) + 4231 (k->stype << 9)) & (h->size - 1)); 4232 } 4233 4234 static int filename_trans_compare(hashtab_t h 4235 __attribute__ ((unused)), const_hashtab_key_t key1, 4236 const_hashtab_key_t key2) 4237 { 4238 const filename_trans_t *a = (const filename_trans_t *)key1; 4239 const filename_trans_t *b = (const filename_trans_t *)key2; 4240 4241 return a->stype != b->stype || a->ttype != b->ttype || a->tclass != b->tclass || strcmp(a->name, b->name); 4242 } 4243 4244 static unsigned int range_trans_hash(hashtab_t h, const_hashtab_key_t key) 4245 { 4246 const range_trans_t *k = (const range_trans_t *)key; 4247 return ((k->target_class + (k->target_type << 2) + 4248 (k->source_type << 5)) & (h->size - 1)); 4249 } 4250 4251 static int range_trans_compare(hashtab_t h 4252 __attribute__ ((unused)), const_hashtab_key_t key1, 4253 const_hashtab_key_t key2) 4254 { 4255 const range_trans_t *a = (const range_trans_t *)key1; 4256 const range_trans_t *b = (const range_trans_t *)key2; 4257 4258 return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class; 4259 } 4260 4261 static unsigned int role_trans_hash(hashtab_t h, const_hashtab_key_t key) 4262 { 4263 const role_trans_t *k = (const role_trans_t *)key; 4264 return ((k->role + (k->type << 2) + 4265 (k->tclass << 5)) & (h->size - 1)); 4266 } 4267 4268 static int role_trans_compare(hashtab_t h 4269 __attribute__ ((unused)), const_hashtab_key_t key1, 4270 const_hashtab_key_t key2) 4271 { 4272 const role_trans_t *a = (const role_trans_t *)key1; 4273 const role_trans_t *b = (const role_trans_t *)key2; 4274 4275 return a->role != b->role || a->type != b->type || a->tclass != b->tclass; 4276 } 4277 4278 /* Based on MurmurHash3, written by Austin Appleby and placed in the 4279 * public domain. 4280 */ 4281 static unsigned int avrulex_hash(__attribute__((unused)) hashtab_t h, const_hashtab_key_t key) 4282 { 4283 const avtab_key_t *k = (const avtab_key_t *)key; 4284 4285 static const uint32_t c1 = 0xcc9e2d51; 4286 static const uint32_t c2 = 0x1b873593; 4287 static const uint32_t r1 = 15; 4288 static const uint32_t r2 = 13; 4289 static const uint32_t m = 5; 4290 static const uint32_t n = 0xe6546b64; 4291 4292 uint32_t hash = 0; 4293 4294 #define mix(input) { \ 4295 uint32_t v = input; \ 4296 v *= c1; \ 4297 v = (v << r1) | (v >> (32 - r1)); \ 4298 v *= c2; \ 4299 hash ^= v; \ 4300 hash = (hash << r2) | (hash >> (32 - r2)); \ 4301 hash = hash * m + n; \ 4302 } 4303 4304 mix(k->target_class); 4305 mix(k->target_type); 4306 mix(k->source_type); 4307 mix(k->specified); 4308 4309 #undef mix 4310 4311 hash ^= hash >> 16; 4312 hash *= 0x85ebca6b; 4313 hash ^= hash >> 13; 4314 hash *= 0xc2b2ae35; 4315 hash ^= hash >> 16; 4316 4317 return hash & (AVRULEX_TABLE_SIZE - 1); 4318 } 4319 4320 static int avrulex_compare(hashtab_t h 4321 __attribute__ ((unused)), const_hashtab_key_t key1, 4322 const_hashtab_key_t key2) 4323 { 4324 const avtab_key_t *a = (const avtab_key_t *)key1; 4325 const avtab_key_t *b = (const avtab_key_t *)key2; 4326 4327 return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class || a->specified != b->specified; 4328 } 4329 4330 int cil_binary_create(const struct cil_db *db, sepol_policydb_t **policydb) 4331 { 4332 int rc = SEPOL_ERR; 4333 struct sepol_policydb *pdb = NULL; 4334 4335 rc = __cil_policydb_create(db, &pdb); 4336 if (rc != SEPOL_OK) { 4337 goto exit; 4338 } 4339 4340 rc = cil_binary_create_allocated_pdb(db, pdb); 4341 if (rc != SEPOL_OK) { 4342 goto exit; 4343 } 4344 4345 *policydb = pdb; 4346 4347 return SEPOL_OK; 4348 4349 exit: 4350 sepol_policydb_free(pdb); 4351 4352 return rc; 4353 } 4354 4355 static void __cil_destroy_sepol_class_perms(class_perm_node_t *curr) 4356 { 4357 class_perm_node_t *next; 4358 4359 while (curr) { 4360 next = curr->next; 4361 free(curr); 4362 curr = next; 4363 } 4364 } 4365 4366 static int __cil_rule_to_sepol_class_perms(policydb_t *pdb, struct cil_list *classperms, class_perm_node_t **sepol_class_perms) 4367 { 4368 int rc = SEPOL_ERR; 4369 struct cil_list_item *i; 4370 cil_list_for_each(i, classperms) { 4371 if (i->flavor == CIL_CLASSPERMS) { 4372 struct cil_classperms *cp = i->data; 4373 if (FLAVOR(cp->class) == CIL_CLASS) { 4374 class_perm_node_t *cpn = NULL; 4375 class_datum_t *sepol_class = NULL; 4376 uint32_t data = 0; 4377 4378 rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class); 4379 if (rc != SEPOL_OK) goto exit; 4380 4381 rc = __cil_perms_to_datum(cp->perms, sepol_class, &data); 4382 if (rc != SEPOL_OK) goto exit; 4383 if (data == 0) { 4384 /* No permissions */ 4385 return SEPOL_OK; 4386 } 4387 cpn = cil_malloc(sizeof(class_perm_node_t)); 4388 cpn->tclass = sepol_class->s.value; 4389 cpn->data = data; 4390 cpn->next = *sepol_class_perms; 4391 *sepol_class_perms = cpn; 4392 } else { /* MAP */ 4393 struct cil_list_item *j = NULL; 4394 cil_list_for_each(j, cp->perms) { 4395 struct cil_perm *cmp = j->data; 4396 rc = __cil_rule_to_sepol_class_perms(pdb, cmp->classperms, sepol_class_perms); 4397 if (rc != SEPOL_OK) { 4398 goto exit; 4399 } 4400 } 4401 } 4402 } else { /* SET */ 4403 struct cil_classperms_set *cp_set = i->data; 4404 struct cil_classpermission *cp = cp_set->set; 4405 rc = __cil_rule_to_sepol_class_perms(pdb, cp->classperms, sepol_class_perms); 4406 if (rc != SEPOL_OK) { 4407 goto exit; 4408 } 4409 } 4410 } 4411 return SEPOL_OK; 4412 4413 exit: 4414 return rc; 4415 } 4416 4417 static int __cil_permx_to_sepol_class_perms(policydb_t *pdb, struct cil_permissionx *permx, class_perm_node_t **sepol_class_perms) 4418 { 4419 int rc = SEPOL_OK; 4420 struct cil_list *class_list = NULL; 4421 struct cil_list_item *c; 4422 class_datum_t *sepol_obj = NULL; 4423 class_perm_node_t *cpn; 4424 uint32_t data = 0; 4425 char *perm_str = NULL; 4426 4427 class_list = cil_expand_class(permx->obj); 4428 4429 cil_list_for_each(c, class_list) { 4430 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); 4431 if (rc != SEPOL_OK) { 4432 goto exit; 4433 } 4434 4435 switch (permx->kind) { 4436 case CIL_PERMX_KIND_IOCTL: 4437 perm_str = CIL_KEY_IOCTL; 4438 break; 4439 default: 4440 rc = SEPOL_ERR; 4441 goto exit; 4442 } 4443 4444 rc = __perm_str_to_datum(perm_str, sepol_obj, &data); 4445 if (rc != SEPOL_OK) { 4446 goto exit; 4447 } 4448 4449 cpn = cil_malloc(sizeof(*cpn)); 4450 cpn->tclass = sepol_obj->s.value; 4451 cpn->data = data; 4452 cpn->next = *sepol_class_perms; 4453 *sepol_class_perms = cpn; 4454 } 4455 4456 exit: 4457 cil_list_destroy(&class_list, CIL_FALSE); 4458 4459 return rc; 4460 } 4461 4462 static void __cil_init_sepol_type_set(type_set_t *t) 4463 { 4464 ebitmap_init(&t->types); 4465 ebitmap_init(&t->negset); 4466 t->flags = 0; 4467 } 4468 4469 static int __cil_add_sepol_type(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *datum, ebitmap_t *map) 4470 { 4471 int rc = SEPOL_ERR; 4472 struct cil_tree_node *n = datum->nodes->head->data; 4473 type_datum_t *sepol_datum = NULL; 4474 4475 if (n->flavor == CIL_TYPEATTRIBUTE) { 4476 ebitmap_node_t *tnode; 4477 unsigned int i; 4478 struct cil_typeattribute *attr = (struct cil_typeattribute *)datum; 4479 ebitmap_for_each_bit(attr->types, tnode, i) { 4480 if (!ebitmap_get_bit(attr->types, i)) continue; 4481 datum = DATUM(db->val_to_type[i]); 4482 rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum); 4483 if (rc != SEPOL_OK) goto exit; 4484 ebitmap_set_bit(map, sepol_datum->s.value - 1, 1); 4485 } 4486 } else { 4487 rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum); 4488 if (rc != SEPOL_OK) goto exit; 4489 ebitmap_set_bit(map, sepol_datum->s.value - 1, 1); 4490 } 4491 4492 return SEPOL_OK; 4493 4494 exit: 4495 return rc; 4496 } 4497 4498 static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *node) 4499 { 4500 avrule_t *avrule; 4501 struct cil_tree_node *source_node; 4502 char *source_path; 4503 int is_cil; 4504 4505 avrule = cil_malloc(sizeof(avrule_t)); 4506 avrule->specified = kind; 4507 avrule->flags = 0; 4508 __cil_init_sepol_type_set(&avrule->stypes); 4509 __cil_init_sepol_type_set(&avrule->ttypes); 4510 avrule->perms = NULL; 4511 avrule->line = node->line; 4512 4513 avrule->source_filename = NULL; 4514 avrule->source_line = node->line; 4515 source_node = cil_tree_get_next_path(node, &source_path, &is_cil); 4516 if (source_node) { 4517 avrule->source_filename = source_path; 4518 if (!is_cil) { 4519 avrule->source_line = node->hll_line; 4520 } 4521 } 4522 4523 avrule->next = NULL; 4524 return avrule; 4525 } 4526 4527 static void __cil_destroy_sepol_avrules(avrule_t *curr) 4528 { 4529 avrule_t *next; 4530 4531 while (curr) { 4532 next = curr->next; 4533 ebitmap_destroy(&curr->stypes.types); 4534 ebitmap_destroy(&curr->stypes.negset); 4535 ebitmap_destroy(&curr->ttypes.types); 4536 ebitmap_destroy(&curr->ttypes.negset); 4537 __cil_destroy_sepol_class_perms(curr->perms); 4538 free(curr); 4539 curr = next; 4540 } 4541 } 4542 4543 static void __cil_print_parents(const char *pad, struct cil_tree_node *n) 4544 { 4545 if (!n) return; 4546 4547 __cil_print_parents(pad, n->parent); 4548 4549 if (n->flavor != CIL_SRC_INFO) { 4550 cil_tree_log(n, CIL_ERR,"%s%s", pad, cil_node_to_string(n)); 4551 } 4552 } 4553 4554 static void __cil_print_classperm(struct cil_list *cp_list) 4555 { 4556 struct cil_list_item *i1, *i2; 4557 4558 i1 = cp_list->head; 4559 if (i1->flavor == CIL_CLASSPERMS) { 4560 struct cil_classperms *cp = i1->data; 4561 cil_log(CIL_ERR,"(%s (", DATUM(cp->class)->fqn); 4562 cil_list_for_each(i2, cp->perms) { 4563 cil_log(CIL_ERR,"%s",DATUM(i2->data)->fqn); 4564 if (i2 != cp->perms->tail) { 4565 cil_log(CIL_ERR," "); 4566 } else { 4567 cil_log(CIL_ERR,"))"); 4568 } 4569 } 4570 } else { 4571 struct cil_classperms_set *cp_set = i1->data; 4572 cil_log(CIL_ERR,"%s", DATUM(cp_set->set)->fqn); 4573 } 4574 } 4575 4576 static void __cil_print_permissionx(struct cil_permissionx *px) 4577 { 4578 const char *kind_str = ""; 4579 char *expr_str; 4580 4581 switch (px->kind) { 4582 case CIL_PERMX_KIND_IOCTL: 4583 kind_str = CIL_KEY_IOCTL; 4584 break; 4585 default: 4586 kind_str = "unknown"; 4587 break; 4588 } 4589 4590 __cil_expr_to_string(px->expr_str, CIL_PERMISSIONX, &expr_str); 4591 4592 cil_log(CIL_ERR, "%s %s (%s)", kind_str, DATUM(px->obj)->fqn, expr_str); 4593 4594 free(expr_str); 4595 } 4596 4597 static void __cil_print_rule(const char *pad, const char *kind, struct cil_avrule *avrule) 4598 { 4599 cil_log(CIL_ERR,"%s(%s ", pad, kind); 4600 cil_log(CIL_ERR,"%s %s ", DATUM(avrule->src)->fqn, DATUM(avrule->tgt)->fqn); 4601 4602 if (!avrule->is_extended) { 4603 __cil_print_classperm(avrule->perms.classperms); 4604 } else { 4605 cil_log(CIL_ERR, "("); 4606 __cil_print_permissionx(avrule->perms.x.permx); 4607 cil_log(CIL_ERR, ")"); 4608 } 4609 4610 cil_log(CIL_ERR,")\n"); 4611 } 4612 4613 static int __cil_print_neverallow_failure(const struct cil_db *db, struct cil_tree_node *node) 4614 { 4615 int rc; 4616 struct cil_list_item *i2; 4617 struct cil_list *matching; 4618 struct cil_avrule *cil_rule = node->data; 4619 struct cil_avrule target; 4620 struct cil_tree_node *n2; 4621 struct cil_avrule *r2; 4622 char *neverallow_str; 4623 char *allow_str; 4624 enum cil_flavor avrule_flavor; 4625 4626 target.rule_kind = CIL_AVRULE_ALLOWED; 4627 target.is_extended = cil_rule->is_extended; 4628 target.src = cil_rule->src; 4629 target.tgt = cil_rule->tgt; 4630 target.perms = cil_rule->perms; 4631 4632 if (!cil_rule->is_extended) { 4633 neverallow_str = CIL_KEY_NEVERALLOW; 4634 allow_str = CIL_KEY_ALLOW; 4635 avrule_flavor = CIL_AVRULE; 4636 } else { 4637 neverallow_str = CIL_KEY_NEVERALLOWX; 4638 allow_str = CIL_KEY_ALLOWX; 4639 avrule_flavor = CIL_AVRULEX; 4640 } 4641 cil_tree_log(node, CIL_ERR, "%s check failed", neverallow_str); 4642 __cil_print_rule(" ", neverallow_str, cil_rule); 4643 cil_list_init(&matching, CIL_NODE); 4644 rc = cil_find_matching_avrule_in_ast(db->ast->root, avrule_flavor, &target, matching, CIL_FALSE); 4645 if (rc) { 4646 cil_log(CIL_ERR, "Error occurred while checking %s rules\n", neverallow_str); 4647 cil_list_destroy(&matching, CIL_FALSE); 4648 goto exit; 4649 } 4650 4651 cil_list_for_each(i2, matching) { 4652 n2 = i2->data; 4653 r2 = n2->data; 4654 __cil_print_parents(" ", n2); 4655 __cil_print_rule(" ", allow_str, r2); 4656 } 4657 cil_log(CIL_ERR,"\n"); 4658 cil_list_destroy(&matching, CIL_FALSE); 4659 4660 exit: 4661 return rc; 4662 } 4663 4664 static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node, int *violation) 4665 { 4666 int rc = SEPOL_OK; 4667 struct cil_avrule *cil_rule = node->data; 4668 struct cil_symtab_datum *tgt = cil_rule->tgt; 4669 uint32_t kind; 4670 avrule_t *rule; 4671 struct cil_list *xperms = NULL; 4672 struct cil_list_item *item; 4673 4674 if (!cil_rule->is_extended) { 4675 kind = AVRULE_NEVERALLOW; 4676 } else { 4677 kind = AVRULE_XPERMS_NEVERALLOW; 4678 } 4679 4680 rule = __cil_init_sepol_avrule(kind, node); 4681 rule->next = NULL; 4682 4683 rc = __cil_add_sepol_type(pdb, db, cil_rule->src, &rule->stypes.types); 4684 if (rc != SEPOL_OK) { 4685 goto exit; 4686 } 4687 4688 if (tgt->fqn == CIL_KEY_SELF) { 4689 rule->flags = RULE_SELF; 4690 } else { 4691 rc = __cil_add_sepol_type(pdb, db, cil_rule->tgt, &rule->ttypes.types); 4692 if (rc != SEPOL_OK) { 4693 goto exit; 4694 } 4695 } 4696 4697 if (!cil_rule->is_extended) { 4698 rc = __cil_rule_to_sepol_class_perms(pdb, cil_rule->perms.classperms, &rule->perms); 4699 if (rc != SEPOL_OK) { 4700 goto exit; 4701 } 4702 4703 rc = check_assertion(pdb, rule); 4704 if (rc == CIL_TRUE) { 4705 *violation = CIL_TRUE; 4706 rc = __cil_print_neverallow_failure(db, node); 4707 if (rc != SEPOL_OK) { 4708 goto exit; 4709 } 4710 } 4711 4712 } else { 4713 rc = __cil_permx_to_sepol_class_perms(pdb, cil_rule->perms.x.permx, &rule->perms); 4714 if (rc != SEPOL_OK) { 4715 goto exit; 4716 } 4717 4718 rc = __cil_permx_bitmap_to_sepol_xperms_list(cil_rule->perms.x.permx->perms, &xperms); 4719 if (rc != SEPOL_OK) { 4720 goto exit; 4721 } 4722 4723 cil_list_for_each(item, xperms) { 4724 rule->xperms = item->data; 4725 rc = check_assertion(pdb, rule); 4726 if (rc == CIL_TRUE) { 4727 *violation = CIL_TRUE; 4728 rc = __cil_print_neverallow_failure(db, node); 4729 if (rc != SEPOL_OK) { 4730 goto exit; 4731 } 4732 } 4733 } 4734 } 4735 4736 exit: 4737 if (xperms != NULL) { 4738 cil_list_for_each(item, xperms) { 4739 free(item->data); 4740 item->data = NULL; 4741 } 4742 cil_list_destroy(&xperms, CIL_FALSE); 4743 } 4744 4745 rule->xperms = NULL; 4746 __cil_destroy_sepol_avrules(rule); 4747 4748 return rc; 4749 } 4750 4751 static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows, int *violation) 4752 { 4753 int rc = SEPOL_OK; 4754 struct cil_list_item *item; 4755 4756 cil_list_for_each(item, neverallows) { 4757 rc = cil_check_neverallow(db, pdb, item->data, violation); 4758 if (rc != SEPOL_OK) { 4759 goto exit; 4760 } 4761 } 4762 4763 exit: 4764 return rc; 4765 } 4766 4767 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[]) 4768 { 4769 struct cil_classperms *cp; 4770 struct cil_list *cp_list; 4771 class_datum_t *sepol_class = pdb->class_val_to_struct[class - 1]; 4772 unsigned i; 4773 4774 cil_classperms_init(&cp); 4775 4776 cp->class = class_value_to_cil[class]; 4777 if (!cp->class) goto exit; 4778 4779 cil_list_init(&cp->perms, CIL_PERM); 4780 for (i = 0; i < sepol_class->permissions.nprim; i++) { 4781 struct cil_perm *perm; 4782 if ((data & (1 << i)) == 0) continue; 4783 perm = perm_value_to_cil[class][i+1]; 4784 if (!perm) goto exit; 4785 cil_list_append(cp->perms, CIL_PERM, perm); 4786 } 4787 4788 cil_list_init(&cp_list, CIL_CLASSPERMS); 4789 cil_list_append(cp_list, CIL_CLASSPERMS, cp); 4790 4791 return cp_list; 4792 4793 exit: 4794 cil_log(CIL_ERR,"Failed to create CIL class-permissions from sepol values\n"); 4795 return NULL; 4796 } 4797 4798 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[]) 4799 { 4800 int rc = SEPOL_ERR; 4801 avtab_key_t *k = &sepol_rule->key; 4802 avtab_datum_t *d = &sepol_rule->datum; 4803 cil_rule->src = type_value_to_cil[k->source_type]; 4804 if (!cil_rule->src) goto exit; 4805 4806 cil_rule->tgt = type_value_to_cil[k->target_type]; 4807 if (!cil_rule->tgt) goto exit; 4808 4809 cil_rule->perms.classperms = cil_classperms_from_sepol(pdb, k->target_class, d->data, class_value_to_cil, perm_value_to_cil); 4810 if (!cil_rule->perms.classperms) goto exit; 4811 4812 return SEPOL_OK; 4813 4814 exit: 4815 cil_log(CIL_ERR,"Failed to create CIL AV rule from sepol values\n"); 4816 return rc; 4817 } 4818 4819 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) 4820 { 4821 int rc = SEPOL_OK; 4822 int i; 4823 4824 for (i = 0; i < db->num_types; i++) { 4825 type_datum_t *child; 4826 type_datum_t *parent; 4827 avtab_ptr_t bad = NULL; 4828 int numbad = 0; 4829 struct cil_type *t = db->val_to_type[i]; 4830 4831 if (!t->bounds) continue; 4832 4833 rc = __cil_get_sepol_type_datum(pdb, DATUM(t), &child); 4834 if (rc != SEPOL_OK) goto exit; 4835 4836 rc = __cil_get_sepol_type_datum(pdb, DATUM(t->bounds), &parent); 4837 if (rc != SEPOL_OK) goto exit; 4838 4839 rc = bounds_check_type(NULL, pdb, child->s.value, parent->s.value, &bad, &numbad); 4840 if (rc != SEPOL_OK) goto exit; 4841 4842 if (bad) { 4843 avtab_ptr_t cur; 4844 struct cil_avrule target; 4845 struct cil_tree_node *n1 = NULL; 4846 4847 *violation = CIL_TRUE; 4848 4849 target.is_extended = 0; 4850 target.rule_kind = CIL_AVRULE_ALLOWED; 4851 target.src_str = NULL; 4852 target.tgt_str = NULL; 4853 4854 cil_log(CIL_ERR, "Child type %s exceeds bounds of parent %s\n", 4855 t->datum.fqn, t->bounds->datum.fqn); 4856 for (cur = bad; cur; cur = cur->next) { 4857 struct cil_list_item *i2; 4858 struct cil_list *matching; 4859 4860 rc = cil_avrule_from_sepol(pdb, cur, &target, type_value_to_cil, class_value_to_cil, perm_value_to_cil); 4861 if (rc != SEPOL_OK) { 4862 cil_log(CIL_ERR, "Failed to convert sepol avrule to CIL\n"); 4863 goto exit; 4864 } 4865 __cil_print_rule(" ", "allow", &target); 4866 cil_list_init(&matching, CIL_NODE); 4867 rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_TRUE); 4868 if (rc) { 4869 cil_log(CIL_ERR, "Error occurred while checking type bounds\n"); 4870 cil_list_destroy(&matching, CIL_FALSE); 4871 cil_list_destroy(&target.perms.classperms, CIL_TRUE); 4872 bounds_destroy_bad(bad); 4873 goto exit; 4874 } 4875 cil_list_for_each(i2, matching) { 4876 struct cil_tree_node *n2 = i2->data; 4877 struct cil_avrule *r2 = n2->data; 4878 if (n1 == n2) { 4879 cil_log(CIL_ERR, " <See previous>\n"); 4880 } else { 4881 n1 = n2; 4882 __cil_print_parents(" ", n2); 4883 __cil_print_rule(" ", "allow", r2); 4884 } 4885 } 4886 cil_list_destroy(&matching, CIL_FALSE); 4887 cil_list_destroy(&target.perms.classperms, CIL_TRUE); 4888 } 4889 bounds_destroy_bad(bad); 4890 } 4891 } 4892 4893 exit: 4894 return rc; 4895 } 4896 4897 // assumes policydb is already allocated and initialized properly with things 4898 // like policy type set to kernel and version set appropriately 4899 int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *policydb) 4900 { 4901 int rc = SEPOL_ERR; 4902 int i; 4903 struct cil_args_binary extra_args; 4904 policydb_t *pdb = &policydb->p; 4905 struct cil_list *neverallows = NULL; 4906 hashtab_t filename_trans_table = NULL; 4907 hashtab_t range_trans_table = NULL; 4908 hashtab_t role_trans_table = NULL; 4909 hashtab_t avrulex_ioctl_table = NULL; 4910 void **type_value_to_cil = NULL; 4911 struct cil_class **class_value_to_cil = NULL; 4912 struct cil_perm ***perm_value_to_cil = NULL; 4913 4914 if (db == NULL || policydb == NULL) { 4915 if (db == NULL) { 4916 cil_log(CIL_ERR,"db == NULL\n"); 4917 } else if (policydb == NULL) { 4918 cil_log(CIL_ERR,"policydb == NULL\n"); 4919 } 4920 return SEPOL_ERR; 4921 } 4922 4923 /* libsepol values start at 1. Just allocate extra memory rather than 4924 * subtract 1 from the sepol value. 4925 */ 4926 type_value_to_cil = calloc(db->num_types_and_attrs+1, sizeof(*type_value_to_cil)); 4927 if (!type_value_to_cil) goto exit; 4928 4929 class_value_to_cil = calloc(db->num_classes+1, sizeof(*class_value_to_cil)); 4930 if (!class_value_to_cil) goto exit; 4931 4932 perm_value_to_cil = calloc(db->num_classes+1, sizeof(*perm_value_to_cil)); 4933 if (!perm_value_to_cil) goto exit; 4934 for (i=1; i < db->num_classes+1; i++) { 4935 perm_value_to_cil[i] = calloc(PERMS_PER_CLASS+1, sizeof(*perm_value_to_cil[i])); 4936 if (!perm_value_to_cil[i]) goto exit; 4937 } 4938 4939 rc = __cil_policydb_init(pdb, db, class_value_to_cil, perm_value_to_cil); 4940 if (rc != SEPOL_OK) { 4941 cil_log(CIL_ERR,"Problem in policydb_init\n"); 4942 goto exit; 4943 } 4944 4945 filename_trans_table = hashtab_create(filename_trans_hash, filename_trans_compare, FILENAME_TRANS_TABLE_SIZE); 4946 if (!filename_trans_table) { 4947 cil_log(CIL_INFO, "Failure to create hashtab for filename_trans\n"); 4948 goto exit; 4949 } 4950 4951 range_trans_table = hashtab_create(range_trans_hash, range_trans_compare, RANGE_TRANS_TABLE_SIZE); 4952 if (!range_trans_table) { 4953 cil_log(CIL_INFO, "Failure to create hashtab for range_trans\n"); 4954 goto exit; 4955 } 4956 4957 role_trans_table = hashtab_create(role_trans_hash, role_trans_compare, ROLE_TRANS_TABLE_SIZE); 4958 if (!role_trans_table) { 4959 cil_log(CIL_INFO, "Failure to create hashtab for role_trans\n"); 4960 goto exit; 4961 } 4962 4963 avrulex_ioctl_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE); 4964 if (!avrulex_ioctl_table) { 4965 cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n"); 4966 goto exit; 4967 } 4968 4969 cil_list_init(&neverallows, CIL_LIST_ITEM); 4970 4971 extra_args.db = db; 4972 extra_args.pdb = pdb; 4973 extra_args.neverallows = neverallows; 4974 extra_args.filename_trans_table = filename_trans_table; 4975 extra_args.range_trans_table = range_trans_table; 4976 extra_args.role_trans_table = role_trans_table; 4977 extra_args.avrulex_ioctl_table = avrulex_ioctl_table; 4978 extra_args.type_value_to_cil = type_value_to_cil; 4979 4980 for (i = 1; i <= 3; i++) { 4981 extra_args.pass = i; 4982 4983 rc = cil_tree_walk(db->ast->root, __cil_binary_create_helper, NULL, NULL, &extra_args); 4984 if (rc != SEPOL_OK) { 4985 cil_log(CIL_INFO, "Failure while walking cil database\n"); 4986 goto exit; 4987 } 4988 4989 if (i == 1) { 4990 rc = __cil_policydb_val_arrays_create(pdb); 4991 if (rc != SEPOL_OK) { 4992 cil_log(CIL_INFO, "Failure creating val_to_{struct,name} arrays\n"); 4993 goto exit; 4994 } 4995 } 4996 4997 if (i == 3) { 4998 rc = hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_to_policydb, pdb); 4999 if (rc != SEPOL_OK) { 5000 cil_log(CIL_INFO, "Failure creating avrulex rules\n"); 5001 goto exit; 5002 } 5003 } 5004 } 5005 5006 rc = cil_sidorder_to_policydb(pdb, db); 5007 if (rc != SEPOL_OK) { 5008 goto exit; 5009 } 5010 5011 rc = __cil_contexts_to_policydb(pdb, db); 5012 if (rc != SEPOL_OK) { 5013 cil_log(CIL_INFO, "Failure while inserting cil contexts into sepol policydb\n"); 5014 goto exit; 5015 } 5016 5017 if (pdb->type_attr_map == NULL) { 5018 rc = __cil_typeattr_bitmap_init(pdb); 5019 if (rc != SEPOL_OK) { 5020 cil_log(CIL_INFO, "Failure while initializing typeattribute bitmap\n"); 5021 goto exit; 5022 } 5023 } 5024 5025 cond_optimize_lists(pdb->cond_list); 5026 __cil_set_conditional_state_and_flags(pdb); 5027 5028 if (db->disable_neverallow != CIL_TRUE) { 5029 int violation = CIL_FALSE; 5030 cil_log(CIL_INFO, "Checking Neverallows\n"); 5031 rc = cil_check_neverallows(db, pdb, neverallows, &violation); 5032 if (rc != SEPOL_OK) goto exit; 5033 5034 cil_log(CIL_INFO, "Checking User Bounds\n"); 5035 rc = bounds_check_users(NULL, pdb); 5036 if (rc) { 5037 violation = CIL_TRUE; 5038 } 5039 5040 cil_log(CIL_INFO, "Checking Role Bounds\n"); 5041 rc = bounds_check_roles(NULL, pdb); 5042 if (rc) { 5043 violation = CIL_TRUE; 5044 } 5045 5046 cil_log(CIL_INFO, "Checking Type Bounds\n"); 5047 rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil, &violation); 5048 if (rc != SEPOL_OK) goto exit; 5049 5050 if (violation == CIL_TRUE) { 5051 rc = SEPOL_ERR; 5052 goto exit; 5053 } 5054 5055 } 5056 5057 /* This pre-expands the roles and users for context validity checking */ 5058 if (hashtab_map(pdb->p_roles.table, policydb_role_cache, pdb)) { 5059 cil_log(CIL_INFO, "Failure creating roles cache"); 5060 rc = SEPOL_ERR; 5061 goto exit; 5062 } 5063 5064 if (hashtab_map(pdb->p_users.table, policydb_user_cache, pdb)) { 5065 cil_log(CIL_INFO, "Failure creating users cache"); 5066 rc = SEPOL_ERR; 5067 goto exit; 5068 } 5069 5070 rc = SEPOL_OK; 5071 5072 exit: 5073 hashtab_destroy(filename_trans_table); 5074 hashtab_destroy(range_trans_table); 5075 hashtab_destroy(role_trans_table); 5076 hashtab_destroy(avrulex_ioctl_table); 5077 free(type_value_to_cil); 5078 free(class_value_to_cil); 5079 /* Range is because libsepol values start at 1. */ 5080 for (i=1; i < db->num_classes+1; i++) { 5081 free(perm_value_to_cil[i]); 5082 } 5083 free(perm_value_to_cil); 5084 cil_list_destroy(&neverallows, CIL_FALSE); 5085 5086 return rc; 5087 } 5088