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