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