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