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