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