• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
cil_verify_is_list(struct cil_list * list,enum cil_flavor flavor)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 
cil_post_fc_fill_data(struct fc_data * fc,char * path)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 
cil_post_filecon_compare(const void * a,const void * b)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 
cil_post_portcon_compare(const void * a,const void * b)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 
cil_post_genfscon_compare(const void * a,const void * b)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 
cil_post_netifcon_compare(const void * a,const void * b)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 
cil_post_nodecon_compare(const void * a,const void * b)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 
cil_post_pirqcon_compare(const void * a,const void * b)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 
cil_post_iomemcon_compare(const void * a,const void * b)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 
cil_post_ioportcon_compare(const void * a,const void * b)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 
cil_post_pcidevicecon_compare(const void * a,const void * b)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 
cil_post_devicetreecon_compare(const void * a,const void * b)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 
cil_post_fsuse_compare(const void * a,const void * b)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 
__cil_post_db_count_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)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 
__cil_post_db_array_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)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 
__evaluate_type_expression(struct cil_typeattribute * attr,struct cil_db * db)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 
__cil_type_to_bitmap(struct cil_symtab_datum * datum,ebitmap_t * bitmap,struct cil_db * db)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 
__evaluate_user_expression(struct cil_userattribute * attr,struct cil_db * db)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 
__cil_user_to_bitmap(struct cil_symtab_datum * datum,ebitmap_t * bitmap,struct cil_db * db)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 
__evaluate_role_expression(struct cil_roleattribute * attr,struct cil_db * db)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 
__cil_role_to_bitmap(struct cil_symtab_datum * datum,ebitmap_t * bitmap,struct cil_db * db)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 
__evaluate_permissionx_expression(struct cil_permissionx * permx,struct cil_db * db)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 
__cil_permx_str_to_int(char * permx_str,uint16_t * val)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 
__cil_permx_to_bitmap(struct cil_symtab_datum * datum,ebitmap_t * bitmap,struct cil_db * db)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 
__cil_perm_to_bitmap(struct cil_symtab_datum * datum,ebitmap_t * bitmap,struct cil_db * db)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 
__evaluate_cat_expression(struct cil_cats * cats,struct cil_db * db)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 
__cil_cat_to_bitmap(struct cil_symtab_datum * datum,ebitmap_t * bitmap,struct cil_db * db)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 
__cil_cat_expr_range_to_bitmap_helper(struct cil_list_item * i1,struct cil_list_item * i2,ebitmap_t * bitmap)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 
__cil_permissionx_expr_range_to_bitmap_helper(struct cil_list_item * i1,struct cil_list_item * i2,ebitmap_t * bitmap)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 
__cil_expr_to_bitmap_helper(struct cil_list_item * curr,enum cil_flavor flavor,ebitmap_t * bitmap,int max,struct cil_db * db)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 
__cil_expr_to_bitmap(struct cil_list * expr,ebitmap_t * out,int max,struct cil_db * db)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 
__cil_expr_list_to_bitmap(struct cil_list * expr_list,ebitmap_t * out,int max,struct cil_db * db)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 
cil_typeattribute_used(struct cil_typeattribute * attr,struct cil_db * db)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 
__cil_post_db_attr_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)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 
__cil_role_assign_types(struct cil_role * role,struct cil_symtab_datum * datum)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 
__cil_post_db_roletype_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)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 
__cil_user_assign_roles(struct cil_user * user,struct cil_symtab_datum * datum)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 
__cil_post_db_userrole_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)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 
__evaluate_level_expression(struct cil_level * level,struct cil_db * db)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 
__evaluate_levelrange_expression(struct cil_levelrange * levelrange,struct cil_db * db)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 
__cil_post_db_cat_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)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 
__perm_bits_to_list(hashtab_key_t k,hashtab_datum_t d,void * args)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 
__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)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 
__evaluate_classperms(struct cil_classperms * cp,struct cil_db * db)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 
__evaluate_classperms_list(struct cil_list * classperms,struct cil_db * db)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 
__evaluate_map_perm_classperms(hashtab_key_t k,hashtab_datum_t d,void * args)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 
__evaluate_map_class(struct cil_class * mc,struct cil_db * db)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 
__cil_post_db_classperms_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)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 
cil_post_db(struct cil_db * db)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 
cil_post_verify(struct cil_db * db)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 
cil_pre_verify(struct cil_db * db)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 
cil_post_process(struct cil_db * db)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