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 <string.h>
     33 #include <stdint.h>
     34 #include <unistd.h>
     35 
     36 #include <sepol/policydb/conditional.h>
     37 #include <sepol/errcodes.h>
     38 
     39 #include "cil_internal.h"
     40 #include "cil_flavor.h"
     41 #include "cil_log.h"
     42 #include "cil_mem.h"
     43 #include "cil_tree.h"
     44 #include "cil_list.h"
     45 #include "cil_post.h"
     46 #include "cil_policy.h"
     47 #include "cil_verify.h"
     48 #include "cil_symtab.h"
     49 
     50 #define GEN_REQUIRE_ATTR "cil_gen_require" /* Also in libsepol/src/module_to_cil.c */
     51 #define TYPEATTR_INFIX "_typeattr_"        /* Also in libsepol/src/module_to_cil.c */
     52 
     53 static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db);
     54 static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db);
     55 
     56 static int cil_verify_is_list(struct cil_list *list, enum cil_flavor flavor)
     57 {
     58 	struct cil_list_item *curr;
     59 
     60 	cil_list_for_each(curr, list) {
     61 		switch (curr->flavor) {
     62 		case CIL_LIST:
     63 			return CIL_FALSE;
     64 			break;
     65 		case CIL_OP:
     66 			return CIL_FALSE;
     67 			break;
     68 		default:
     69 			if (flavor == CIL_CAT) {
     70 				struct cil_symtab_datum *d = curr->data;
     71 				struct cil_tree_node *n = d->nodes->head->data;
     72 				if (n->flavor == CIL_CATSET) {
     73 					return CIL_FALSE;
     74 				}
     75 			}
     76 			break;
     77 		}
     78 	}
     79 	return CIL_TRUE;
     80 }
     81 
     82 void cil_post_fc_fill_data(struct fc_data *fc, char *path)
     83 {
     84 	int c = 0;
     85 	fc->meta = 0;
     86 	fc->stem_len = 0;
     87 	fc->str_len = 0;
     88 
     89 	while (path[c] != '\0') {
     90 		switch (path[c]) {
     91 		case '.':
     92 		case '^':
     93 		case '$':
     94 		case '?':
     95 		case '*':
     96 		case '+':
     97 		case '|':
     98 		case '[':
     99 		case '(':
    100 		case '{':
    101 			fc->meta = 1;
    102 			break;
    103 		case '\\':
    104 			c++;
    105 		default:
    106 			if (!fc->meta) {
    107 				fc->stem_len++;
    108 			}
    109 			break;
    110 		}
    111 		fc->str_len++;
    112 		c++;
    113 	}
    114 }
    115 
    116 int cil_post_filecon_compare(const void *a, const void *b)
    117 {
    118 	int rc = 0;
    119 	struct cil_filecon *a_filecon = *(struct cil_filecon**)a;
    120 	struct cil_filecon *b_filecon = *(struct cil_filecon**)b;
    121 	struct fc_data *a_data = cil_malloc(sizeof(*a_data));
    122 	struct fc_data *b_data = cil_malloc(sizeof(*b_data));
    123 	char *a_path = cil_malloc(strlen(a_filecon->path_str) + 1);
    124 	a_path[0] = '\0';
    125 	char *b_path = cil_malloc(strlen(b_filecon->path_str) + 1);
    126 	b_path[0] = '\0';
    127 	strcat(a_path, a_filecon->path_str);
    128 	strcat(b_path, b_filecon->path_str);
    129 	cil_post_fc_fill_data(a_data, a_path);
    130 	cil_post_fc_fill_data(b_data, b_path);
    131 	if (a_data->meta && !b_data->meta) {
    132 		rc = -1;
    133 	} else if (b_data->meta && !a_data->meta) {
    134 		rc = 1;
    135 	} else if (a_data->stem_len < b_data->stem_len) {
    136 		rc = -1;
    137 	} else if (b_data->stem_len < a_data->stem_len) {
    138 		rc = 1;
    139 	} else if (a_data->str_len < b_data->str_len) {
    140 		rc = -1;
    141 	} else if (b_data->str_len < a_data->str_len) {
    142 		rc = 1;
    143 	} else if (a_filecon->type < b_filecon->type) {
    144 		rc = -1;
    145 	} else if (b_filecon->type < a_filecon->type) {
    146 		rc = 1;
    147 	}
    148 
    149 	free(a_path);
    150 	free(b_path);
    151 	free(a_data);
    152 	free(b_data);
    153 
    154 	return rc;
    155 }
    156 
    157 int cil_post_portcon_compare(const void *a, const void *b)
    158 {
    159 	int rc = SEPOL_ERR;
    160 	struct cil_portcon *aportcon = *(struct cil_portcon**)a;
    161 	struct cil_portcon *bportcon = *(struct cil_portcon**)b;
    162 
    163 	rc = (aportcon->port_high - aportcon->port_low)
    164 		- (bportcon->port_high - bportcon->port_low);
    165 	if (rc == 0) {
    166 		if (aportcon->port_low < bportcon->port_low) {
    167 			rc = -1;
    168 		} else if (bportcon->port_low < aportcon->port_low) {
    169 			rc = 1;
    170 		}
    171 	}
    172 
    173 	return rc;
    174 }
    175 
    176 int cil_post_genfscon_compare(const void *a, const void *b)
    177 {
    178 	int rc = SEPOL_ERR;
    179 	struct cil_genfscon *agenfscon = *(struct cil_genfscon**)a;
    180 	struct cil_genfscon *bgenfscon = *(struct cil_genfscon**)b;
    181 
    182 	rc = strcmp(agenfscon->fs_str, bgenfscon->fs_str);
    183 	if (rc == 0) {
    184 		rc = strcmp(agenfscon->path_str, bgenfscon->path_str);
    185 	}
    186 
    187 	return rc;
    188 }
    189 
    190 int cil_post_netifcon_compare(const void *a, const void *b)
    191 {
    192 	struct cil_netifcon *anetifcon = *(struct cil_netifcon**)a;
    193 	struct cil_netifcon *bnetifcon = *(struct cil_netifcon**)b;
    194 
    195 	return  strcmp(anetifcon->interface_str, bnetifcon->interface_str);
    196 }
    197 
    198 int cil_post_nodecon_compare(const void *a, const void *b)
    199 {
    200 	struct cil_nodecon *anodecon;
    201 	struct cil_nodecon *bnodecon;
    202 	anodecon = *(struct cil_nodecon**)a;
    203 	bnodecon = *(struct cil_nodecon**)b;
    204 
    205 	/* sort ipv4 before ipv6 */
    206 	if (anodecon->addr->family != bnodecon->addr->family) {
    207 		if (anodecon->addr->family == AF_INET) {
    208 			return -1;
    209 		} else {
    210 			return 1;
    211 		}
    212 	}
    213 
    214 	/* most specific netmask goes first, then order by ip addr */
    215 	if (anodecon->addr->family == AF_INET) {
    216 		int rc = memcmp(&anodecon->mask->ip.v4, &bnodecon->mask->ip.v4, sizeof(anodecon->mask->ip.v4));
    217 		if (rc != 0) {
    218 			return -1 * rc;
    219 		}
    220 		return memcmp(&anodecon->addr->ip.v4, &bnodecon->addr->ip.v4, sizeof(anodecon->addr->ip.v4));
    221 	} else {
    222 		int rc = memcmp(&anodecon->mask->ip.v6, &bnodecon->mask->ip.v6, sizeof(anodecon->mask->ip.v6));
    223 		if (rc != 0) {
    224 			return -1 * rc;
    225 		}
    226 		return memcmp(&anodecon->addr->ip.v6, &bnodecon->addr->ip.v6, sizeof(anodecon->addr->ip.v6));
    227 	}
    228 }
    229 
    230 int cil_post_pirqcon_compare(const void *a, const void *b)
    231 {
    232 	int rc = SEPOL_ERR;
    233 	struct cil_pirqcon *apirqcon = *(struct cil_pirqcon**)a;
    234 	struct cil_pirqcon *bpirqcon = *(struct cil_pirqcon**)b;
    235 
    236 	if (apirqcon->pirq < bpirqcon->pirq) {
    237 		rc = -1;
    238 	} else if (bpirqcon->pirq < apirqcon->pirq) {
    239 		rc = 1;
    240 	} else {
    241 		rc = 0;
    242 	}
    243 
    244 	return rc;
    245 }
    246 
    247 int cil_post_iomemcon_compare(const void *a, const void *b)
    248 {
    249 	int rc = SEPOL_ERR;
    250 	struct cil_iomemcon *aiomemcon = *(struct cil_iomemcon**)a;
    251 	struct cil_iomemcon *biomemcon = *(struct cil_iomemcon**)b;
    252 
    253 	rc = (aiomemcon->iomem_high - aiomemcon->iomem_low)
    254 		- (biomemcon->iomem_high - biomemcon->iomem_low);
    255 	if (rc == 0) {
    256 		if (aiomemcon->iomem_low < biomemcon->iomem_low) {
    257 			rc = -1;
    258 		} else if (biomemcon->iomem_low < aiomemcon->iomem_low) {
    259 			rc = 1;
    260 		}
    261 	}
    262 
    263 	return rc;
    264 }
    265 
    266 int cil_post_ioportcon_compare(const void *a, const void *b)
    267 {
    268 	int rc = SEPOL_ERR;
    269 	struct cil_ioportcon *aioportcon = *(struct cil_ioportcon**)a;
    270 	struct cil_ioportcon *bioportcon = *(struct cil_ioportcon**)b;
    271 
    272 	rc = (aioportcon->ioport_high - aioportcon->ioport_low)
    273 		- (bioportcon->ioport_high - bioportcon->ioport_low);
    274 	if (rc == 0) {
    275 		if (aioportcon->ioport_low < bioportcon->ioport_low) {
    276 			rc = -1;
    277 		} else if (bioportcon->ioport_low < aioportcon->ioport_low) {
    278 			rc = 1;
    279 		}
    280 	}
    281 
    282 	return rc;
    283 }
    284 
    285 int cil_post_pcidevicecon_compare(const void *a, const void *b)
    286 {
    287 	int rc = SEPOL_ERR;
    288 	struct cil_pcidevicecon *apcidevicecon = *(struct cil_pcidevicecon**)a;
    289 	struct cil_pcidevicecon *bpcidevicecon = *(struct cil_pcidevicecon**)b;
    290 
    291 	if (apcidevicecon->dev < bpcidevicecon->dev) {
    292 		rc = -1;
    293 	} else if (bpcidevicecon->dev < apcidevicecon->dev) {
    294 		rc = 1;
    295 	} else {
    296 		rc = 0;
    297 	}
    298 
    299 	return rc;
    300 }
    301 
    302 int cil_post_devicetreecon_compare(const void *a, const void *b)
    303 {
    304 	int rc = SEPOL_ERR;
    305 	struct cil_devicetreecon *adevicetreecon = *(struct cil_devicetreecon**)a;
    306 	struct cil_devicetreecon *bdevicetreecon = *(struct cil_devicetreecon**)b;
    307 
    308 	rc = strcmp(adevicetreecon->path, bdevicetreecon->path);
    309 
    310 	return rc;
    311 }
    312 
    313 int cil_post_fsuse_compare(const void *a, const void *b)
    314 {
    315 	int rc;
    316 	struct cil_fsuse *afsuse;
    317 	struct cil_fsuse *bfsuse;
    318 	afsuse = *(struct cil_fsuse**)a;
    319 	bfsuse = *(struct cil_fsuse**)b;
    320 	if (afsuse->type < bfsuse->type) {
    321 		rc = -1;
    322 	} else if (bfsuse->type < afsuse->type) {
    323 		rc = 1;
    324 	} else {
    325 		rc = strcmp(afsuse->fs_str, bfsuse->fs_str);
    326 	}
    327 	return rc;
    328 }
    329 
    330 static int __cil_post_db_count_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
    331 {
    332 	struct cil_db *db = extra_args;
    333 
    334 	switch(node->flavor) {
    335 	case CIL_BLOCK: {
    336 		struct cil_block *blk = node->data;
    337 		if (blk->is_abstract == CIL_TRUE) {
    338 			*finished = CIL_TREE_SKIP_HEAD;
    339 		}
    340 		break;
    341 	}
    342 	case CIL_MACRO:
    343 		*finished = CIL_TREE_SKIP_HEAD;
    344 		break;
    345 	case CIL_CLASS: {
    346 		struct cil_class *class = node->data;
    347 		if (class->datum.nodes->head->data == node) {
    348 			// Multiple nodes can point to the same datum. Only count once.
    349 			db->num_classes++;
    350 		}
    351 		break;
    352 	}
    353 	case CIL_TYPE: {
    354 		struct cil_type *type = node->data;
    355 		if (type->datum.nodes->head->data == node) {
    356 			// Multiple nodes can point to the same datum. Only count once.
    357 			type->value = db->num_types;
    358 			db->num_types++;
    359 			db->num_types_and_attrs++;
    360 		}
    361 		break;
    362 	}
    363 	case CIL_TYPEATTRIBUTE: {
    364 		struct cil_typeattribute *attr = node->data;
    365 		if (attr->datum.nodes->head->data == node) {
    366 			// Multiple nodes can point to the same datum. Only count once.
    367 			db->num_types_and_attrs++;
    368 		}
    369 		break;
    370 	}
    371 
    372 	case CIL_ROLE: {
    373 		struct cil_role *role = node->data;
    374 		if (role->datum.nodes->head->data == node) {
    375 			// Multiple nodes can point to the same datum. Only count once.
    376 			role->value = db->num_roles;
    377 			db->num_roles++;
    378 		}
    379 		break;
    380 	}
    381 	case CIL_USER: {
    382 		struct cil_user *user = node->data;
    383 		if (user->datum.nodes->head->data == node) {
    384 			// multiple AST nodes can point to the same cil_user data (like if
    385 			// copied from a macro). This check ensures we only count the
    386 			// duplicates once
    387 			user->value = db->num_users;
    388 			db->num_users++;
    389 		}
    390 		break;
    391 	}
    392 	case CIL_NETIFCON:
    393 		db->netifcon->count++;
    394 		break;
    395 	case CIL_GENFSCON:
    396 		db->genfscon->count++;
    397 		break;
    398 	case CIL_FILECON:
    399 		db->filecon->count++;
    400 		break;
    401 	case CIL_NODECON:
    402 		db->nodecon->count++;
    403 		break;
    404 	case CIL_PORTCON:
    405 		db->portcon->count++;
    406 		break;
    407 	case CIL_PIRQCON:
    408 		db->pirqcon->count++;
    409 		break;
    410 	case CIL_IOMEMCON:
    411 		db->iomemcon->count++;
    412 		break;
    413 	case CIL_IOPORTCON:
    414 		db->ioportcon->count++;
    415 		break;
    416 	case CIL_PCIDEVICECON:
    417 		db->pcidevicecon->count++;
    418 		break;
    419 	case CIL_DEVICETREECON:
    420 		db->devicetreecon->count++;
    421 		break;
    422 	case CIL_FSUSE:
    423 		db->fsuse->count++;
    424 		break;
    425 	default:
    426 		break;
    427 	}
    428 
    429 	return SEPOL_OK;
    430 }
    431 
    432 static int __cil_post_db_array_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
    433 {
    434 	struct cil_db *db = extra_args;
    435 
    436 	switch(node->flavor) {
    437 	case CIL_BLOCK: {
    438 		struct cil_block *blk = node->data;
    439 		if (blk->is_abstract == CIL_TRUE) {
    440 			*finished = CIL_TREE_SKIP_HEAD;
    441 		}
    442 		break;
    443 	}
    444 	case CIL_MACRO:
    445 		*finished = CIL_TREE_SKIP_HEAD;
    446 		break;
    447 	case CIL_TYPE: {
    448 		struct cil_type *type = node->data;
    449 		if (db->val_to_type == NULL) {
    450 			db->val_to_type = cil_malloc(sizeof(*db->val_to_type) * db->num_types);
    451 		}
    452 		db->val_to_type[type->value] = type;
    453 		break;
    454 	}
    455 	case CIL_ROLE: {
    456 		struct cil_role *role = node->data;
    457 		if (db->val_to_role == NULL) {
    458 			db->val_to_role = cil_malloc(sizeof(*db->val_to_role) * db->num_roles);
    459 		}
    460 		db->val_to_role[role->value] = role;
    461 		break;
    462 	}
    463 	case CIL_USER: {
    464 		struct cil_user *user= node->data;
    465 		if (db->val_to_user == NULL) {
    466 			db->val_to_user = cil_malloc(sizeof(*db->val_to_user) * db->num_users);
    467 		}
    468 		db->val_to_user[user->value] = user;
    469 		break;
    470 	}
    471 	case CIL_USERPREFIX: {
    472 		cil_list_append(db->userprefixes, CIL_USERPREFIX, node->data);
    473 		break;
    474 	}
    475 	case CIL_SELINUXUSER: {
    476 		cil_list_prepend(db->selinuxusers, CIL_SELINUXUSER, node->data);
    477 		break;
    478 	}
    479 	case CIL_SELINUXUSERDEFAULT: {
    480 		cil_list_append(db->selinuxusers, CIL_SELINUXUSERDEFAULT, node->data);
    481 		break;
    482 	}
    483 	case CIL_NETIFCON: {
    484 		struct cil_sort *sort = db->netifcon;
    485 		uint32_t count = sort->count;
    486 		uint32_t i = sort->index;
    487 		if (sort->array == NULL) {
    488 			sort->array = cil_malloc(sizeof(*sort->array)*count);
    489 		}
    490 		sort->array[i] = node->data;
    491 		sort->index++;
    492 		break;
    493 	}
    494 	case CIL_FSUSE: {
    495 		struct cil_sort *sort = db->fsuse;
    496 		uint32_t count = sort->count;
    497 		uint32_t i = sort->index;
    498 		if (sort->array == NULL) {
    499 			sort->array = cil_malloc(sizeof(*sort->array)*count);
    500 		}
    501 		sort->array[i] = node->data;
    502 		sort->index++;
    503 		break;
    504 	}
    505 	case CIL_GENFSCON: {
    506 		struct cil_sort *sort = db->genfscon;
    507 		uint32_t count = sort->count;
    508 		uint32_t i = sort->index;
    509 		if (sort->array == NULL) {
    510 			sort->array = cil_malloc(sizeof(*sort->array)*count);
    511 		}
    512 		sort->array[i] = node->data;
    513 		sort->index++;
    514 		break;
    515 	}
    516 	case CIL_FILECON: {
    517 		struct cil_sort *sort = db->filecon;
    518 		uint32_t count = sort->count;
    519 		uint32_t i = sort->index;
    520 		if (sort->array == NULL) {
    521 		sort->array = cil_malloc(sizeof(*sort->array)*count);
    522 		}
    523 		sort->array[i] = node->data;
    524 		sort->index++;
    525 		break;
    526 	}
    527 	case CIL_NODECON: {
    528 		struct cil_sort *sort = db->nodecon;
    529 		uint32_t count = sort->count;
    530 		uint32_t i = sort->index;
    531 		if (sort->array == NULL) {
    532 			sort->array = cil_malloc(sizeof(*sort->array)*count);
    533 		}
    534 		sort->array[i] = node->data;
    535 		sort->index++;
    536 		break;
    537 	}
    538 	case CIL_PORTCON: {
    539 		struct cil_sort *sort = db->portcon;
    540 		uint32_t count = sort->count;
    541 		uint32_t i = sort->index;
    542 		if (sort->array == NULL) {
    543 			sort->array = cil_malloc(sizeof(*sort->array)*count);
    544 		}
    545 		sort->array[i] = node->data;
    546 		sort->index++;
    547 		break;
    548 	}
    549 	case CIL_PIRQCON: {
    550 		struct cil_sort *sort = db->pirqcon;
    551 		uint32_t count = sort->count;
    552 		uint32_t i = sort->index;
    553 		if (sort->array == NULL) {
    554 			sort->array = cil_malloc(sizeof(*sort->array)*count);
    555 		}
    556 		sort->array[i] = node->data;
    557 		sort->index++;
    558 		break;
    559 	}
    560 	case CIL_IOMEMCON: {
    561 		struct cil_sort *sort = db->iomemcon;
    562 		uint32_t count = sort->count;
    563 		uint32_t i = sort->index;
    564 		if (sort->array == NULL) {
    565 			sort->array = cil_malloc(sizeof(*sort->array)*count);
    566 		}
    567 		sort->array[i] = node->data;
    568 		sort->index++;
    569 		break;
    570 	}
    571 	case CIL_IOPORTCON: {
    572 		struct cil_sort *sort = db->ioportcon;
    573 		uint32_t count = sort->count;
    574 		uint32_t i = sort->index;
    575 		if (sort->array == NULL) {
    576 			sort->array = cil_malloc(sizeof(*sort->array)*count);
    577 		}
    578 		sort->array[i] = node->data;
    579 		sort->index++;
    580 		break;
    581 	}
    582 	case CIL_PCIDEVICECON: {
    583 		struct cil_sort *sort = db->pcidevicecon;
    584 		uint32_t count = sort->count;
    585 		uint32_t i = sort->index;
    586 		if (sort->array == NULL) {
    587 			sort->array = cil_malloc(sizeof(*sort->array)*count);
    588 		}
    589 		sort->array[i] = node->data;
    590 		sort->index++;
    591 		break;
    592 	}
    593 	case CIL_DEVICETREECON: {
    594 		struct cil_sort *sort = db->devicetreecon;
    595 		uint32_t count = sort->count;
    596 		uint32_t i = sort->index;
    597 		if (sort->array == NULL) {
    598 			sort->array = cil_malloc(sizeof(*sort->array)*count);
    599 		}
    600 		sort->array[i] = node->data;
    601 		sort->index++;
    602 		break;
    603 	}
    604 	default:
    605 		break;
    606 	}
    607 
    608 	return SEPOL_OK;
    609 }
    610 
    611 static int __evaluate_type_expression(struct cil_typeattribute *attr, struct cil_db *db)
    612 {
    613 	int rc;
    614 
    615 	attr->types = cil_malloc(sizeof(*attr->types));
    616 	rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->types, db->num_types, db);
    617 	if (rc != SEPOL_OK) {
    618 		cil_log(CIL_ERR, "Failed to expand type attribute to bitmap\n");
    619 		ebitmap_destroy(attr->types);
    620 		free(attr->types);
    621 		attr->types = NULL;
    622 	}
    623 	return rc;
    624 }
    625 
    626 static int __cil_type_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db)
    627 {
    628 	int rc = SEPOL_ERR;
    629 	struct cil_tree_node *node = datum->nodes->head->data;
    630 
    631 	ebitmap_init(bitmap);
    632 
    633 	if (node->flavor == CIL_TYPEATTRIBUTE) {
    634 		struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
    635 		if (attr->types == NULL) {
    636 			rc = __evaluate_type_expression(attr, db);
    637 			if (rc != SEPOL_OK) goto exit;
    638 		}
    639 		ebitmap_union(bitmap, attr->types);
    640 	} else if (node->flavor == CIL_TYPEALIAS) {
    641 		struct cil_alias *alias = (struct cil_alias *)datum;
    642 		struct cil_type *type = alias->actual;
    643 		if (ebitmap_set_bit(bitmap, type->value, 1)) {
    644 			cil_log(CIL_ERR, "Failed to set type bit\n");
    645 			ebitmap_destroy(bitmap);
    646 			goto exit;
    647 		}
    648 	} else {
    649 		struct cil_type *type = (struct cil_type *)datum;
    650 		if (ebitmap_set_bit(bitmap, type->value, 1)) {
    651 			cil_log(CIL_ERR, "Failed to set type bit\n");
    652 			ebitmap_destroy(bitmap);
    653 			goto exit;
    654 		}
    655 	}
    656 
    657 	return SEPOL_OK;
    658 
    659 exit:
    660 	return rc;
    661 }
    662 
    663 static int __evaluate_user_expression(struct cil_userattribute *attr, struct cil_db *db)
    664 {
    665 	int rc;
    666 
    667 	attr->users = cil_malloc(sizeof(*attr->users));
    668 	rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->users, db->num_users, db);
    669 	if (rc != SEPOL_OK) {
    670 		cil_log(CIL_ERR, "Failed to expand user attribute to bitmap\n");
    671 		ebitmap_destroy(attr->users);
    672 		free(attr->users);
    673 		attr->users = NULL;
    674 	}
    675 	return rc;
    676 }
    677 
    678 static int __cil_user_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db)
    679 {
    680 	int rc = SEPOL_ERR;
    681 	struct cil_tree_node *node = datum->nodes->head->data;
    682 	struct cil_userattribute *attr = NULL;
    683 	struct cil_user *user = NULL;
    684 
    685 	ebitmap_init(bitmap);
    686 
    687 	if (node->flavor == CIL_USERATTRIBUTE) {
    688 		attr = (struct cil_userattribute *)datum;
    689 		if (attr->users == NULL) {
    690 			rc = __evaluate_user_expression(attr, db);
    691 			if (rc != SEPOL_OK) {
    692 				goto exit;
    693 			}
    694 		}
    695 		ebitmap_union(bitmap, attr->users);
    696 	} else {
    697 		user = (struct cil_user *)datum;
    698 		if (ebitmap_set_bit(bitmap, user->value, 1)) {
    699 			cil_log(CIL_ERR, "Failed to set user bit\n");
    700 			ebitmap_destroy(bitmap);
    701 			goto exit;
    702 		}
    703 	}
    704 
    705 	return SEPOL_OK;
    706 
    707 exit:
    708 	return rc;
    709 }
    710 
    711 static int __evaluate_role_expression(struct cil_roleattribute *attr, struct cil_db *db)
    712 {
    713 	int rc;
    714 
    715 	attr->roles = cil_malloc(sizeof(*attr->roles));
    716 	rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->roles, db->num_roles, db);
    717 	if (rc != SEPOL_OK) {
    718 		cil_log(CIL_ERR, "Failed to expand role attribute to bitmap\n");
    719 		ebitmap_destroy(attr->roles);
    720 		free(attr->roles);
    721 		attr->roles = NULL;
    722 	}
    723 	return rc;
    724 }
    725 
    726 static int __cil_role_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db)
    727 {
    728 	int rc = SEPOL_ERR;
    729 	struct cil_tree_node *node = datum->nodes->head->data;
    730 
    731 	ebitmap_init(bitmap);
    732 
    733 	if (node->flavor == CIL_ROLEATTRIBUTE) {
    734 		struct cil_roleattribute *attr = (struct cil_roleattribute *)datum;
    735 		if (attr->roles == NULL) {
    736 			rc = __evaluate_role_expression(attr, db);
    737 			if (rc != SEPOL_OK) goto exit;
    738 		}
    739 		ebitmap_union(bitmap, attr->roles);
    740 	} else {
    741 		struct cil_role *role = (struct cil_role *)datum;
    742 		if (ebitmap_set_bit(bitmap, role->value, 1)) {
    743 			cil_log(CIL_ERR, "Failed to set role bit\n");
    744 			ebitmap_destroy(bitmap);
    745 			goto exit;
    746 		}
    747 	}
    748 
    749 	return SEPOL_OK;
    750 
    751 exit:
    752 	return rc;
    753 }
    754 
    755 static int __evaluate_permissionx_expression(struct cil_permissionx *permx, struct cil_db *db)
    756 {
    757 	int rc;
    758 
    759 	permx->perms = cil_malloc(sizeof(*permx->perms));
    760 	ebitmap_init(permx->perms);
    761 
    762 	rc = __cil_expr_to_bitmap(permx->expr_str, permx->perms, 0x10000, db); // max is one more than 0xFFFF
    763 	if (rc != SEPOL_OK) {
    764 		cil_log(CIL_ERR, "Failed to expand permissionx expression\n");
    765 		ebitmap_destroy(permx->perms);
    766 		free(permx->perms);
    767 		permx->perms = NULL;
    768 	}
    769 
    770 	return rc;
    771 }
    772 
    773 static int __cil_permx_str_to_int(char *permx_str, uint16_t *val)
    774 {
    775 	char *endptr = NULL;
    776 	long lval = strtol(permx_str, &endptr, 0);
    777 
    778 	if (*endptr != '\0') {
    779 		cil_log(CIL_ERR, "permissionx value %s not valid number\n", permx_str);
    780 		goto exit;
    781 	}
    782 	if (lval < 0x0000 || lval > 0xFFFF) {
    783 		cil_log(CIL_ERR, "permissionx value %s must be between 0x0000 and 0xFFFF\n", permx_str);
    784 		goto exit;
    785 	}
    786 
    787 	*val = (uint16_t)lval;
    788 
    789 	return SEPOL_OK;
    790 
    791 exit:
    792 	return SEPOL_ERR;
    793 }
    794 
    795 static int __cil_permx_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db)
    796 {
    797 	int rc = SEPOL_ERR;
    798 	uint16_t val;
    799 
    800 	rc = __cil_permx_str_to_int((char*)datum, &val);
    801 	if (rc != SEPOL_OK) {
    802 		goto exit;
    803 	}
    804 
    805 	ebitmap_init(bitmap);
    806 	if (ebitmap_set_bit(bitmap, (unsigned int)val, 1)) {
    807 		cil_log(CIL_ERR, "Failed to set permissionx bit\n");
    808 		ebitmap_destroy(bitmap);
    809 		goto exit;
    810 	}
    811 
    812 	return SEPOL_OK;
    813 
    814 exit:
    815 	return rc;
    816 }
    817 
    818 static int __cil_perm_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db)
    819 {
    820 	struct cil_perm *perm = (struct cil_perm *)datum;
    821 	unsigned int value = perm->value;
    822 
    823 	ebitmap_init(bitmap);
    824 	if (ebitmap_set_bit(bitmap, value, 1)) {
    825 		cil_log(CIL_INFO, "Failed to set perm bit\n");
    826 		ebitmap_destroy(bitmap);
    827 		return SEPOL_ERR;
    828 	}
    829 
    830 	return SEPOL_OK;
    831 }
    832 
    833 static int __evaluate_cat_expression(struct cil_cats *cats, struct cil_db *db)
    834 {
    835 	int rc = SEPOL_ERR;
    836 	ebitmap_t bitmap;
    837 	struct cil_list *new;
    838 	struct cil_list_item *curr;
    839 
    840 	if (cats->evaluated == CIL_TRUE) {
    841 		return SEPOL_OK;
    842 	}
    843 
    844 	if (cil_verify_is_list(cats->datum_expr, CIL_CAT)) {
    845 		return SEPOL_OK;
    846 	}
    847 
    848 	ebitmap_init(&bitmap);
    849 	rc = __cil_expr_to_bitmap(cats->datum_expr, &bitmap, db->num_cats, db);
    850 	if (rc != SEPOL_OK) {
    851 		cil_log(CIL_ERR, "Failed to expand category expression to bitmap\n");
    852 		ebitmap_destroy(&bitmap);
    853 		goto exit;
    854 	}
    855 
    856 	cil_list_init(&new, CIL_CAT);
    857 
    858 	cil_list_for_each(curr, db->catorder) {
    859 		struct cil_cat *cat = curr->data;
    860 		if (ebitmap_get_bit(&bitmap, cat->value)) {
    861 			cil_list_append(new, CIL_DATUM, cat);
    862 		}
    863 	}
    864 
    865 	ebitmap_destroy(&bitmap);
    866 	cil_list_destroy(&cats->datum_expr, CIL_FALSE);
    867 	cats->datum_expr = new;
    868 
    869 	cats->evaluated = CIL_TRUE;
    870 
    871 	return SEPOL_OK;
    872 
    873 exit:
    874 	return rc;
    875 }
    876 
    877 static int __cil_cat_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db)
    878 {
    879 	int rc = SEPOL_ERR;
    880 	struct cil_tree_node *node = datum->nodes->head->data;
    881 
    882 	ebitmap_init(bitmap);
    883 
    884 	if (node->flavor == CIL_CATSET) {
    885 		struct cil_catset *catset = (struct cil_catset *)datum;
    886 		struct cil_list_item *curr;
    887 		if (catset->cats->evaluated == CIL_FALSE) {
    888 			rc = __evaluate_cat_expression(catset->cats, db);
    889 			if (rc != SEPOL_OK) goto exit;
    890 		}
    891 		for (curr = catset->cats->datum_expr->head; curr; curr = curr->next) {
    892 			struct cil_cat *cat = (struct cil_cat *)curr->data;
    893 			if (ebitmap_set_bit(bitmap, cat->value, 1)) {
    894 				cil_log(CIL_ERR, "Failed to set cat bit\n");
    895 				ebitmap_destroy(bitmap);
    896 				goto exit;
    897 			}
    898 		}
    899 	} else if (node->flavor == CIL_CATALIAS) {
    900 		struct cil_alias *alias = (struct cil_alias *)datum;
    901 		struct cil_cat *cat = alias->actual;
    902 		if (ebitmap_set_bit(bitmap, cat->value, 1)) {
    903 			cil_log(CIL_ERR, "Failed to set cat bit\n");
    904 			ebitmap_destroy(bitmap);
    905 			goto exit;
    906 		}
    907 	} else {
    908 		struct cil_cat *cat = (struct cil_cat *)datum;
    909 		if (ebitmap_set_bit(bitmap, cat->value, 1)) {
    910 			cil_log(CIL_ERR, "Failed to set cat bit\n");
    911 			ebitmap_destroy(bitmap);
    912 			goto exit;
    913 		}
    914 	}
    915 
    916 	return SEPOL_OK;
    917 
    918 exit:
    919 	return rc;
    920 }
    921 
    922 static int __cil_cat_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap)
    923 {
    924 	int rc = SEPOL_ERR;
    925 	struct cil_symtab_datum *d1 = i1->data;
    926 	struct cil_symtab_datum *d2 = i2->data;
    927 	struct cil_tree_node *n1 = d1->nodes->head->data;
    928 	struct cil_tree_node *n2 = d2->nodes->head->data;
    929 	struct cil_cat *c1 = (struct cil_cat *)d1;
    930 	struct cil_cat *c2 = (struct cil_cat *)d2;
    931 	int i;
    932 
    933 	if (n1->flavor == CIL_CATSET || n2->flavor == CIL_CATSET) {
    934 		cil_log(CIL_ERR, "Category sets cannont be used in a category range\n");
    935 		goto exit;
    936 	}
    937 
    938 	if (n1->flavor == CIL_CATALIAS) {
    939 		struct cil_alias *alias = (struct cil_alias *)d1;
    940 		c1 = alias->actual;
    941 	}
    942 
    943 	if (n2->flavor == CIL_CATALIAS) {
    944 		struct cil_alias *alias = (struct cil_alias *)d2;
    945 		c2 = alias->actual;
    946 	}
    947 
    948 	if (c1->value > c2->value) {
    949 		cil_log(CIL_ERR, "Invalid category range\n");
    950 		goto exit;
    951 	}
    952 
    953 	for (i = c1->value; i <= c2->value; i++) {
    954 		if (ebitmap_set_bit(bitmap, i, 1)) {
    955 			cil_log(CIL_ERR, "Failed to set cat bit\n");
    956 			ebitmap_destroy(bitmap);
    957 			goto exit;
    958 		}
    959 	}
    960 
    961 	return SEPOL_OK;
    962 
    963 exit:
    964 	return rc;
    965 }
    966 
    967 static int __cil_permissionx_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap)
    968 {
    969 	int rc = SEPOL_ERR;
    970 	char *p1 = i1->data;
    971 	char *p2 = i2->data;
    972 	uint16_t v1;
    973 	uint16_t v2;
    974 	uint32_t i;
    975 
    976 	rc = __cil_permx_str_to_int(p1, &v1);
    977 	if (rc != SEPOL_OK) {
    978 		goto exit;
    979 	}
    980 
    981 	rc = __cil_permx_str_to_int(p2, &v2);
    982 	if (rc != SEPOL_OK) {
    983 		goto exit;
    984 	}
    985 
    986 	for (i = v1; i <= v2; i++) {
    987 		if (ebitmap_set_bit(bitmap, i, 1)) {
    988 			cil_log(CIL_ERR, "Failed to set permissionx bit\n");
    989 			ebitmap_destroy(bitmap);
    990 			goto exit;
    991 		}
    992 	}
    993 
    994 	return SEPOL_OK;
    995 
    996 exit:
    997 	return rc;
    998 }
    999 
   1000 static int __cil_expr_to_bitmap_helper(struct cil_list_item *curr, enum cil_flavor flavor, ebitmap_t *bitmap, int max, struct cil_db *db)
   1001 {
   1002 	int rc = SEPOL_ERR;
   1003 
   1004 	if (curr->flavor == CIL_DATUM) {
   1005 		switch (flavor) {
   1006 		case CIL_TYPE:
   1007 			rc = __cil_type_to_bitmap(curr->data, bitmap, db);
   1008 			break;
   1009 		case CIL_ROLE:
   1010 			rc = __cil_role_to_bitmap(curr->data, bitmap, db);
   1011 			break;
   1012 		case CIL_USER:
   1013 			rc = __cil_user_to_bitmap(curr->data, bitmap, db);
   1014 			break;
   1015 		case CIL_PERM:
   1016 			rc = __cil_perm_to_bitmap(curr->data, bitmap, db);
   1017 			break;
   1018 		case CIL_CAT:
   1019 			rc = __cil_cat_to_bitmap(curr->data, bitmap, db);
   1020 			break;
   1021 		default:
   1022 			rc = SEPOL_ERR;
   1023 		}
   1024 	} else if (curr->flavor == CIL_LIST) {
   1025 		struct cil_list *l = curr->data;
   1026 		ebitmap_init(bitmap);
   1027 		rc = __cil_expr_to_bitmap(l, bitmap, max, db);
   1028 		if (rc != SEPOL_OK) {
   1029 			ebitmap_destroy(bitmap);
   1030 		}
   1031 	} else if (flavor == CIL_PERMISSIONX) {
   1032 		// permissionx expressions aren't resolved into anything, so curr->flavor
   1033 		// is just a CIL_STRING, not a CIL_DATUM, so just check on flavor for those
   1034 		rc = __cil_permx_to_bitmap(curr->data, bitmap, db);
   1035 	}
   1036 
   1037 	return rc;
   1038 }
   1039 
   1040 static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db)
   1041 {
   1042 	int rc = SEPOL_ERR;
   1043 	struct cil_list_item *curr;
   1044 	enum cil_flavor flavor;
   1045 	ebitmap_t tmp, b1, b2;
   1046 
   1047 	if (expr == NULL || expr->head == NULL) {
   1048 		return SEPOL_OK;
   1049 	}
   1050 
   1051 	curr = expr->head;
   1052 	flavor = expr->flavor;
   1053 
   1054 	if (curr->flavor == CIL_OP) {
   1055 		enum cil_flavor op = (enum cil_flavor)curr->data;
   1056 
   1057 		if (op == CIL_ALL) {
   1058 			ebitmap_init(&b1); /* all zeros */
   1059 			rc = ebitmap_not(&tmp, &b1, max);
   1060 			ebitmap_destroy(&b1);
   1061 			if (rc != SEPOL_OK) {
   1062 				cil_log(CIL_INFO, "Failed to expand 'all' operator\n");
   1063 				ebitmap_destroy(&tmp);
   1064 				goto exit;
   1065 			}
   1066 		} else if (op == CIL_RANGE) {
   1067 			if (flavor == CIL_CAT) {
   1068 				ebitmap_init(&tmp);
   1069 				rc = __cil_cat_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp);
   1070 				if (rc != SEPOL_OK) {
   1071 					cil_log(CIL_INFO, "Failed to expand category range\n");
   1072 					ebitmap_destroy(&tmp);
   1073 					goto exit;
   1074 				}
   1075 			} else if (flavor == CIL_PERMISSIONX) {
   1076 				ebitmap_init(&tmp);
   1077 				rc = __cil_permissionx_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp);
   1078 				if (rc != SEPOL_OK) {
   1079 					cil_log(CIL_INFO, "Failed to expand category range\n");
   1080 					ebitmap_destroy(&tmp);
   1081 					goto exit;
   1082 				}
   1083 			} else {
   1084 				cil_log(CIL_INFO, "Range operation only supported for categories permissionx\n");
   1085 				rc = SEPOL_ERR;
   1086 				goto exit;
   1087 			}
   1088 		} else {
   1089 			rc = __cil_expr_to_bitmap_helper(curr->next, flavor, &b1, max, db);
   1090 			if (rc != SEPOL_OK) {
   1091 				cil_log(CIL_INFO, "Failed to get first operand bitmap\n");
   1092 				goto exit;
   1093 			}
   1094 
   1095 			if (op == CIL_NOT) {
   1096 				rc = ebitmap_not(&tmp, &b1, max);
   1097 				ebitmap_destroy(&b1);
   1098 				if (rc != SEPOL_OK) {
   1099 					cil_log(CIL_INFO, "Failed to NOT bitmap\n");
   1100 					ebitmap_destroy(&tmp);
   1101 					goto exit;
   1102 				}
   1103 			} else {
   1104 				rc = __cil_expr_to_bitmap_helper(curr->next->next, flavor, &b2, max, db);
   1105 				if (rc != SEPOL_OK) {
   1106 					cil_log(CIL_INFO, "Failed to get second operand bitmap\n");
   1107 					ebitmap_destroy(&b1);
   1108 					goto exit;
   1109 				}
   1110 
   1111 				if (op == CIL_OR) {
   1112 					rc = ebitmap_or(&tmp, &b1, &b2);
   1113 				} else if (op == CIL_AND) {
   1114 					rc = ebitmap_and(&tmp, &b1, &b2);
   1115 				} else if (op == CIL_XOR) {
   1116 					rc = ebitmap_xor(&tmp, &b1, &b2);
   1117 				} else {
   1118 					rc = SEPOL_ERR;
   1119 				}
   1120 				ebitmap_destroy(&b1);
   1121 				ebitmap_destroy(&b2);
   1122 				if (rc != SEPOL_OK) {
   1123 					cil_log(CIL_INFO, "Failed to apply operator to bitmaps\n");
   1124 					ebitmap_destroy(&tmp);
   1125 					goto exit;
   1126 				}
   1127 			}
   1128 		}
   1129 	} else {
   1130 		ebitmap_init(&tmp);
   1131 		for (;curr; curr = curr->next) {
   1132 			rc = __cil_expr_to_bitmap_helper(curr, flavor, &b2, max, db);
   1133 			if (rc != SEPOL_OK) {
   1134 				cil_log(CIL_INFO, "Failed to get operand in list\n");
   1135 				ebitmap_destroy(&tmp);
   1136 				goto exit;
   1137 			}
   1138 			b1 = tmp;
   1139 			rc = ebitmap_or(&tmp, &b1, &b2);
   1140 			ebitmap_destroy(&b1);
   1141 			ebitmap_destroy(&b2);
   1142 			if (rc != SEPOL_OK) {
   1143 				cil_log(CIL_INFO, "Failed to OR operands in list\n");
   1144 				ebitmap_destroy(&tmp);
   1145 				goto exit;
   1146 			}
   1147 
   1148 		}
   1149 	}
   1150 
   1151 	ebitmap_union(out, &tmp);
   1152 	ebitmap_destroy(&tmp);
   1153 
   1154 	return SEPOL_OK;
   1155 
   1156 exit:
   1157 	return rc;
   1158 }
   1159 
   1160 static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db)
   1161 {
   1162 	int rc = SEPOL_ERR;
   1163 	struct cil_list_item *expr;
   1164 
   1165 	ebitmap_init(out);
   1166 
   1167 	if (expr_list == NULL) {
   1168 		return SEPOL_OK;
   1169 	}
   1170 
   1171 	cil_list_for_each(expr, expr_list) {
   1172 		ebitmap_t bitmap;
   1173 		struct cil_list *l = (struct cil_list *)expr->data;
   1174 		ebitmap_init(&bitmap);
   1175 		rc = __cil_expr_to_bitmap(l, &bitmap, max, db);
   1176 		if (rc != SEPOL_OK) {
   1177 			cil_log(CIL_INFO, "Failed to expand expression list to bitmap\n");
   1178 			ebitmap_destroy(&bitmap);
   1179 			goto exit;
   1180 		}
   1181 		ebitmap_union(out, &bitmap);
   1182 		ebitmap_destroy(&bitmap);
   1183 	}
   1184 
   1185 	return SEPOL_OK;
   1186 
   1187 exit:
   1188 	return SEPOL_ERR;
   1189 }
   1190 
   1191 static int cil_typeattribute_used(struct cil_typeattribute *attr, struct cil_db *db)
   1192 {
   1193 	if (!attr->used) {
   1194 		return CIL_FALSE;
   1195 	}
   1196 
   1197 	if (attr->used & CIL_ATTR_EXPAND_FALSE) {
   1198 		return CIL_TRUE;
   1199 	}
   1200 
   1201 	if (attr->used & CIL_ATTR_EXPAND_TRUE) {
   1202 		return CIL_FALSE;
   1203 	}
   1204 
   1205 	if (attr->used & CIL_ATTR_CONSTRAINT) {
   1206 		return CIL_TRUE;
   1207 	}
   1208 
   1209 	if (db->attrs_expand_generated || attr->used == CIL_ATTR_NEVERALLOW) {
   1210 		if (strcmp(DATUM(attr)->name, GEN_REQUIRE_ATTR) == 0) {
   1211 			return CIL_FALSE;
   1212 		} else if (strstr(DATUM(attr)->name, TYPEATTR_INFIX) != NULL) {
   1213 			return CIL_FALSE;
   1214 		}
   1215 
   1216 		if (attr->used == CIL_ATTR_NEVERALLOW) {
   1217 			return CIL_TRUE;
   1218 		}
   1219 	}
   1220 
   1221 	if (attr->used == CIL_ATTR_AVRULE) {
   1222 		if (ebitmap_cardinality(attr->types) < db->attrs_expand_size) {
   1223 			return CIL_FALSE;
   1224 		}
   1225 	}
   1226 
   1227 	return CIL_TRUE;
   1228 }
   1229 
   1230 static int __cil_post_db_attr_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
   1231 {
   1232 	int rc = SEPOL_ERR;
   1233 	struct cil_db *db = extra_args;
   1234 
   1235 	switch (node->flavor) {
   1236 	case CIL_BLOCK: {
   1237 		struct cil_block *blk = node->data;
   1238 		if (blk->is_abstract == CIL_TRUE) {
   1239 			*finished = CIL_TREE_SKIP_HEAD;
   1240 		}
   1241 		break;
   1242 	}
   1243 	case CIL_MACRO: {
   1244 		*finished = CIL_TREE_SKIP_HEAD;
   1245 		break;
   1246 	}
   1247 	case CIL_TYPEATTRIBUTE: {
   1248 		struct cil_typeattribute *attr = node->data;
   1249 		if (attr->types == NULL) {
   1250 			rc = __evaluate_type_expression(attr, db);
   1251 			if (rc != SEPOL_OK) goto exit;
   1252 		}
   1253 		attr->used = cil_typeattribute_used(attr, db);
   1254 		break;
   1255 	}
   1256 	case CIL_ROLEATTRIBUTE: {
   1257 		struct cil_roleattribute *attr = node->data;
   1258 		if (attr->roles == NULL) {
   1259 			rc = __evaluate_role_expression(attr, db);
   1260 			if (rc != SEPOL_OK) goto exit;
   1261 		}
   1262 		break;
   1263 	}
   1264 	case CIL_AVRULEX: {
   1265 		struct cil_avrule *rule = node->data;
   1266 		if (rule->perms.x.permx_str == NULL) {
   1267 			rc = __evaluate_permissionx_expression(rule->perms.x.permx, db);
   1268 			if (rc != SEPOL_OK) goto exit;
   1269 		}
   1270 		break;
   1271 	}
   1272 	case CIL_PERMISSIONX: {
   1273 		struct cil_permissionx *permx = node->data;
   1274 		rc = __evaluate_permissionx_expression(permx, db);
   1275 		if (rc != SEPOL_OK) goto exit;
   1276 		break;
   1277 	}
   1278 	case CIL_USERATTRIBUTE: {
   1279 		struct cil_userattribute *attr = node->data;
   1280 		if (attr->users == NULL) {
   1281 			rc = __evaluate_user_expression(attr, db);
   1282 			if (rc != SEPOL_OK) {
   1283 				goto exit;
   1284 			}
   1285 		}
   1286 		break;
   1287 	}
   1288 	default:
   1289 		break;
   1290 	}
   1291 
   1292 	return SEPOL_OK;
   1293 
   1294 exit:
   1295 	return rc;
   1296 }
   1297 
   1298 static int __cil_role_assign_types(struct cil_role *role, struct cil_symtab_datum *datum)
   1299 {
   1300 	struct cil_tree_node *node = datum->nodes->head->data;
   1301 
   1302 	if (role->types == NULL) {
   1303 		role->types = cil_malloc(sizeof(*role->types));
   1304 		ebitmap_init(role->types);
   1305 	}
   1306 
   1307 	if (node->flavor == CIL_TYPE) {
   1308 		struct cil_type *type = (struct cil_type *)datum;
   1309 		if (ebitmap_set_bit(role->types, type->value, 1)) {
   1310 			cil_log(CIL_INFO, "Failed to set bit in role types bitmap\n");
   1311 			goto exit;
   1312 		}
   1313 	} else if (node->flavor == CIL_TYPEALIAS) {
   1314 		struct cil_alias *alias = (struct cil_alias *)datum;
   1315 		struct cil_type *type = alias->actual;
   1316 		if (ebitmap_set_bit(role->types, type->value, 1)) {
   1317 			cil_log(CIL_INFO, "Failed to set bit in role types bitmap\n");
   1318 			goto exit;
   1319 		}
   1320 	} else if (node->flavor == CIL_TYPEATTRIBUTE) {
   1321 		struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
   1322 		ebitmap_union(role->types, attr->types);
   1323 	}
   1324 
   1325 	return SEPOL_OK;
   1326 
   1327 exit:
   1328 	return SEPOL_ERR;
   1329 }
   1330 
   1331 static int __cil_post_db_roletype_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
   1332 {
   1333 	int rc = SEPOL_ERR;
   1334 	struct cil_db *db = extra_args;
   1335 
   1336 	switch (node->flavor) {
   1337 	case CIL_BLOCK: {
   1338 		struct cil_block *blk = node->data;
   1339 		if (blk->is_abstract == CIL_TRUE) {
   1340 			*finished = CIL_TREE_SKIP_HEAD;
   1341 		}
   1342 		break;
   1343 	}
   1344 	case CIL_MACRO: {
   1345 		*finished = CIL_TREE_SKIP_HEAD;
   1346 		break;
   1347 	}
   1348 	case CIL_ROLETYPE: {
   1349 		struct cil_roletype *roletype = node->data;
   1350 		struct cil_symtab_datum *role_datum = roletype->role;
   1351 		struct cil_symtab_datum *type_datum = roletype->type;
   1352 		struct cil_tree_node *role_node = role_datum->nodes->head->data;
   1353 
   1354 		if (role_node->flavor == CIL_ROLEATTRIBUTE) {
   1355 			struct cil_roleattribute *attr = roletype->role;
   1356 			ebitmap_node_t *rnode;
   1357 			unsigned int i;
   1358 
   1359 			ebitmap_for_each_bit(attr->roles, rnode, i) {
   1360 				struct cil_role *role = NULL;
   1361 
   1362 				if (!ebitmap_get_bit(attr->roles, i)) {
   1363 					continue;
   1364 				}
   1365 
   1366 				role = db->val_to_role[i];
   1367 
   1368 				rc = __cil_role_assign_types(role, type_datum);
   1369 				if (rc != SEPOL_OK) {
   1370 					goto exit;
   1371 				}
   1372 			}
   1373 		} else {
   1374 			struct cil_role *role = roletype->role;
   1375 
   1376 			rc = __cil_role_assign_types(role, type_datum);
   1377 			if (rc != SEPOL_OK) {
   1378 				goto exit;
   1379 			}
   1380 		}
   1381 		break;
   1382 	}
   1383 	default:
   1384 		break;
   1385 	}
   1386 
   1387 	return SEPOL_OK;
   1388 exit:
   1389 	cil_log(CIL_INFO, "cil_post_db_roletype_helper failed\n");
   1390 	return rc;
   1391 }
   1392 
   1393 static int __cil_user_assign_roles(struct cil_user *user, struct cil_symtab_datum *datum)
   1394 {
   1395 	struct cil_tree_node *node = datum->nodes->head->data;
   1396 	struct cil_role *role = NULL;
   1397 	struct cil_roleattribute *attr = NULL;
   1398 
   1399 	if (user->roles == NULL) {
   1400 		user->roles = cil_malloc(sizeof(*user->roles));
   1401 		ebitmap_init(user->roles);
   1402 	}
   1403 
   1404 	if (node->flavor == CIL_ROLE) {
   1405 		role = (struct cil_role *)datum;
   1406 		if (ebitmap_set_bit(user->roles, role->value, 1)) {
   1407 			cil_log(CIL_INFO, "Failed to set bit in user roles bitmap\n");
   1408 			goto exit;
   1409 		}
   1410 	} else if (node->flavor == CIL_ROLEATTRIBUTE) {
   1411 		attr = (struct cil_roleattribute *)datum;
   1412 		ebitmap_union(user->roles, attr->roles);
   1413 	}
   1414 
   1415 	return SEPOL_OK;
   1416 
   1417 exit:
   1418 	return SEPOL_ERR;
   1419 }
   1420 
   1421 static int __cil_post_db_userrole_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
   1422 {
   1423 	int rc = SEPOL_ERR;
   1424 	struct cil_db *db = extra_args;
   1425 	struct cil_block *blk = NULL;
   1426 	struct cil_userrole *userrole = NULL;
   1427 	struct cil_symtab_datum *user_datum = NULL;
   1428 	struct cil_symtab_datum *role_datum = NULL;
   1429 	struct cil_tree_node *user_node = NULL;
   1430 	struct cil_userattribute *u_attr = NULL;
   1431 	unsigned int i;
   1432 	struct cil_user *user = NULL;
   1433 	ebitmap_node_t *unode = NULL;
   1434 
   1435 	switch (node->flavor) {
   1436 	case CIL_BLOCK: {
   1437 		blk = node->data;
   1438 		if (blk->is_abstract == CIL_TRUE) {
   1439 			*finished = CIL_TREE_SKIP_HEAD;
   1440 		}
   1441 		break;
   1442 	}
   1443 	case CIL_MACRO: {
   1444 		*finished = CIL_TREE_SKIP_HEAD;
   1445 		break;
   1446 	}
   1447 	case CIL_USERROLE: {
   1448 		userrole = node->data;
   1449 		user_datum = userrole->user;
   1450 		role_datum = userrole->role;
   1451 		user_node = user_datum->nodes->head->data;
   1452 
   1453 		if (user_node->flavor == CIL_USERATTRIBUTE) {
   1454 			u_attr = userrole->user;
   1455 
   1456 			ebitmap_for_each_bit(u_attr->users, unode, i) {
   1457 				if (!ebitmap_get_bit(u_attr->users, i)) {
   1458 					continue;
   1459 				}
   1460 
   1461 				user = db->val_to_user[i];
   1462 
   1463 				rc = __cil_user_assign_roles(user, role_datum);
   1464 				if (rc != SEPOL_OK) {
   1465 					goto exit;
   1466 				}
   1467 			}
   1468 		} else {
   1469 			user = userrole->user;
   1470 
   1471 			rc = __cil_user_assign_roles(user, role_datum);
   1472 			if (rc != SEPOL_OK) {
   1473 				goto exit;
   1474 			}
   1475 		}
   1476 
   1477 		break;
   1478 	}
   1479 	default:
   1480 		break;
   1481 	}
   1482 
   1483 	return SEPOL_OK;
   1484 exit:
   1485 	cil_log(CIL_INFO, "cil_post_db_userrole_helper failed\n");
   1486 	return rc;
   1487 }
   1488 
   1489 static int __evaluate_level_expression(struct cil_level *level, struct cil_db *db)
   1490 {
   1491 	if (level->cats != NULL) {
   1492 		return __evaluate_cat_expression(level->cats, db);
   1493 	}
   1494 
   1495 	return SEPOL_OK;
   1496 }
   1497 
   1498 static int __evaluate_levelrange_expression(struct cil_levelrange *levelrange, struct cil_db *db)
   1499 {
   1500 	int rc = SEPOL_OK;
   1501 
   1502 	if (levelrange->low != NULL && levelrange->low->cats != NULL) {
   1503 		rc =  __evaluate_cat_expression(levelrange->low->cats, db);
   1504 		if (rc != SEPOL_OK) {
   1505 			goto exit;
   1506 		}
   1507 	}
   1508 	if (levelrange->high != NULL && levelrange->high->cats != NULL) {
   1509 		rc = __evaluate_cat_expression(levelrange->high->cats, db);
   1510 		if (rc != SEPOL_OK) {
   1511 			goto exit;
   1512 		}
   1513 	}
   1514 
   1515 exit:
   1516 	return rc;
   1517 }
   1518 
   1519 static int __cil_post_db_cat_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
   1520 {
   1521 	int rc = SEPOL_ERR;
   1522 	struct cil_db *db = extra_args;
   1523 
   1524 	switch (node->flavor) {
   1525 	case CIL_BLOCK: {
   1526 		struct cil_block *blk = node->data;
   1527 		if (blk->is_abstract == CIL_TRUE) {
   1528 			*finished = CIL_TREE_SKIP_HEAD;
   1529 		}
   1530 		break;
   1531 	}
   1532 	case CIL_MACRO: {
   1533 		*finished = CIL_TREE_SKIP_HEAD;
   1534 		break;
   1535 	}
   1536 	case CIL_CATSET: {
   1537 		struct cil_catset *catset = node->data;
   1538 		rc = __evaluate_cat_expression(catset->cats, db);
   1539 		if (rc != SEPOL_OK) {
   1540 			goto exit;
   1541 		}
   1542 		break;
   1543 	}
   1544 	case CIL_SENSCAT: {
   1545 		struct cil_senscat *senscat = node->data;
   1546 		rc = __evaluate_cat_expression(senscat->cats, db);
   1547 		if (rc != SEPOL_OK) {
   1548 			goto exit;
   1549 		}
   1550 		break;
   1551 	}
   1552 	case CIL_LEVEL: {
   1553 		rc = __evaluate_level_expression(node->data, db);
   1554 		if (rc != SEPOL_OK) {
   1555 			goto exit;
   1556 		}
   1557 		break;
   1558 	}
   1559 	case CIL_LEVELRANGE: {
   1560 		rc = __evaluate_levelrange_expression(node->data, db);
   1561 		if (rc != SEPOL_OK) {
   1562 			goto exit;
   1563 		}
   1564 		break;
   1565 	}
   1566 	case CIL_USER: {
   1567 		struct cil_user *user = node->data;
   1568 		rc = __evaluate_level_expression(user->dftlevel, db);
   1569 		if (rc != SEPOL_OK) {
   1570 			goto exit;
   1571 		}
   1572 		rc = __evaluate_levelrange_expression(user->range, db);
   1573 		if (rc != SEPOL_OK) {
   1574 			goto exit;
   1575 		}
   1576 		break;
   1577 	}
   1578 	case CIL_SELINUXUSERDEFAULT:
   1579 	case CIL_SELINUXUSER: {
   1580 		struct cil_selinuxuser *selinuxuser = node->data;
   1581 		rc = __evaluate_levelrange_expression(selinuxuser->range, db);
   1582 		if (rc != SEPOL_OK) {
   1583 			goto exit;
   1584 		}
   1585 		break;
   1586 	}
   1587 	case CIL_RANGETRANSITION: {
   1588 		struct cil_rangetransition *rangetrans = node->data;
   1589 		rc = __evaluate_levelrange_expression(rangetrans->range, db);
   1590 		if (rc != SEPOL_OK) {
   1591 			goto exit;
   1592 		}
   1593 		break;
   1594 	}
   1595 	case CIL_CONTEXT: {
   1596 		struct cil_context *context = node->data;
   1597 		rc = __evaluate_levelrange_expression(context->range, db);
   1598 		if (rc != SEPOL_OK) {
   1599 			goto exit;
   1600 		}
   1601 		break;
   1602 	}
   1603 	case CIL_SIDCONTEXT: {
   1604 		struct cil_sidcontext *sidcontext = node->data;
   1605 		rc = __evaluate_levelrange_expression(sidcontext->context->range, db);
   1606 		if (rc != SEPOL_OK) {
   1607 			goto exit;
   1608 		}
   1609 		break;
   1610 	}
   1611 	case CIL_FILECON: {
   1612 		struct cil_filecon *filecon = node->data;
   1613 		if (filecon->context) {
   1614 			rc = __evaluate_levelrange_expression(filecon->context->range, db);
   1615 			if (rc != SEPOL_OK) {
   1616 				goto exit;
   1617 			}
   1618 		}
   1619 		break;
   1620 	}
   1621 	case CIL_PORTCON: {
   1622 		struct cil_portcon *portcon = node->data;
   1623 		rc = __evaluate_levelrange_expression(portcon->context->range, db);
   1624 		if (rc != SEPOL_OK) {
   1625 			goto exit;
   1626 		}
   1627 		break;
   1628 	}
   1629 	case CIL_NODECON: {
   1630 		struct cil_nodecon *nodecon = node->data;
   1631 		rc = __evaluate_levelrange_expression(nodecon->context->range, db);
   1632 		if (rc != SEPOL_OK) {
   1633 			goto exit;
   1634 		}
   1635 		break;
   1636 	}
   1637 	case CIL_GENFSCON: {
   1638 		struct cil_genfscon *genfscon = node->data;
   1639 		rc = __evaluate_levelrange_expression(genfscon->context->range, db);
   1640 		if (rc != SEPOL_OK) {
   1641 			goto exit;
   1642 		}
   1643 		break;
   1644 	}
   1645 	case CIL_NETIFCON: {
   1646 		struct cil_netifcon *netifcon = node->data;
   1647 		rc = __evaluate_levelrange_expression(netifcon->if_context->range, db);
   1648 		if (rc != SEPOL_OK) {
   1649 			goto exit;
   1650 		}
   1651 		rc = __evaluate_levelrange_expression(netifcon->packet_context->range, db);
   1652 		if (rc != SEPOL_OK) {
   1653 			goto exit;
   1654 		}
   1655 		break;
   1656 	}
   1657 	case CIL_PIRQCON: {
   1658 		struct cil_pirqcon *pirqcon = node->data;
   1659 		rc = __evaluate_levelrange_expression(pirqcon->context->range, db);
   1660 		if (rc != SEPOL_OK) {
   1661 			goto exit;
   1662 		}
   1663 		break;
   1664 	}
   1665 	case CIL_IOMEMCON: {
   1666 		struct cil_iomemcon *iomemcon = node->data;
   1667 		rc = __evaluate_levelrange_expression(iomemcon->context->range, db);
   1668 		if (rc != SEPOL_OK) {
   1669 			goto exit;
   1670 		}
   1671 		break;
   1672 	}
   1673 	case CIL_IOPORTCON: {
   1674 		struct cil_ioportcon *ioportcon = node->data;
   1675 		rc = __evaluate_levelrange_expression(ioportcon->context->range, db);
   1676 		if (rc != SEPOL_OK) {
   1677 			goto exit;
   1678 		}
   1679 		break;
   1680 	}
   1681 	case CIL_PCIDEVICECON: {
   1682 		struct cil_pcidevicecon *pcidevicecon = node->data;
   1683 		rc = __evaluate_levelrange_expression(pcidevicecon->context->range, db);
   1684 		if (rc != SEPOL_OK) {
   1685 			goto exit;
   1686 		}
   1687 		break;
   1688 	}
   1689 	case CIL_DEVICETREECON: {
   1690 		struct cil_devicetreecon *devicetreecon = node->data;
   1691 		rc = __evaluate_levelrange_expression(devicetreecon->context->range, db);
   1692 		if (rc != SEPOL_OK) {
   1693 			goto exit;
   1694 		}
   1695 		break;
   1696 	}
   1697 	case CIL_FSUSE: {
   1698 		struct cil_fsuse *fsuse = node->data;
   1699 		rc = __evaluate_levelrange_expression(fsuse->context->range, db);
   1700 		if (rc != SEPOL_OK) {
   1701 			goto exit;
   1702 		}
   1703 		break;
   1704 	}
   1705 	default:
   1706 		break;
   1707 	}
   1708 
   1709 	return SEPOL_OK;
   1710 
   1711 exit:
   1712 	return rc;
   1713 }
   1714 
   1715 struct perm_to_list {
   1716 	enum cil_flavor flavor;
   1717 	ebitmap_t *perms;
   1718 	struct cil_list *new_list;
   1719 };
   1720 
   1721 static int __perm_bits_to_list(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
   1722 {
   1723 	struct perm_to_list *perm_args = (struct perm_to_list *)args;
   1724 	ebitmap_t *perms = perm_args->perms;
   1725 	struct cil_list *new_list = perm_args->new_list;
   1726 	struct cil_perm *perm = (struct cil_perm *)d;
   1727 	unsigned int value = perm->value;
   1728 
   1729 	if (!ebitmap_get_bit(perms, value)) {
   1730 		return SEPOL_OK;
   1731 	}
   1732 
   1733 	cil_list_append(new_list, CIL_DATUM, d);
   1734 
   1735 	return SEPOL_OK;
   1736 }
   1737 
   1738 static int __evaluate_perm_expression(struct cil_list *perms, enum cil_flavor flavor, symtab_t *class_symtab, symtab_t *common_symtab, unsigned int num_perms, struct cil_list **new_list, struct cil_db *db)
   1739 {
   1740 	int rc = SEPOL_ERR;
   1741 	struct perm_to_list args;
   1742 	ebitmap_t bitmap;
   1743 
   1744 	if (cil_verify_is_list(perms, CIL_PERM)) {
   1745 		return SEPOL_OK;
   1746 	}
   1747 
   1748 	ebitmap_init(&bitmap);
   1749 	rc = __cil_expr_to_bitmap(perms, &bitmap, num_perms, db);
   1750 	if (rc != SEPOL_OK) {
   1751 		ebitmap_destroy(&bitmap);
   1752 		goto exit;
   1753 	}
   1754 
   1755 	cil_list_init(new_list, flavor);
   1756 
   1757 	args.flavor = flavor;
   1758 	args.perms = &bitmap;
   1759 	args.new_list = *new_list;
   1760 
   1761 	cil_symtab_map(class_symtab, __perm_bits_to_list, &args);
   1762 
   1763 	if (common_symtab != NULL) {
   1764 		cil_symtab_map(common_symtab, __perm_bits_to_list, &args);
   1765 	}
   1766 
   1767 	ebitmap_destroy(&bitmap);
   1768 	return SEPOL_OK;
   1769 
   1770 exit:
   1771 	return rc;
   1772 }
   1773 
   1774 static int __evaluate_classperms(struct cil_classperms *cp, struct cil_db *db)
   1775 {
   1776 	int rc = SEPOL_ERR;
   1777 	struct cil_class *class = cp->class;
   1778 	struct cil_class *common = class->common;
   1779 	symtab_t *common_symtab = NULL;
   1780 	struct cil_list *new_list = NULL;
   1781 
   1782 	if (common) {
   1783 		common_symtab = &common->perms;
   1784 	}
   1785 
   1786 	rc = __evaluate_perm_expression(cp->perms, CIL_PERM, &class->perms, common_symtab, class->num_perms, &new_list, db);
   1787 	if (rc != SEPOL_OK) {
   1788 		goto exit;
   1789 	}
   1790 
   1791 	if (new_list == NULL) {
   1792 		return SEPOL_OK;
   1793 	}
   1794 
   1795 	cil_list_destroy(&cp->perms, CIL_FALSE);
   1796 
   1797 	cp->perms = new_list;
   1798 
   1799 	return SEPOL_OK;
   1800 
   1801 exit:
   1802 	return rc;
   1803 }
   1804 
   1805 static int __evaluate_classperms_list(struct cil_list *classperms, struct cil_db *db)
   1806 {
   1807 	int rc = SEPOL_ERR;
   1808 	struct cil_list_item *curr;
   1809 
   1810 	cil_list_for_each(curr, classperms) {
   1811 		if (curr->flavor == CIL_CLASSPERMS) {
   1812 			struct cil_classperms *cp = curr->data;
   1813 			if (FLAVOR(cp->class) == CIL_CLASS) {
   1814 				rc = __evaluate_classperms(cp, db);
   1815 				if (rc != SEPOL_OK) {
   1816 					goto exit;
   1817 				}
   1818 			} else { /* MAP */
   1819 				struct cil_list_item *i = NULL;
   1820 				cil_list_for_each(i, cp->perms) {
   1821 					struct cil_perm *cmp = i->data;
   1822 					rc = __evaluate_classperms_list(cmp->classperms, db);
   1823 					if (rc != SEPOL_OK) {
   1824 						goto exit;
   1825 					}
   1826 				}
   1827 			}
   1828 		} else { /* SET */
   1829 			struct cil_classperms_set *cp_set = curr->data;
   1830 			struct cil_classpermission *cp = cp_set->set;
   1831 			rc = __evaluate_classperms_list(cp->classperms, db);
   1832 			if (rc != SEPOL_OK) {
   1833 				goto exit;
   1834 			}
   1835 		}
   1836 	}
   1837 
   1838 	return SEPOL_OK;
   1839 
   1840 exit:
   1841 	return rc;
   1842 }
   1843 
   1844 struct class_map_args {
   1845 	struct cil_db *db;
   1846 	int rc;
   1847 };
   1848 
   1849 static int __evaluate_map_perm_classperms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
   1850 {
   1851 	struct class_map_args *map_args = args;
   1852 	struct cil_perm *cmp = (struct cil_perm *)d;
   1853 
   1854 	int rc = __evaluate_classperms_list(cmp->classperms, map_args->db);
   1855 
   1856 	if (rc != SEPOL_OK) {
   1857 		map_args->rc = rc;
   1858 	}
   1859 
   1860 	return SEPOL_OK;
   1861 }
   1862 
   1863 static int __evaluate_map_class(struct cil_class *mc, struct cil_db *db)
   1864 {
   1865 	struct class_map_args map_args;
   1866 
   1867 	map_args.db = db;
   1868 	map_args.rc = SEPOL_OK;
   1869 	cil_symtab_map(&mc->perms, __evaluate_map_perm_classperms, &map_args);
   1870 
   1871 	return map_args.rc;
   1872 }
   1873 
   1874 static int __cil_post_db_classperms_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
   1875 {
   1876 	int rc = SEPOL_ERR;
   1877 	struct cil_db *db = extra_args;
   1878 
   1879 	switch (node->flavor) {
   1880 	case CIL_BLOCK: {
   1881 		struct cil_block *blk = node->data;
   1882 		if (blk->is_abstract == CIL_TRUE) {
   1883 			*finished = CIL_TREE_SKIP_HEAD;
   1884 		}
   1885 		break;
   1886 	}
   1887 	case CIL_MACRO:
   1888 		*finished = CIL_TREE_SKIP_HEAD;
   1889 		break;
   1890 	case CIL_MAP_CLASS: {
   1891 		rc = __evaluate_map_class(node->data, db);
   1892 		if (rc != SEPOL_OK) {
   1893 			goto exit;
   1894 		}
   1895 		break;
   1896 	}
   1897 	case CIL_CLASSPERMISSION: {
   1898 		struct cil_classpermission *cp = node->data;
   1899 		rc = __evaluate_classperms_list(cp->classperms, db);
   1900 		if (rc != SEPOL_OK) {
   1901 			goto exit;
   1902 		}
   1903 		break;
   1904 	}
   1905 	case CIL_AVRULE: {
   1906 		struct cil_avrule *avrule = node->data;
   1907 		rc = __evaluate_classperms_list(avrule->perms.classperms, db);
   1908 		if (rc != SEPOL_OK) {
   1909 			goto exit;
   1910 		}
   1911 		break;
   1912 	}
   1913 	case CIL_CONSTRAIN:
   1914 	case CIL_MLSCONSTRAIN: {
   1915 		struct cil_constrain *constrain = node->data;
   1916 		rc = __evaluate_classperms_list(constrain->classperms, db);
   1917 		if (rc != SEPOL_OK) {
   1918 			goto exit;
   1919 		}
   1920 		break;
   1921 	}
   1922 	default:
   1923 		break;
   1924 	}
   1925 
   1926 	return SEPOL_OK;
   1927 
   1928 exit:
   1929 	return rc;
   1930 }
   1931 
   1932 static int cil_post_db(struct cil_db *db)
   1933 {
   1934 	int rc = SEPOL_ERR;
   1935 
   1936 	rc = cil_tree_walk(db->ast->root, __cil_post_db_count_helper, NULL, NULL, db);
   1937 	if (rc != SEPOL_OK) {
   1938 		cil_log(CIL_INFO, "Failure during cil databse count helper\n");
   1939 		goto exit;
   1940 	}
   1941 
   1942 	rc = cil_tree_walk(db->ast->root, __cil_post_db_array_helper, NULL, NULL, db);
   1943 	if (rc != SEPOL_OK) {
   1944 		cil_log(CIL_INFO, "Failure during cil database array helper\n");
   1945 		goto exit;
   1946 	}
   1947 
   1948 	rc = cil_tree_walk(db->ast->root, __cil_post_db_attr_helper, NULL, NULL, db);
   1949 	if (rc != SEPOL_OK) {
   1950 		cil_log(CIL_INFO, "Failed to create attribute bitmaps\n");
   1951 		goto exit;
   1952 	}
   1953 
   1954 	rc = cil_tree_walk(db->ast->root, __cil_post_db_roletype_helper, NULL, NULL, db);
   1955 	if (rc != SEPOL_OK) {
   1956 		cil_log(CIL_INFO, "Failed during roletype association\n");
   1957 		goto exit;
   1958 	}
   1959 
   1960 	rc = cil_tree_walk(db->ast->root, __cil_post_db_userrole_helper, NULL, NULL, db);
   1961 	if (rc != SEPOL_OK) {
   1962 		cil_log(CIL_INFO, "Failed during userrole association\n");
   1963 		goto exit;
   1964 	}
   1965 
   1966 	rc = cil_tree_walk(db->ast->root, __cil_post_db_classperms_helper, NULL, NULL, db);
   1967 	if (rc != SEPOL_OK) {
   1968 		cil_log(CIL_INFO, "Failed to evaluate class mapping permissions expressions\n");
   1969 		goto exit;
   1970 	}
   1971 
   1972 	rc = cil_tree_walk(db->ast->root, __cil_post_db_cat_helper, NULL, NULL, db);
   1973 	if (rc != SEPOL_OK) {
   1974 		cil_log(CIL_INFO, "Failed to evaluate category expressions\n");
   1975 		goto exit;
   1976 	}
   1977 
   1978 	qsort(db->netifcon->array, db->netifcon->count, sizeof(db->netifcon->array), cil_post_netifcon_compare);
   1979 	qsort(db->genfscon->array, db->genfscon->count, sizeof(db->genfscon->array), cil_post_genfscon_compare);
   1980 	qsort(db->portcon->array, db->portcon->count, sizeof(db->portcon->array), cil_post_portcon_compare);
   1981 	qsort(db->nodecon->array, db->nodecon->count, sizeof(db->nodecon->array), cil_post_nodecon_compare);
   1982 	qsort(db->fsuse->array, db->fsuse->count, sizeof(db->fsuse->array), cil_post_fsuse_compare);
   1983 	qsort(db->filecon->array, db->filecon->count, sizeof(db->filecon->array), cil_post_filecon_compare);
   1984 	qsort(db->pirqcon->array, db->pirqcon->count, sizeof(db->pirqcon->array), cil_post_pirqcon_compare);
   1985 	qsort(db->iomemcon->array, db->iomemcon->count, sizeof(db->iomemcon->array), cil_post_iomemcon_compare);
   1986 	qsort(db->ioportcon->array, db->ioportcon->count, sizeof(db->ioportcon->array), cil_post_ioportcon_compare);
   1987 	qsort(db->pcidevicecon->array, db->pcidevicecon->count, sizeof(db->pcidevicecon->array), cil_post_pcidevicecon_compare);
   1988 	qsort(db->devicetreecon->array, db->devicetreecon->count, sizeof(db->devicetreecon->array), cil_post_devicetreecon_compare);
   1989 
   1990 exit:
   1991 	return rc;
   1992 }
   1993 
   1994 static int cil_post_verify(struct cil_db *db)
   1995 {
   1996 	int rc = SEPOL_ERR;
   1997 	int avrule_cnt = 0;
   1998 	int handleunknown = -1;
   1999 	int mls = -1;
   2000 	int nseuserdflt = 0;
   2001 	int pass = 0;
   2002 	struct cil_args_verify extra_args;
   2003 	struct cil_complex_symtab csymtab;
   2004 
   2005 	cil_complex_symtab_init(&csymtab, CIL_CLASS_SYM_SIZE);
   2006 
   2007 	extra_args.db = db;
   2008 	extra_args.csymtab = &csymtab;
   2009 	extra_args.avrule_cnt = &avrule_cnt;
   2010 	extra_args.handleunknown = &handleunknown;
   2011 	extra_args.mls = &mls;
   2012 	extra_args.nseuserdflt = &nseuserdflt;
   2013 	extra_args.pass = &pass;
   2014 
   2015 	for (pass = 0; pass < 2; pass++) {
   2016 		rc = cil_tree_walk(db->ast->root, __cil_verify_helper, NULL, NULL, &extra_args);
   2017 		if (rc != SEPOL_OK) {
   2018 			cil_log(CIL_ERR, "Failed to verify cil database\n");
   2019 			goto exit;
   2020 		}
   2021 	}
   2022 
   2023 	if (db->handle_unknown == -1) {
   2024 		if (handleunknown == -1) {
   2025 			db->handle_unknown = SEPOL_DENY_UNKNOWN;
   2026 		} else {
   2027 			db->handle_unknown = handleunknown;
   2028 		}
   2029 	}
   2030 
   2031 	if (db->mls == -1) {
   2032 		if (mls == -1) {
   2033 			db->mls = CIL_FALSE;
   2034 		} else {
   2035 			db->mls = mls;
   2036 		}
   2037 	}
   2038 
   2039 	if (avrule_cnt == 0) {
   2040 		cil_log(CIL_ERR, "Policy must include at least one avrule\n");
   2041 		rc = SEPOL_ERR;
   2042 		goto exit;
   2043 	}
   2044 
   2045 	if (nseuserdflt > 1) {
   2046 		cil_log(CIL_ERR, "Policy cannot contain more than one selinuxuserdefault, found: %d\n", nseuserdflt);
   2047 		rc = SEPOL_ERR;
   2048 		goto exit;
   2049 	}
   2050 
   2051 exit:
   2052 	cil_complex_symtab_destroy(&csymtab);
   2053 	return rc;
   2054 }
   2055 
   2056 static int cil_pre_verify(struct cil_db *db)
   2057 {
   2058 	int rc = SEPOL_ERR;
   2059 	struct cil_args_verify extra_args;
   2060 
   2061 	extra_args.db = db;
   2062 
   2063 	rc = cil_tree_walk(db->ast->root, __cil_pre_verify_helper, NULL, NULL, &extra_args);
   2064 	if (rc != SEPOL_OK) {
   2065 		cil_log(CIL_ERR, "Failed to verify cil database\n");
   2066 		goto exit;
   2067 	}
   2068 
   2069 exit:
   2070 	return rc;
   2071 }
   2072 
   2073 int cil_post_process(struct cil_db *db)
   2074 {
   2075 	int rc = SEPOL_ERR;
   2076 
   2077 	rc = cil_pre_verify(db);
   2078 	if (rc != SEPOL_OK) {
   2079 		cil_log(CIL_ERR, "Failed to verify cil database\n");
   2080 		goto exit;
   2081 	}
   2082 
   2083 	rc = cil_post_db(db);
   2084 	if (rc != SEPOL_OK) {
   2085 		cil_log(CIL_ERR, "Failed post db handling\n");
   2086 		goto exit;
   2087 	}
   2088 
   2089 	rc = cil_post_verify(db);
   2090 	if (rc != SEPOL_OK) {
   2091 		cil_log(CIL_ERR, "Failed to verify cil database\n");
   2092 		goto exit;
   2093 	}
   2094 
   2095 exit:
   2096 	return rc;
   2097 
   2098 }
   2099