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