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