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