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