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 static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db);
51 static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db);
52
cil_verify_is_list(struct cil_list * list,enum cil_flavor flavor)53 static int cil_verify_is_list(struct cil_list *list, enum cil_flavor flavor)
54 {
55 struct cil_list_item *curr;
56
57 cil_list_for_each(curr, list) {
58 switch (curr->flavor) {
59 case CIL_LIST:
60 return CIL_FALSE;
61 break;
62 case CIL_OP:
63 return CIL_FALSE;
64 break;
65 default:
66 if (flavor == CIL_CAT) {
67 struct cil_symtab_datum *d = curr->data;
68 struct cil_tree_node *n = d->nodes->head->data;
69 if (n->flavor == CIL_CATSET) {
70 return CIL_FALSE;
71 }
72 }
73 break;
74 }
75 }
76 return CIL_TRUE;
77 }
78
cil_post_fc_fill_data(struct fc_data * fc,char * path)79 void cil_post_fc_fill_data(struct fc_data *fc, char *path)
80 {
81 int c = 0;
82 fc->meta = 0;
83 fc->stem_len = 0;
84 fc->str_len = 0;
85
86 while (path[c] != '\0') {
87 switch (path[c]) {
88 case '.':
89 case '^':
90 case '$':
91 case '?':
92 case '*':
93 case '+':
94 case '|':
95 case '[':
96 case '(':
97 case '{':
98 fc->meta = 1;
99 break;
100 case '\\':
101 c++;
102 default:
103 if (!fc->meta) {
104 fc->stem_len++;
105 }
106 break;
107 }
108 fc->str_len++;
109 c++;
110 }
111 }
112
cil_post_filecon_compare(const void * a,const void * b)113 int cil_post_filecon_compare(const void *a, const void *b)
114 {
115 int rc = 0;
116 struct cil_filecon *a_filecon = *(struct cil_filecon**)a;
117 struct cil_filecon *b_filecon = *(struct cil_filecon**)b;
118 struct fc_data *a_data = cil_malloc(sizeof(*a_data));
119 struct fc_data *b_data = cil_malloc(sizeof(*b_data));
120 char *a_path = cil_malloc(strlen(a_filecon->path_str) + 1);
121 a_path[0] = '\0';
122 char *b_path = cil_malloc(strlen(b_filecon->path_str) + 1);
123 b_path[0] = '\0';
124 strcat(a_path, a_filecon->path_str);
125 strcat(b_path, b_filecon->path_str);
126 cil_post_fc_fill_data(a_data, a_path);
127 cil_post_fc_fill_data(b_data, b_path);
128 if (a_data->meta && !b_data->meta) {
129 rc = -1;
130 } else if (b_data->meta && !a_data->meta) {
131 rc = 1;
132 } else if (a_data->stem_len < b_data->stem_len) {
133 rc = -1;
134 } else if (b_data->stem_len < a_data->stem_len) {
135 rc = 1;
136 } else if (a_data->str_len < b_data->str_len) {
137 rc = -1;
138 } else if (b_data->str_len < a_data->str_len) {
139 rc = 1;
140 } else if (a_filecon->type < b_filecon->type) {
141 rc = -1;
142 } else if (b_filecon->type < a_filecon->type) {
143 rc = 1;
144 }
145
146 free(a_path);
147 free(b_path);
148 free(a_data);
149 free(b_data);
150
151 return rc;
152 }
153
cil_post_portcon_compare(const void * a,const void * b)154 int cil_post_portcon_compare(const void *a, const void *b)
155 {
156 int rc = SEPOL_ERR;
157 struct cil_portcon *aportcon = *(struct cil_portcon**)a;
158 struct cil_portcon *bportcon = *(struct cil_portcon**)b;
159
160 rc = (aportcon->port_high - aportcon->port_low)
161 - (bportcon->port_high - bportcon->port_low);
162 if (rc == 0) {
163 if (aportcon->port_low < bportcon->port_low) {
164 rc = -1;
165 } else if (bportcon->port_low < aportcon->port_low) {
166 rc = 1;
167 }
168 }
169
170 return rc;
171 }
172
cil_post_genfscon_compare(const void * a,const void * b)173 int cil_post_genfscon_compare(const void *a, const void *b)
174 {
175 int rc = SEPOL_ERR;
176 struct cil_genfscon *agenfscon = *(struct cil_genfscon**)a;
177 struct cil_genfscon *bgenfscon = *(struct cil_genfscon**)b;
178
179 rc = strcmp(agenfscon->fs_str, bgenfscon->fs_str);
180 if (rc == 0) {
181 rc = strcmp(agenfscon->path_str, bgenfscon->path_str);
182 }
183
184 return rc;
185 }
186
cil_post_netifcon_compare(const void * a,const void * b)187 int cil_post_netifcon_compare(const void *a, const void *b)
188 {
189 struct cil_netifcon *anetifcon = *(struct cil_netifcon**)a;
190 struct cil_netifcon *bnetifcon = *(struct cil_netifcon**)b;
191
192 return strcmp(anetifcon->interface_str, bnetifcon->interface_str);
193 }
194
cil_post_nodecon_compare(const void * a,const void * b)195 int cil_post_nodecon_compare(const void *a, const void *b)
196 {
197 struct cil_nodecon *anodecon;
198 struct cil_nodecon *bnodecon;
199 anodecon = *(struct cil_nodecon**)a;
200 bnodecon = *(struct cil_nodecon**)b;
201
202 /* sort ipv4 before ipv6 */
203 if (anodecon->addr->family != bnodecon->addr->family) {
204 if (anodecon->addr->family == AF_INET) {
205 return -1;
206 } else {
207 return 1;
208 }
209 }
210
211 /* most specific netmask goes first, then order by ip addr */
212 if (anodecon->addr->family == AF_INET) {
213 int rc = memcmp(&anodecon->mask->ip.v4, &bnodecon->mask->ip.v4, sizeof(anodecon->mask->ip.v4));
214 if (rc != 0) {
215 return -1 * rc;
216 }
217 return memcmp(&anodecon->addr->ip.v4, &bnodecon->addr->ip.v4, sizeof(anodecon->addr->ip.v4));
218 } else {
219 int rc = memcmp(&anodecon->mask->ip.v6, &bnodecon->mask->ip.v6, sizeof(anodecon->mask->ip.v6));
220 if (rc != 0) {
221 return -1 * rc;
222 }
223 return memcmp(&anodecon->addr->ip.v6, &bnodecon->addr->ip.v6, sizeof(anodecon->addr->ip.v6));
224 }
225 }
226
cil_post_pirqcon_compare(const void * a,const void * b)227 int cil_post_pirqcon_compare(const void *a, const void *b)
228 {
229 int rc = SEPOL_ERR;
230 struct cil_pirqcon *apirqcon = *(struct cil_pirqcon**)a;
231 struct cil_pirqcon *bpirqcon = *(struct cil_pirqcon**)b;
232
233 if (apirqcon->pirq < bpirqcon->pirq) {
234 rc = -1;
235 } else if (bpirqcon->pirq < apirqcon->pirq) {
236 rc = 1;
237 } else {
238 rc = 0;
239 }
240
241 return rc;
242 }
243
cil_post_iomemcon_compare(const void * a,const void * b)244 int cil_post_iomemcon_compare(const void *a, const void *b)
245 {
246 int rc = SEPOL_ERR;
247 struct cil_iomemcon *aiomemcon = *(struct cil_iomemcon**)a;
248 struct cil_iomemcon *biomemcon = *(struct cil_iomemcon**)b;
249
250 rc = (aiomemcon->iomem_high - aiomemcon->iomem_low)
251 - (biomemcon->iomem_high - biomemcon->iomem_low);
252 if (rc == 0) {
253 if (aiomemcon->iomem_low < biomemcon->iomem_low) {
254 rc = -1;
255 } else if (biomemcon->iomem_low < aiomemcon->iomem_low) {
256 rc = 1;
257 }
258 }
259
260 return rc;
261 }
262
cil_post_ioportcon_compare(const void * a,const void * b)263 int cil_post_ioportcon_compare(const void *a, const void *b)
264 {
265 int rc = SEPOL_ERR;
266 struct cil_ioportcon *aioportcon = *(struct cil_ioportcon**)a;
267 struct cil_ioportcon *bioportcon = *(struct cil_ioportcon**)b;
268
269 rc = (aioportcon->ioport_high - aioportcon->ioport_low)
270 - (bioportcon->ioport_high - bioportcon->ioport_low);
271 if (rc == 0) {
272 if (aioportcon->ioport_low < bioportcon->ioport_low) {
273 rc = -1;
274 } else if (bioportcon->ioport_low < aioportcon->ioport_low) {
275 rc = 1;
276 }
277 }
278
279 return rc;
280 }
281
cil_post_pcidevicecon_compare(const void * a,const void * b)282 int cil_post_pcidevicecon_compare(const void *a, const void *b)
283 {
284 int rc = SEPOL_ERR;
285 struct cil_pcidevicecon *apcidevicecon = *(struct cil_pcidevicecon**)a;
286 struct cil_pcidevicecon *bpcidevicecon = *(struct cil_pcidevicecon**)b;
287
288 if (apcidevicecon->dev < bpcidevicecon->dev) {
289 rc = -1;
290 } else if (bpcidevicecon->dev < apcidevicecon->dev) {
291 rc = 1;
292 } else {
293 rc = 0;
294 }
295
296 return rc;
297 }
298
cil_post_devicetreecon_compare(const void * a,const void * b)299 int cil_post_devicetreecon_compare(const void *a, const void *b)
300 {
301 int rc = SEPOL_ERR;
302 struct cil_devicetreecon *adevicetreecon = *(struct cil_devicetreecon**)a;
303 struct cil_devicetreecon *bdevicetreecon = *(struct cil_devicetreecon**)b;
304
305 rc = strcmp(adevicetreecon->path, bdevicetreecon->path);
306
307 return rc;
308 }
309
cil_post_fsuse_compare(const void * a,const void * b)310 int cil_post_fsuse_compare(const void *a, const void *b)
311 {
312 int rc;
313 struct cil_fsuse *afsuse;
314 struct cil_fsuse *bfsuse;
315 afsuse = *(struct cil_fsuse**)a;
316 bfsuse = *(struct cil_fsuse**)b;
317 if (afsuse->type < bfsuse->type) {
318 rc = -1;
319 } else if (bfsuse->type < afsuse->type) {
320 rc = 1;
321 } else {
322 rc = strcmp(afsuse->fs_str, bfsuse->fs_str);
323 }
324 return rc;
325 }
326
__cil_post_db_count_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)327 static int __cil_post_db_count_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
328 {
329 struct cil_db *db = extra_args;
330
331 switch(node->flavor) {
332 case CIL_BLOCK: {
333 struct cil_block *blk = node->data;
334 if (blk->is_abstract == CIL_TRUE) {
335 *finished = CIL_TREE_SKIP_HEAD;
336 }
337 break;
338 }
339 case CIL_MACRO:
340 *finished = CIL_TREE_SKIP_HEAD;
341 break;
342 case CIL_CLASS: {
343 struct cil_class *class = node->data;
344 if (class->datum.nodes->head->data == node) {
345 // Multiple nodes can point to the same datum. Only count once.
346 db->num_classes++;
347 }
348 break;
349 }
350 case CIL_TYPE: {
351 struct cil_type *type = node->data;
352 if (type->datum.nodes->head->data == node) {
353 // Multiple nodes can point to the same datum. Only count once.
354 type->value = db->num_types;
355 db->num_types++;
356 db->num_types_and_attrs++;
357 }
358 break;
359 }
360 case CIL_TYPEATTRIBUTE: {
361 struct cil_typeattribute *attr = node->data;
362 if (attr->datum.nodes->head->data == node) {
363 // Multiple nodes can point to the same datum. Only count once.
364 db->num_types_and_attrs++;
365 }
366 break;
367 }
368
369 case CIL_ROLE: {
370 struct cil_role *role = node->data;
371 if (role->datum.nodes->head->data == node) {
372 // Multiple nodes can point to the same datum. Only count once.
373 role->value = db->num_roles;
374 db->num_roles++;
375 }
376 break;
377 }
378 case CIL_USER: {
379 struct cil_user *user = node->data;
380 if (user->datum.nodes->head->data == node) {
381 // multiple AST nodes can point to the same cil_user data (like if
382 // copied from a macro). This check ensures we only count the
383 // duplicates once
384 user->value = db->num_users;
385 db->num_users++;
386 }
387 break;
388 }
389 case CIL_NETIFCON:
390 db->netifcon->count++;
391 break;
392 case CIL_GENFSCON:
393 db->genfscon->count++;
394 break;
395 case CIL_FILECON:
396 db->filecon->count++;
397 break;
398 case CIL_NODECON:
399 db->nodecon->count++;
400 break;
401 case CIL_PORTCON:
402 db->portcon->count++;
403 break;
404 case CIL_PIRQCON:
405 db->pirqcon->count++;
406 break;
407 case CIL_IOMEMCON:
408 db->iomemcon->count++;
409 break;
410 case CIL_IOPORTCON:
411 db->ioportcon->count++;
412 break;
413 case CIL_PCIDEVICECON:
414 db->pcidevicecon->count++;
415 break;
416 case CIL_DEVICETREECON:
417 db->devicetreecon->count++;
418 break;
419 case CIL_FSUSE:
420 db->fsuse->count++;
421 break;
422 default:
423 break;
424 }
425
426 return SEPOL_OK;
427 }
428
__cil_post_db_array_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)429 static int __cil_post_db_array_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
430 {
431 struct cil_db *db = extra_args;
432
433 switch(node->flavor) {
434 case CIL_BLOCK: {
435 struct cil_block *blk = node->data;
436 if (blk->is_abstract == CIL_TRUE) {
437 *finished = CIL_TREE_SKIP_HEAD;
438 }
439 break;
440 }
441 case CIL_MACRO:
442 *finished = CIL_TREE_SKIP_HEAD;
443 break;
444 case CIL_TYPE: {
445 struct cil_type *type = node->data;
446 if (db->val_to_type == NULL) {
447 db->val_to_type = cil_malloc(sizeof(*db->val_to_type) * db->num_types);
448 }
449 db->val_to_type[type->value] = type;
450 break;
451 }
452 case CIL_ROLE: {
453 struct cil_role *role = node->data;
454 if (db->val_to_role == NULL) {
455 db->val_to_role = cil_malloc(sizeof(*db->val_to_role) * db->num_roles);
456 }
457 db->val_to_role[role->value] = role;
458 break;
459 }
460 case CIL_USER: {
461 struct cil_user *user= node->data;
462 if (db->val_to_user == NULL) {
463 db->val_to_user = cil_malloc(sizeof(*db->val_to_user) * db->num_users);
464 }
465 db->val_to_user[user->value] = user;
466 break;
467 }
468 case CIL_USERPREFIX: {
469 cil_list_append(db->userprefixes, CIL_USERPREFIX, node->data);
470 break;
471 }
472 case CIL_SELINUXUSER: {
473 cil_list_prepend(db->selinuxusers, CIL_SELINUXUSER, node->data);
474 break;
475 }
476 case CIL_SELINUXUSERDEFAULT: {
477 cil_list_append(db->selinuxusers, CIL_SELINUXUSERDEFAULT, node->data);
478 break;
479 }
480 case CIL_NETIFCON: {
481 struct cil_sort *sort = db->netifcon;
482 uint32_t count = sort->count;
483 uint32_t i = sort->index;
484 if (sort->array == NULL) {
485 sort->array = cil_malloc(sizeof(*sort->array)*count);
486 }
487 sort->array[i] = node->data;
488 sort->index++;
489 break;
490 }
491 case CIL_FSUSE: {
492 struct cil_sort *sort = db->fsuse;
493 uint32_t count = sort->count;
494 uint32_t i = sort->index;
495 if (sort->array == NULL) {
496 sort->array = cil_malloc(sizeof(*sort->array)*count);
497 }
498 sort->array[i] = node->data;
499 sort->index++;
500 break;
501 }
502 case CIL_GENFSCON: {
503 struct cil_sort *sort = db->genfscon;
504 uint32_t count = sort->count;
505 uint32_t i = sort->index;
506 if (sort->array == NULL) {
507 sort->array = cil_malloc(sizeof(*sort->array)*count);
508 }
509 sort->array[i] = node->data;
510 sort->index++;
511 break;
512 }
513 case CIL_FILECON: {
514 struct cil_sort *sort = db->filecon;
515 uint32_t count = sort->count;
516 uint32_t i = sort->index;
517 if (sort->array == NULL) {
518 sort->array = cil_malloc(sizeof(*sort->array)*count);
519 }
520 sort->array[i] = node->data;
521 sort->index++;
522 break;
523 }
524 case CIL_NODECON: {
525 struct cil_sort *sort = db->nodecon;
526 uint32_t count = sort->count;
527 uint32_t i = sort->index;
528 if (sort->array == NULL) {
529 sort->array = cil_malloc(sizeof(*sort->array)*count);
530 }
531 sort->array[i] = node->data;
532 sort->index++;
533 break;
534 }
535 case CIL_PORTCON: {
536 struct cil_sort *sort = db->portcon;
537 uint32_t count = sort->count;
538 uint32_t i = sort->index;
539 if (sort->array == NULL) {
540 sort->array = cil_malloc(sizeof(*sort->array)*count);
541 }
542 sort->array[i] = node->data;
543 sort->index++;
544 break;
545 }
546 case CIL_PIRQCON: {
547 struct cil_sort *sort = db->pirqcon;
548 uint32_t count = sort->count;
549 uint32_t i = sort->index;
550 if (sort->array == NULL) {
551 sort->array = cil_malloc(sizeof(*sort->array)*count);
552 }
553 sort->array[i] = node->data;
554 sort->index++;
555 break;
556 }
557 case CIL_IOMEMCON: {
558 struct cil_sort *sort = db->iomemcon;
559 uint32_t count = sort->count;
560 uint32_t i = sort->index;
561 if (sort->array == NULL) {
562 sort->array = cil_malloc(sizeof(*sort->array)*count);
563 }
564 sort->array[i] = node->data;
565 sort->index++;
566 break;
567 }
568 case CIL_IOPORTCON: {
569 struct cil_sort *sort = db->ioportcon;
570 uint32_t count = sort->count;
571 uint32_t i = sort->index;
572 if (sort->array == NULL) {
573 sort->array = cil_malloc(sizeof(*sort->array)*count);
574 }
575 sort->array[i] = node->data;
576 sort->index++;
577 break;
578 }
579 case CIL_PCIDEVICECON: {
580 struct cil_sort *sort = db->pcidevicecon;
581 uint32_t count = sort->count;
582 uint32_t i = sort->index;
583 if (sort->array == NULL) {
584 sort->array = cil_malloc(sizeof(*sort->array)*count);
585 }
586 sort->array[i] = node->data;
587 sort->index++;
588 break;
589 }
590 case CIL_DEVICETREECON: {
591 struct cil_sort *sort = db->devicetreecon;
592 uint32_t count = sort->count;
593 uint32_t i = sort->index;
594 if (sort->array == NULL) {
595 sort->array = cil_malloc(sizeof(*sort->array)*count);
596 }
597 sort->array[i] = node->data;
598 sort->index++;
599 break;
600 }
601 default:
602 break;
603 }
604
605 return SEPOL_OK;
606 }
607
__evaluate_type_expression(struct cil_typeattribute * attr,struct cil_db * db)608 static int __evaluate_type_expression(struct cil_typeattribute *attr, struct cil_db *db)
609 {
610 int rc;
611
612 attr->types = cil_malloc(sizeof(*attr->types));
613 rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->types, db->num_types, db);
614 if (rc != SEPOL_OK) {
615 cil_log(CIL_ERR, "Failed to expand type attribute to bitmap\n");
616 ebitmap_destroy(attr->types);
617 free(attr->types);
618 attr->types = NULL;
619 }
620 return rc;
621 }
622
__cil_type_to_bitmap(struct cil_symtab_datum * datum,ebitmap_t * bitmap,struct cil_db * db)623 static int __cil_type_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db)
624 {
625 int rc = SEPOL_ERR;
626 struct cil_tree_node *node = datum->nodes->head->data;
627
628 ebitmap_init(bitmap);
629
630 if (node->flavor == CIL_TYPEATTRIBUTE) {
631 struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
632 if (attr->types == NULL) {
633 rc = __evaluate_type_expression(attr, db);
634 if (rc != SEPOL_OK) goto exit;
635 }
636 ebitmap_union(bitmap, attr->types);
637 } else if (node->flavor == CIL_TYPEALIAS) {
638 struct cil_alias *alias = (struct cil_alias *)datum;
639 struct cil_type *type = alias->actual;
640 if (ebitmap_set_bit(bitmap, type->value, 1)) {
641 cil_log(CIL_ERR, "Failed to set type bit\n");
642 ebitmap_destroy(bitmap);
643 goto exit;
644 }
645 } else {
646 struct cil_type *type = (struct cil_type *)datum;
647 if (ebitmap_set_bit(bitmap, type->value, 1)) {
648 cil_log(CIL_ERR, "Failed to set type bit\n");
649 ebitmap_destroy(bitmap);
650 goto exit;
651 }
652 }
653
654 return SEPOL_OK;
655
656 exit:
657 return rc;
658 }
659
__evaluate_user_expression(struct cil_userattribute * attr,struct cil_db * db)660 static int __evaluate_user_expression(struct cil_userattribute *attr, struct cil_db *db)
661 {
662 int rc;
663
664 attr->users = cil_malloc(sizeof(*attr->users));
665 rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->users, db->num_users, db);
666 if (rc != SEPOL_OK) {
667 cil_log(CIL_ERR, "Failed to expand user attribute to bitmap\n");
668 ebitmap_destroy(attr->users);
669 free(attr->users);
670 attr->users = NULL;
671 }
672 return rc;
673 }
674
__cil_user_to_bitmap(struct cil_symtab_datum * datum,ebitmap_t * bitmap,struct cil_db * db)675 static int __cil_user_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db)
676 {
677 int rc = SEPOL_ERR;
678 struct cil_tree_node *node = datum->nodes->head->data;
679 struct cil_userattribute *attr = NULL;
680 struct cil_user *user = NULL;
681
682 ebitmap_init(bitmap);
683
684 if (node->flavor == CIL_USERATTRIBUTE) {
685 attr = (struct cil_userattribute *)datum;
686 if (attr->users == NULL) {
687 rc = __evaluate_user_expression(attr, db);
688 if (rc != SEPOL_OK) {
689 goto exit;
690 }
691 }
692 ebitmap_union(bitmap, attr->users);
693 } else {
694 user = (struct cil_user *)datum;
695 if (ebitmap_set_bit(bitmap, user->value, 1)) {
696 cil_log(CIL_ERR, "Failed to set user bit\n");
697 ebitmap_destroy(bitmap);
698 goto exit;
699 }
700 }
701
702 return SEPOL_OK;
703
704 exit:
705 return rc;
706 }
707
__evaluate_role_expression(struct cil_roleattribute * attr,struct cil_db * db)708 static int __evaluate_role_expression(struct cil_roleattribute *attr, struct cil_db *db)
709 {
710 int rc;
711
712 attr->roles = cil_malloc(sizeof(*attr->roles));
713 rc = __cil_expr_list_to_bitmap(attr->expr_list, attr->roles, db->num_roles, db);
714 if (rc != SEPOL_OK) {
715 cil_log(CIL_ERR, "Failed to expand role attribute to bitmap\n");
716 ebitmap_destroy(attr->roles);
717 free(attr->roles);
718 attr->roles = NULL;
719 }
720 return rc;
721 }
722
__cil_role_to_bitmap(struct cil_symtab_datum * datum,ebitmap_t * bitmap,struct cil_db * db)723 static int __cil_role_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db)
724 {
725 int rc = SEPOL_ERR;
726 struct cil_tree_node *node = datum->nodes->head->data;
727
728 ebitmap_init(bitmap);
729
730 if (node->flavor == CIL_ROLEATTRIBUTE) {
731 struct cil_roleattribute *attr = (struct cil_roleattribute *)datum;
732 if (attr->roles == NULL) {
733 rc = __evaluate_role_expression(attr, db);
734 if (rc != SEPOL_OK) goto exit;
735 }
736 ebitmap_union(bitmap, attr->roles);
737 } else {
738 struct cil_role *role = (struct cil_role *)datum;
739 if (ebitmap_set_bit(bitmap, role->value, 1)) {
740 cil_log(CIL_ERR, "Failed to set role bit\n");
741 ebitmap_destroy(bitmap);
742 goto exit;
743 }
744 }
745
746 return SEPOL_OK;
747
748 exit:
749 return rc;
750 }
751
__evaluate_permissionx_expression(struct cil_permissionx * permx,struct cil_db * db)752 static int __evaluate_permissionx_expression(struct cil_permissionx *permx, struct cil_db *db)
753 {
754 int rc;
755
756 permx->perms = cil_malloc(sizeof(*permx->perms));
757 ebitmap_init(permx->perms);
758
759 rc = __cil_expr_to_bitmap(permx->expr_str, permx->perms, 0x10000, db); // max is one more than 0xFFFF
760 if (rc != SEPOL_OK) {
761 cil_log(CIL_ERR, "Failed to expand permissionx expression\n");
762 ebitmap_destroy(permx->perms);
763 free(permx->perms);
764 permx->perms = NULL;
765 }
766
767 return rc;
768 }
769
__cil_permx_str_to_int(char * permx_str,uint16_t * val)770 static int __cil_permx_str_to_int(char *permx_str, uint16_t *val)
771 {
772 char *endptr = NULL;
773 long lval = strtol(permx_str, &endptr, 0);
774
775 if (*endptr != '\0') {
776 cil_log(CIL_ERR, "permissionx value %s not valid number\n", permx_str);
777 goto exit;
778 }
779 if (lval < 0x0000 || lval > 0xFFFF) {
780 cil_log(CIL_ERR, "permissionx value %s must be between 0x0000 and 0xFFFF\n", permx_str);
781 goto exit;
782 }
783
784 *val = (uint16_t)lval;
785
786 return SEPOL_OK;
787
788 exit:
789 return SEPOL_ERR;
790 }
791
__cil_permx_to_bitmap(struct cil_symtab_datum * datum,ebitmap_t * bitmap,struct cil_db * db)792 static int __cil_permx_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db)
793 {
794 int rc = SEPOL_ERR;
795 uint16_t val;
796
797 ebitmap_init(bitmap);
798
799 rc = __cil_permx_str_to_int((char*)datum, &val);
800 if (rc != SEPOL_OK) {
801 goto exit;
802 }
803
804 if (ebitmap_set_bit(bitmap, (unsigned int)val, 1)) {
805 cil_log(CIL_ERR, "Failed to set permissionx bit\n");
806 ebitmap_destroy(bitmap);
807 goto exit;
808 }
809
810 return SEPOL_OK;
811
812 exit:
813 return rc;
814 }
815
__cil_perm_to_bitmap(struct cil_symtab_datum * datum,ebitmap_t * bitmap,struct cil_db * db)816 static int __cil_perm_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, __attribute__((unused)) struct cil_db *db)
817 {
818 struct cil_perm *perm = (struct cil_perm *)datum;
819 unsigned int value = perm->value;
820
821 ebitmap_init(bitmap);
822 if (ebitmap_set_bit(bitmap, value, 1)) {
823 cil_log(CIL_INFO, "Failed to set perm bit\n");
824 ebitmap_destroy(bitmap);
825 return SEPOL_ERR;
826 }
827
828 return SEPOL_OK;
829 }
830
__evaluate_cat_expression(struct cil_cats * cats,struct cil_db * db)831 static int __evaluate_cat_expression(struct cil_cats *cats, struct cil_db *db)
832 {
833 int rc = SEPOL_ERR;
834 ebitmap_t bitmap;
835 struct cil_list *new;
836 struct cil_list_item *curr;
837
838 if (cats->evaluated == CIL_TRUE) {
839 return SEPOL_OK;
840 }
841
842 if (cil_verify_is_list(cats->datum_expr, CIL_CAT)) {
843 return SEPOL_OK;
844 }
845
846 ebitmap_init(&bitmap);
847 rc = __cil_expr_to_bitmap(cats->datum_expr, &bitmap, db->num_cats, db);
848 if (rc != SEPOL_OK) {
849 cil_log(CIL_ERR, "Failed to expand category expression to bitmap\n");
850 ebitmap_destroy(&bitmap);
851 goto exit;
852 }
853
854 cil_list_init(&new, CIL_CAT);
855
856 cil_list_for_each(curr, db->catorder) {
857 struct cil_cat *cat = curr->data;
858 if (ebitmap_get_bit(&bitmap, cat->value)) {
859 cil_list_append(new, CIL_DATUM, cat);
860 }
861 }
862
863 ebitmap_destroy(&bitmap);
864 cil_list_destroy(&cats->datum_expr, CIL_FALSE);
865 if (new->head != NULL) {
866 cats->datum_expr = new;
867 } else {
868 /* empty list */
869 cil_list_destroy(&new, CIL_FALSE);
870 cats->datum_expr = NULL;
871 }
872
873 cats->evaluated = CIL_TRUE;
874
875 return SEPOL_OK;
876
877 exit:
878 return rc;
879 }
880
__cil_cat_to_bitmap(struct cil_symtab_datum * datum,ebitmap_t * bitmap,struct cil_db * db)881 static int __cil_cat_to_bitmap(struct cil_symtab_datum *datum, ebitmap_t *bitmap, struct cil_db *db)
882 {
883 int rc = SEPOL_ERR;
884 struct cil_tree_node *node = datum->nodes->head->data;
885
886 ebitmap_init(bitmap);
887
888 if (node->flavor == CIL_CATSET) {
889 struct cil_catset *catset = (struct cil_catset *)datum;
890 struct cil_list_item *curr;
891 if (catset->cats->evaluated == CIL_FALSE) {
892 rc = __evaluate_cat_expression(catset->cats, db);
893 if (rc != SEPOL_OK) goto exit;
894 }
895 for (curr = catset->cats->datum_expr->head; curr; curr = curr->next) {
896 struct cil_cat *cat = (struct cil_cat *)curr->data;
897 if (ebitmap_set_bit(bitmap, cat->value, 1)) {
898 cil_log(CIL_ERR, "Failed to set cat bit\n");
899 ebitmap_destroy(bitmap);
900 goto exit;
901 }
902 }
903 } else if (node->flavor == CIL_CATALIAS) {
904 struct cil_alias *alias = (struct cil_alias *)datum;
905 struct cil_cat *cat = alias->actual;
906 if (ebitmap_set_bit(bitmap, cat->value, 1)) {
907 cil_log(CIL_ERR, "Failed to set cat bit\n");
908 ebitmap_destroy(bitmap);
909 goto exit;
910 }
911 } else {
912 struct cil_cat *cat = (struct cil_cat *)datum;
913 if (ebitmap_set_bit(bitmap, cat->value, 1)) {
914 cil_log(CIL_ERR, "Failed to set cat bit\n");
915 ebitmap_destroy(bitmap);
916 goto exit;
917 }
918 }
919
920 return SEPOL_OK;
921
922 exit:
923 return rc;
924 }
925
__cil_cat_expr_range_to_bitmap_helper(struct cil_list_item * i1,struct cil_list_item * i2,ebitmap_t * bitmap)926 static int __cil_cat_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap)
927 {
928 int rc = SEPOL_ERR;
929 struct cil_symtab_datum *d1 = i1->data;
930 struct cil_symtab_datum *d2 = i2->data;
931 struct cil_tree_node *n1 = d1->nodes->head->data;
932 struct cil_tree_node *n2 = d2->nodes->head->data;
933 struct cil_cat *c1 = (struct cil_cat *)d1;
934 struct cil_cat *c2 = (struct cil_cat *)d2;
935 int i;
936
937 if (n1->flavor == CIL_CATSET || n2->flavor == CIL_CATSET) {
938 cil_log(CIL_ERR, "Category sets cannont be used in a category range\n");
939 goto exit;
940 }
941
942 if (n1->flavor == CIL_CATALIAS) {
943 struct cil_alias *alias = (struct cil_alias *)d1;
944 c1 = alias->actual;
945 }
946
947 if (n2->flavor == CIL_CATALIAS) {
948 struct cil_alias *alias = (struct cil_alias *)d2;
949 c2 = alias->actual;
950 }
951
952 for (i = c1->value; i <= c2->value; i++) {
953 if (ebitmap_set_bit(bitmap, i, 1)) {
954 cil_log(CIL_ERR, "Failed to set cat bit\n");
955 ebitmap_destroy(bitmap);
956 goto exit;
957 }
958 }
959
960 return SEPOL_OK;
961
962 exit:
963 return rc;
964 }
965
__cil_permissionx_expr_range_to_bitmap_helper(struct cil_list_item * i1,struct cil_list_item * i2,ebitmap_t * bitmap)966 static int __cil_permissionx_expr_range_to_bitmap_helper(struct cil_list_item *i1, struct cil_list_item *i2, ebitmap_t *bitmap)
967 {
968 int rc = SEPOL_ERR;
969 char *p1 = i1->data;
970 char *p2 = i2->data;
971 uint16_t v1;
972 uint16_t v2;
973 uint32_t i;
974
975 rc = __cil_permx_str_to_int(p1, &v1);
976 if (rc != SEPOL_OK) {
977 goto exit;
978 }
979
980 rc = __cil_permx_str_to_int(p2, &v2);
981 if (rc != SEPOL_OK) {
982 goto exit;
983 }
984
985 for (i = v1; i <= v2; i++) {
986 if (ebitmap_set_bit(bitmap, i, 1)) {
987 cil_log(CIL_ERR, "Failed to set permissionx bit\n");
988 ebitmap_destroy(bitmap);
989 goto exit;
990 }
991 }
992
993 return SEPOL_OK;
994
995 exit:
996 return rc;
997 }
998
__cil_expr_to_bitmap_helper(struct cil_list_item * curr,enum cil_flavor flavor,ebitmap_t * bitmap,int max,struct cil_db * db)999 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)
1000 {
1001 int rc = SEPOL_ERR;
1002
1003 if (curr->flavor == CIL_DATUM) {
1004 switch (flavor) {
1005 case CIL_TYPE:
1006 rc = __cil_type_to_bitmap(curr->data, bitmap, db);
1007 break;
1008 case CIL_ROLE:
1009 rc = __cil_role_to_bitmap(curr->data, bitmap, db);
1010 break;
1011 case CIL_USER:
1012 rc = __cil_user_to_bitmap(curr->data, bitmap, db);
1013 break;
1014 case CIL_PERM:
1015 rc = __cil_perm_to_bitmap(curr->data, bitmap, db);
1016 break;
1017 case CIL_CAT:
1018 rc = __cil_cat_to_bitmap(curr->data, bitmap, db);
1019 break;
1020 default:
1021 rc = SEPOL_ERR;
1022 }
1023 } else if (curr->flavor == CIL_LIST) {
1024 struct cil_list *l = curr->data;
1025 ebitmap_init(bitmap);
1026 rc = __cil_expr_to_bitmap(l, bitmap, max, db);
1027 if (rc != SEPOL_OK) {
1028 ebitmap_destroy(bitmap);
1029 }
1030 } else if (flavor == CIL_PERMISSIONX) {
1031 // permissionx expressions aren't resolved into anything, so curr->flavor
1032 // is just a CIL_STRING, not a CIL_DATUM, so just check on flavor for those
1033 rc = __cil_permx_to_bitmap(curr->data, bitmap, db);
1034 }
1035
1036 return rc;
1037 }
1038
__cil_expr_to_bitmap(struct cil_list * expr,ebitmap_t * out,int max,struct cil_db * db)1039 static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db)
1040 {
1041 int rc = SEPOL_ERR;
1042 struct cil_list_item *curr;
1043 enum cil_flavor flavor;
1044 ebitmap_t tmp, b1, b2;
1045
1046 if (expr == NULL || expr->head == NULL) {
1047 return SEPOL_OK;
1048 }
1049
1050 curr = expr->head;
1051 flavor = expr->flavor;
1052
1053 if (curr->flavor == CIL_OP) {
1054 enum cil_flavor op = (enum cil_flavor)curr->data;
1055
1056 if (op == CIL_ALL) {
1057 ebitmap_init(&b1); /* all zeros */
1058 rc = ebitmap_not(&tmp, &b1, max);
1059 ebitmap_destroy(&b1);
1060 if (rc != SEPOL_OK) {
1061 cil_log(CIL_INFO, "Failed to expand 'all' operator\n");
1062 ebitmap_destroy(&tmp);
1063 goto exit;
1064 }
1065 } else if (op == CIL_RANGE) {
1066 if (flavor == CIL_CAT) {
1067 ebitmap_init(&tmp);
1068 rc = __cil_cat_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp);
1069 if (rc != SEPOL_OK) {
1070 cil_log(CIL_INFO, "Failed to expand category range\n");
1071 ebitmap_destroy(&tmp);
1072 goto exit;
1073 }
1074 } else if (flavor == CIL_PERMISSIONX) {
1075 ebitmap_init(&tmp);
1076 rc = __cil_permissionx_expr_range_to_bitmap_helper(curr->next, curr->next->next, &tmp);
1077 if (rc != SEPOL_OK) {
1078 cil_log(CIL_INFO, "Failed to expand category range\n");
1079 ebitmap_destroy(&tmp);
1080 goto exit;
1081 }
1082 } else {
1083 cil_log(CIL_INFO, "Range operation only supported for categories permissionx\n");
1084 rc = SEPOL_ERR;
1085 goto exit;
1086 }
1087 } else {
1088 rc = __cil_expr_to_bitmap_helper(curr->next, flavor, &b1, max, db);
1089 if (rc != SEPOL_OK) {
1090 cil_log(CIL_INFO, "Failed to get first operand bitmap\n");
1091 goto exit;
1092 }
1093
1094 if (op == CIL_NOT) {
1095 rc = ebitmap_not(&tmp, &b1, max);
1096 ebitmap_destroy(&b1);
1097 if (rc != SEPOL_OK) {
1098 cil_log(CIL_INFO, "Failed to NOT bitmap\n");
1099 ebitmap_destroy(&tmp);
1100 goto exit;
1101 }
1102 } else {
1103 rc = __cil_expr_to_bitmap_helper(curr->next->next, flavor, &b2, max, db);
1104 if (rc != SEPOL_OK) {
1105 cil_log(CIL_INFO, "Failed to get second operand bitmap\n");
1106 goto exit;
1107 }
1108
1109 if (op == CIL_OR) {
1110 rc = ebitmap_or(&tmp, &b1, &b2);
1111 } else if (op == CIL_AND) {
1112 rc = ebitmap_and(&tmp, &b1, &b2);
1113 } else if (op == CIL_XOR) {
1114 rc = ebitmap_xor(&tmp, &b1, &b2);
1115 } else {
1116 rc = SEPOL_ERR;
1117 }
1118 ebitmap_destroy(&b1);
1119 ebitmap_destroy(&b2);
1120 if (rc != SEPOL_OK) {
1121 cil_log(CIL_INFO, "Failed to apply operator to bitmaps\n");
1122 ebitmap_destroy(&tmp);
1123 goto exit;
1124 }
1125 }
1126 }
1127 } else {
1128 ebitmap_init(&tmp);
1129 for (;curr; curr = curr->next) {
1130 rc = __cil_expr_to_bitmap_helper(curr, flavor, &b2, max, db);
1131 if (rc != SEPOL_OK) {
1132 cil_log(CIL_INFO, "Failed to get operand in list\n");
1133 ebitmap_destroy(&tmp);
1134 goto exit;
1135 }
1136 b1 = tmp;
1137 rc = ebitmap_or(&tmp, &b1, &b2);
1138 ebitmap_destroy(&b1);
1139 ebitmap_destroy(&b2);
1140 if (rc != SEPOL_OK) {
1141 cil_log(CIL_INFO, "Failed to OR operands in list\n");
1142 ebitmap_destroy(&tmp);
1143 goto exit;
1144 }
1145
1146 }
1147 }
1148
1149 ebitmap_union(out, &tmp);
1150 ebitmap_destroy(&tmp);
1151
1152 return SEPOL_OK;
1153
1154 exit:
1155 return rc;
1156 }
1157
__cil_expr_list_to_bitmap(struct cil_list * expr_list,ebitmap_t * out,int max,struct cil_db * db)1158 static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db)
1159 {
1160 int rc = SEPOL_ERR;
1161 struct cil_list_item *expr;
1162
1163 ebitmap_init(out);
1164
1165 if (expr_list == NULL) {
1166 return SEPOL_OK;
1167 }
1168
1169 cil_list_for_each(expr, expr_list) {
1170 ebitmap_t bitmap;
1171 struct cil_list *l = (struct cil_list *)expr->data;
1172 ebitmap_init(&bitmap);
1173 rc = __cil_expr_to_bitmap(l, &bitmap, max, db);
1174 if (rc != SEPOL_OK) {
1175 cil_log(CIL_INFO, "Failed to expand expression list to bitmap\n");
1176 ebitmap_destroy(&bitmap);
1177 goto exit;
1178 }
1179 ebitmap_union(out, &bitmap);
1180 ebitmap_destroy(&bitmap);
1181 }
1182
1183 return SEPOL_OK;
1184
1185 exit:
1186 return SEPOL_ERR;
1187 }
1188
__cil_post_db_attr_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1189 static int __cil_post_db_attr_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
1190 {
1191 int rc = SEPOL_ERR;
1192 struct cil_db *db = extra_args;
1193
1194 switch (node->flavor) {
1195 case CIL_BLOCK: {
1196 struct cil_block *blk = node->data;
1197 if (blk->is_abstract == CIL_TRUE) {
1198 *finished = CIL_TREE_SKIP_HEAD;
1199 }
1200 break;
1201 }
1202 case CIL_MACRO: {
1203 *finished = CIL_TREE_SKIP_HEAD;
1204 break;
1205 }
1206 case CIL_TYPEATTRIBUTE: {
1207 struct cil_typeattribute *attr = node->data;
1208 if (attr->types == NULL) {
1209 rc = __evaluate_type_expression(attr, db);
1210 if (rc != SEPOL_OK) goto exit;
1211 }
1212 break;
1213 }
1214 case CIL_ROLEATTRIBUTE: {
1215 struct cil_roleattribute *attr = node->data;
1216 if (attr->roles == NULL) {
1217 rc = __evaluate_role_expression(attr, db);
1218 if (rc != SEPOL_OK) goto exit;
1219 }
1220 break;
1221 }
1222 case CIL_AVRULEX: {
1223 struct cil_avrule *rule = node->data;
1224 if (rule->perms.x.permx_str == NULL) {
1225 rc = __evaluate_permissionx_expression(rule->perms.x.permx, db);
1226 if (rc != SEPOL_OK) goto exit;
1227 }
1228 break;
1229 }
1230 case CIL_PERMISSIONX: {
1231 struct cil_permissionx *permx = node->data;
1232 rc = __evaluate_permissionx_expression(permx, db);
1233 if (rc != SEPOL_OK) goto exit;
1234 break;
1235 }
1236 case CIL_USERATTRIBUTE: {
1237 struct cil_userattribute *attr = node->data;
1238 if (attr->users == NULL) {
1239 rc = __evaluate_user_expression(attr, db);
1240 if (rc != SEPOL_OK) {
1241 goto exit;
1242 }
1243 }
1244 break;
1245 }
1246 default:
1247 break;
1248 }
1249
1250 return SEPOL_OK;
1251
1252 exit:
1253 return rc;
1254 }
1255
__cil_role_assign_types(struct cil_role * role,struct cil_symtab_datum * datum)1256 static int __cil_role_assign_types(struct cil_role *role, struct cil_symtab_datum *datum)
1257 {
1258 struct cil_tree_node *node = datum->nodes->head->data;
1259
1260 if (role->types == NULL) {
1261 role->types = cil_malloc(sizeof(*role->types));
1262 ebitmap_init(role->types);
1263 }
1264
1265 if (node->flavor == CIL_TYPE) {
1266 struct cil_type *type = (struct cil_type *)datum;
1267 if (ebitmap_set_bit(role->types, type->value, 1)) {
1268 cil_log(CIL_INFO, "Failed to set bit in role types bitmap\n");
1269 goto exit;
1270 }
1271 } else if (node->flavor == CIL_TYPEALIAS) {
1272 struct cil_alias *alias = (struct cil_alias *)datum;
1273 struct cil_type *type = alias->actual;
1274 if (ebitmap_set_bit(role->types, type->value, 1)) {
1275 cil_log(CIL_INFO, "Failed to set bit in role types bitmap\n");
1276 goto exit;
1277 }
1278 } else if (node->flavor == CIL_TYPEATTRIBUTE) {
1279 struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
1280 ebitmap_union(role->types, attr->types);
1281 }
1282
1283 return SEPOL_OK;
1284
1285 exit:
1286 return SEPOL_ERR;
1287 }
1288
__cil_post_db_roletype_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1289 static int __cil_post_db_roletype_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
1290 {
1291 int rc = SEPOL_ERR;
1292 struct cil_db *db = extra_args;
1293
1294 switch (node->flavor) {
1295 case CIL_BLOCK: {
1296 struct cil_block *blk = node->data;
1297 if (blk->is_abstract == CIL_TRUE) {
1298 *finished = CIL_TREE_SKIP_HEAD;
1299 }
1300 break;
1301 }
1302 case CIL_MACRO: {
1303 *finished = CIL_TREE_SKIP_HEAD;
1304 break;
1305 }
1306 case CIL_ROLETYPE: {
1307 struct cil_roletype *roletype = node->data;
1308 struct cil_symtab_datum *role_datum = roletype->role;
1309 struct cil_symtab_datum *type_datum = roletype->type;
1310 struct cil_tree_node *role_node = role_datum->nodes->head->data;
1311
1312 if (role_node->flavor == CIL_ROLEATTRIBUTE) {
1313 struct cil_roleattribute *attr = roletype->role;
1314 ebitmap_node_t *rnode;
1315 unsigned int i;
1316
1317 ebitmap_for_each_bit(attr->roles, rnode, i) {
1318 struct cil_role *role = NULL;
1319
1320 if (!ebitmap_get_bit(attr->roles, i)) {
1321 continue;
1322 }
1323
1324 role = db->val_to_role[i];
1325
1326 rc = __cil_role_assign_types(role, type_datum);
1327 if (rc != SEPOL_OK) {
1328 goto exit;
1329 }
1330 }
1331 } else {
1332 struct cil_role *role = roletype->role;
1333
1334 rc = __cil_role_assign_types(role, type_datum);
1335 if (rc != SEPOL_OK) {
1336 goto exit;
1337 }
1338 }
1339 break;
1340 }
1341 default:
1342 break;
1343 }
1344
1345 return SEPOL_OK;
1346 exit:
1347 cil_log(CIL_INFO, "cil_post_db_roletype_helper failed\n");
1348 return rc;
1349 }
1350
__cil_user_assign_roles(struct cil_user * user,struct cil_symtab_datum * datum)1351 static int __cil_user_assign_roles(struct cil_user *user, struct cil_symtab_datum *datum)
1352 {
1353 struct cil_tree_node *node = datum->nodes->head->data;
1354 struct cil_role *role = NULL;
1355 struct cil_roleattribute *attr = NULL;
1356
1357 if (user->roles == NULL) {
1358 user->roles = cil_malloc(sizeof(*user->roles));
1359 ebitmap_init(user->roles);
1360 }
1361
1362 if (node->flavor == CIL_ROLE) {
1363 role = (struct cil_role *)datum;
1364 if (ebitmap_set_bit(user->roles, role->value, 1)) {
1365 cil_log(CIL_INFO, "Failed to set bit in user roles bitmap\n");
1366 goto exit;
1367 }
1368 } else if (node->flavor == CIL_ROLEATTRIBUTE) {
1369 attr = (struct cil_roleattribute *)datum;
1370 ebitmap_union(user->roles, attr->roles);
1371 }
1372
1373 return SEPOL_OK;
1374
1375 exit:
1376 return SEPOL_ERR;
1377 }
1378
__cil_post_db_userrole_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1379 static int __cil_post_db_userrole_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
1380 {
1381 int rc = SEPOL_ERR;
1382 struct cil_db *db = extra_args;
1383 struct cil_block *blk = NULL;
1384 struct cil_userrole *userrole = NULL;
1385 struct cil_symtab_datum *user_datum = NULL;
1386 struct cil_symtab_datum *role_datum = NULL;
1387 struct cil_tree_node *user_node = NULL;
1388 struct cil_userattribute *u_attr = NULL;
1389 unsigned int i;
1390 struct cil_user *user = NULL;
1391 ebitmap_node_t *unode = NULL;
1392
1393 switch (node->flavor) {
1394 case CIL_BLOCK: {
1395 blk = node->data;
1396 if (blk->is_abstract == CIL_TRUE) {
1397 *finished = CIL_TREE_SKIP_HEAD;
1398 }
1399 break;
1400 }
1401 case CIL_MACRO: {
1402 *finished = CIL_TREE_SKIP_HEAD;
1403 break;
1404 }
1405 case CIL_USERROLE: {
1406 userrole = node->data;
1407 user_datum = userrole->user;
1408 role_datum = userrole->role;
1409 user_node = user_datum->nodes->head->data;
1410
1411 if (user_node->flavor == CIL_USERATTRIBUTE) {
1412 u_attr = userrole->user;
1413
1414 ebitmap_for_each_bit(u_attr->users, unode, i) {
1415 if (!ebitmap_get_bit(u_attr->users, i)) {
1416 continue;
1417 }
1418
1419 user = db->val_to_user[i];
1420
1421 rc = __cil_user_assign_roles(user, role_datum);
1422 if (rc != SEPOL_OK) {
1423 goto exit;
1424 }
1425 }
1426 } else {
1427 user = userrole->user;
1428
1429 rc = __cil_user_assign_roles(user, role_datum);
1430 if (rc != SEPOL_OK) {
1431 goto exit;
1432 }
1433 }
1434
1435 break;
1436 }
1437 default:
1438 break;
1439 }
1440
1441 return SEPOL_OK;
1442 exit:
1443 cil_log(CIL_INFO, "cil_post_db_userrole_helper failed\n");
1444 return rc;
1445 }
1446
__evaluate_level_expression(struct cil_level * level,struct cil_db * db)1447 static int __evaluate_level_expression(struct cil_level *level, struct cil_db *db)
1448 {
1449 if (level->cats != NULL) {
1450 return __evaluate_cat_expression(level->cats, db);
1451 }
1452
1453 return SEPOL_OK;
1454 }
1455
__evaluate_levelrange_expression(struct cil_levelrange * levelrange,struct cil_db * db)1456 static int __evaluate_levelrange_expression(struct cil_levelrange *levelrange, struct cil_db *db)
1457 {
1458 int rc = SEPOL_OK;
1459
1460 if (levelrange->low != NULL && levelrange->low->cats != NULL) {
1461 rc = __evaluate_cat_expression(levelrange->low->cats, db);
1462 if (rc != SEPOL_OK) {
1463 goto exit;
1464 }
1465 }
1466 if (levelrange->high != NULL && levelrange->high->cats != NULL) {
1467 rc = __evaluate_cat_expression(levelrange->high->cats, db);
1468 if (rc != SEPOL_OK) {
1469 goto exit;
1470 }
1471 }
1472
1473 exit:
1474 return rc;
1475 }
1476
__cil_post_db_cat_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1477 static int __cil_post_db_cat_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
1478 {
1479 int rc = SEPOL_ERR;
1480 struct cil_db *db = extra_args;
1481
1482 switch (node->flavor) {
1483 case CIL_BLOCK: {
1484 struct cil_block *blk = node->data;
1485 if (blk->is_abstract == CIL_TRUE) {
1486 *finished = CIL_TREE_SKIP_HEAD;
1487 }
1488 break;
1489 }
1490 case CIL_MACRO: {
1491 *finished = CIL_TREE_SKIP_HEAD;
1492 break;
1493 }
1494 case CIL_CATSET: {
1495 struct cil_catset *catset = node->data;
1496 rc = __evaluate_cat_expression(catset->cats, db);
1497 if (rc != SEPOL_OK) {
1498 goto exit;
1499 }
1500 break;
1501 }
1502 case CIL_SENSCAT: {
1503 struct cil_senscat *senscat = node->data;
1504 rc = __evaluate_cat_expression(senscat->cats, db);
1505 if (rc != SEPOL_OK) {
1506 goto exit;
1507 }
1508 break;
1509 }
1510 case CIL_LEVEL: {
1511 rc = __evaluate_level_expression(node->data, db);
1512 if (rc != SEPOL_OK) {
1513 goto exit;
1514 }
1515 break;
1516 }
1517 case CIL_LEVELRANGE: {
1518 rc = __evaluate_levelrange_expression(node->data, db);
1519 if (rc != SEPOL_OK) {
1520 goto exit;
1521 }
1522 break;
1523 }
1524 case CIL_USER: {
1525 struct cil_user *user = node->data;
1526 rc = __evaluate_level_expression(user->dftlevel, db);
1527 if (rc != SEPOL_OK) {
1528 goto exit;
1529 }
1530 rc = __evaluate_levelrange_expression(user->range, db);
1531 if (rc != SEPOL_OK) {
1532 goto exit;
1533 }
1534 break;
1535 }
1536 case CIL_SELINUXUSERDEFAULT:
1537 case CIL_SELINUXUSER: {
1538 struct cil_selinuxuser *selinuxuser = node->data;
1539 rc = __evaluate_levelrange_expression(selinuxuser->range, db);
1540 if (rc != SEPOL_OK) {
1541 goto exit;
1542 }
1543 break;
1544 }
1545 case CIL_RANGETRANSITION: {
1546 struct cil_rangetransition *rangetrans = node->data;
1547 rc = __evaluate_levelrange_expression(rangetrans->range, db);
1548 if (rc != SEPOL_OK) {
1549 goto exit;
1550 }
1551 break;
1552 }
1553 case CIL_CONTEXT: {
1554 struct cil_context *context = node->data;
1555 rc = __evaluate_levelrange_expression(context->range, db);
1556 if (rc != SEPOL_OK) {
1557 goto exit;
1558 }
1559 break;
1560 }
1561 case CIL_SIDCONTEXT: {
1562 struct cil_sidcontext *sidcontext = node->data;
1563 rc = __evaluate_levelrange_expression(sidcontext->context->range, db);
1564 if (rc != SEPOL_OK) {
1565 goto exit;
1566 }
1567 break;
1568 }
1569 case CIL_FILECON: {
1570 struct cil_filecon *filecon = node->data;
1571 if (filecon->context) {
1572 rc = __evaluate_levelrange_expression(filecon->context->range, db);
1573 if (rc != SEPOL_OK) {
1574 goto exit;
1575 }
1576 }
1577 break;
1578 }
1579 case CIL_PORTCON: {
1580 struct cil_portcon *portcon = node->data;
1581 rc = __evaluate_levelrange_expression(portcon->context->range, db);
1582 if (rc != SEPOL_OK) {
1583 goto exit;
1584 }
1585 break;
1586 }
1587 case CIL_NODECON: {
1588 struct cil_nodecon *nodecon = node->data;
1589 rc = __evaluate_levelrange_expression(nodecon->context->range, db);
1590 if (rc != SEPOL_OK) {
1591 goto exit;
1592 }
1593 break;
1594 }
1595 case CIL_GENFSCON: {
1596 struct cil_genfscon *genfscon = node->data;
1597 rc = __evaluate_levelrange_expression(genfscon->context->range, db);
1598 if (rc != SEPOL_OK) {
1599 goto exit;
1600 }
1601 break;
1602 }
1603 case CIL_NETIFCON: {
1604 struct cil_netifcon *netifcon = node->data;
1605 rc = __evaluate_levelrange_expression(netifcon->if_context->range, db);
1606 if (rc != SEPOL_OK) {
1607 goto exit;
1608 }
1609 rc = __evaluate_levelrange_expression(netifcon->packet_context->range, db);
1610 if (rc != SEPOL_OK) {
1611 goto exit;
1612 }
1613 break;
1614 }
1615 case CIL_PIRQCON: {
1616 struct cil_pirqcon *pirqcon = node->data;
1617 rc = __evaluate_levelrange_expression(pirqcon->context->range, db);
1618 if (rc != SEPOL_OK) {
1619 goto exit;
1620 }
1621 break;
1622 }
1623 case CIL_IOMEMCON: {
1624 struct cil_iomemcon *iomemcon = node->data;
1625 rc = __evaluate_levelrange_expression(iomemcon->context->range, db);
1626 if (rc != SEPOL_OK) {
1627 goto exit;
1628 }
1629 break;
1630 }
1631 case CIL_IOPORTCON: {
1632 struct cil_ioportcon *ioportcon = node->data;
1633 rc = __evaluate_levelrange_expression(ioportcon->context->range, db);
1634 if (rc != SEPOL_OK) {
1635 goto exit;
1636 }
1637 break;
1638 }
1639 case CIL_PCIDEVICECON: {
1640 struct cil_pcidevicecon *pcidevicecon = node->data;
1641 rc = __evaluate_levelrange_expression(pcidevicecon->context->range, db);
1642 if (rc != SEPOL_OK) {
1643 goto exit;
1644 }
1645 break;
1646 }
1647 case CIL_DEVICETREECON: {
1648 struct cil_devicetreecon *devicetreecon = node->data;
1649 rc = __evaluate_levelrange_expression(devicetreecon->context->range, db);
1650 if (rc != SEPOL_OK) {
1651 goto exit;
1652 }
1653 break;
1654 }
1655 case CIL_FSUSE: {
1656 struct cil_fsuse *fsuse = node->data;
1657 rc = __evaluate_levelrange_expression(fsuse->context->range, db);
1658 if (rc != SEPOL_OK) {
1659 goto exit;
1660 }
1661 break;
1662 }
1663 default:
1664 break;
1665 }
1666
1667 return SEPOL_OK;
1668
1669 exit:
1670 return rc;
1671 }
1672
1673 struct perm_to_list {
1674 enum cil_flavor flavor;
1675 ebitmap_t *perms;
1676 struct cil_list *new_list;
1677 };
1678
__perm_bits_to_list(hashtab_key_t k,hashtab_datum_t d,void * args)1679 static int __perm_bits_to_list(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
1680 {
1681 struct perm_to_list *perm_args = (struct perm_to_list *)args;
1682 ebitmap_t *perms = perm_args->perms;
1683 struct cil_list *new_list = perm_args->new_list;
1684 struct cil_perm *perm = (struct cil_perm *)d;
1685 unsigned int value = perm->value;
1686
1687 if (!ebitmap_get_bit(perms, value)) {
1688 return SEPOL_OK;
1689 }
1690
1691 cil_list_append(new_list, CIL_DATUM, d);
1692
1693 return SEPOL_OK;
1694 }
1695
__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)1696 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)
1697 {
1698 int rc = SEPOL_ERR;
1699 struct perm_to_list args;
1700 ebitmap_t bitmap;
1701
1702 if (cil_verify_is_list(perms, CIL_PERM)) {
1703 return SEPOL_OK;
1704 }
1705
1706 ebitmap_init(&bitmap);
1707 rc = __cil_expr_to_bitmap(perms, &bitmap, num_perms, db);
1708 if (rc != SEPOL_OK) {
1709 ebitmap_destroy(&bitmap);
1710 goto exit;
1711 }
1712
1713 cil_list_init(new_list, flavor);
1714
1715 args.flavor = flavor;
1716 args.perms = &bitmap;
1717 args.new_list = *new_list;
1718
1719 cil_symtab_map(class_symtab, __perm_bits_to_list, &args);
1720
1721 if (common_symtab != NULL) {
1722 cil_symtab_map(common_symtab, __perm_bits_to_list, &args);
1723 }
1724
1725 ebitmap_destroy(&bitmap);
1726 return SEPOL_OK;
1727
1728 exit:
1729 return rc;
1730 }
1731
__evaluate_classperms(struct cil_classperms * cp,struct cil_db * db)1732 static int __evaluate_classperms(struct cil_classperms *cp, struct cil_db *db)
1733 {
1734 int rc = SEPOL_ERR;
1735 struct cil_class *class = cp->class;
1736 struct cil_class *common = class->common;
1737 symtab_t *common_symtab = NULL;
1738 struct cil_list *new_list = NULL;
1739
1740 if (common) {
1741 common_symtab = &common->perms;
1742 }
1743
1744 rc = __evaluate_perm_expression(cp->perms, CIL_PERM, &class->perms, common_symtab, class->num_perms, &new_list, db);
1745 if (rc != SEPOL_OK) {
1746 goto exit;
1747 }
1748
1749 if (new_list == NULL) {
1750 return SEPOL_OK;
1751 }
1752
1753 cil_list_destroy(&cp->perms, CIL_FALSE);
1754
1755 cp->perms = new_list;
1756
1757 return SEPOL_OK;
1758
1759 exit:
1760 return rc;
1761 }
1762
__evaluate_classperms_list(struct cil_list * classperms,struct cil_db * db)1763 static int __evaluate_classperms_list(struct cil_list *classperms, struct cil_db *db)
1764 {
1765 int rc = SEPOL_ERR;
1766 struct cil_list_item *curr;
1767
1768 cil_list_for_each(curr, classperms) {
1769 if (curr->flavor == CIL_CLASSPERMS) {
1770 struct cil_classperms *cp = curr->data;
1771 if (FLAVOR(cp->class) == CIL_CLASS) {
1772 rc = __evaluate_classperms(cp, db);
1773 if (rc != SEPOL_OK) {
1774 goto exit;
1775 }
1776 } else { /* MAP */
1777 struct cil_list_item *i = NULL;
1778 cil_list_for_each(i, cp->perms) {
1779 struct cil_perm *cmp = i->data;
1780 rc = __evaluate_classperms_list(cmp->classperms, db);
1781 if (rc != SEPOL_OK) {
1782 goto exit;
1783 }
1784 }
1785 }
1786 } else { /* SET */
1787 struct cil_classperms_set *cp_set = curr->data;
1788 struct cil_classpermission *cp = cp_set->set;
1789 rc = __evaluate_classperms_list(cp->classperms, db);
1790 if (rc != SEPOL_OK) {
1791 goto exit;
1792 }
1793 }
1794 }
1795
1796 return SEPOL_OK;
1797
1798 exit:
1799 return rc;
1800 }
1801
1802 struct class_map_args {
1803 struct cil_db *db;
1804 int rc;
1805 };
1806
__evaluate_map_perm_classperms(hashtab_key_t k,hashtab_datum_t d,void * args)1807 static int __evaluate_map_perm_classperms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
1808 {
1809 struct class_map_args *map_args = args;
1810 struct cil_perm *cmp = (struct cil_perm *)d;
1811
1812 int rc = __evaluate_classperms_list(cmp->classperms, map_args->db);
1813
1814 if (rc != SEPOL_OK) {
1815 map_args->rc = rc;
1816 }
1817
1818 return SEPOL_OK;
1819 }
1820
__evaluate_map_class(struct cil_class * mc,struct cil_db * db)1821 static int __evaluate_map_class(struct cil_class *mc, struct cil_db *db)
1822 {
1823 struct class_map_args map_args;
1824
1825 map_args.db = db;
1826 map_args.rc = SEPOL_OK;
1827 cil_symtab_map(&mc->perms, __evaluate_map_perm_classperms, &map_args);
1828
1829 return map_args.rc;
1830 }
1831
__cil_post_db_classperms_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1832 static int __cil_post_db_classperms_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
1833 {
1834 int rc = SEPOL_ERR;
1835 struct cil_db *db = extra_args;
1836
1837 switch (node->flavor) {
1838 case CIL_BLOCK: {
1839 struct cil_block *blk = node->data;
1840 if (blk->is_abstract == CIL_TRUE) {
1841 *finished = CIL_TREE_SKIP_HEAD;
1842 }
1843 break;
1844 }
1845 case CIL_MACRO:
1846 *finished = CIL_TREE_SKIP_HEAD;
1847 break;
1848 case CIL_MAP_CLASS: {
1849 rc = __evaluate_map_class(node->data, db);
1850 if (rc != SEPOL_OK) {
1851 goto exit;
1852 }
1853 break;
1854 }
1855 case CIL_CLASSPERMISSION: {
1856 struct cil_classpermission *cp = node->data;
1857 rc = __evaluate_classperms_list(cp->classperms, db);
1858 if (rc != SEPOL_OK) {
1859 goto exit;
1860 }
1861 break;
1862 }
1863 case CIL_AVRULE: {
1864 struct cil_avrule *avrule = node->data;
1865 rc = __evaluate_classperms_list(avrule->perms.classperms, db);
1866 if (rc != SEPOL_OK) {
1867 goto exit;
1868 }
1869 break;
1870 }
1871 case CIL_CONSTRAIN:
1872 case CIL_MLSCONSTRAIN: {
1873 struct cil_constrain *constrain = node->data;
1874 rc = __evaluate_classperms_list(constrain->classperms, db);
1875 if (rc != SEPOL_OK) {
1876 goto exit;
1877 }
1878 break;
1879 }
1880 default:
1881 break;
1882 }
1883
1884 return SEPOL_OK;
1885
1886 exit:
1887 return rc;
1888 }
1889
cil_post_db(struct cil_db * db)1890 static int cil_post_db(struct cil_db *db)
1891 {
1892 int rc = SEPOL_ERR;
1893
1894 rc = cil_tree_walk(db->ast->root, __cil_post_db_count_helper, NULL, NULL, db);
1895 if (rc != SEPOL_OK) {
1896 cil_log(CIL_INFO, "Failure during cil databse count helper\n");
1897 goto exit;
1898 }
1899
1900 rc = cil_tree_walk(db->ast->root, __cil_post_db_array_helper, NULL, NULL, db);
1901 if (rc != SEPOL_OK) {
1902 cil_log(CIL_INFO, "Failure during cil database array helper\n");
1903 goto exit;
1904 }
1905
1906 rc = cil_tree_walk(db->ast->root, __cil_post_db_attr_helper, NULL, NULL, db);
1907 if (rc != SEPOL_OK) {
1908 cil_log(CIL_INFO, "Failed to create attribute bitmaps\n");
1909 goto exit;
1910 }
1911
1912 rc = cil_tree_walk(db->ast->root, __cil_post_db_roletype_helper, NULL, NULL, db);
1913 if (rc != SEPOL_OK) {
1914 cil_log(CIL_INFO, "Failed during roletype association\n");
1915 goto exit;
1916 }
1917
1918 rc = cil_tree_walk(db->ast->root, __cil_post_db_userrole_helper, NULL, NULL, db);
1919 if (rc != SEPOL_OK) {
1920 cil_log(CIL_INFO, "Failed during userrole association\n");
1921 goto exit;
1922 }
1923
1924 rc = cil_tree_walk(db->ast->root, __cil_post_db_classperms_helper, NULL, NULL, db);
1925 if (rc != SEPOL_OK) {
1926 cil_log(CIL_INFO, "Failed to evaluate class mapping permissions expressions\n");
1927 goto exit;
1928 }
1929
1930 rc = cil_tree_walk(db->ast->root, __cil_post_db_cat_helper, NULL, NULL, db);
1931 if (rc != SEPOL_OK) {
1932 cil_log(CIL_INFO, "Failed to evaluate category expressions\n");
1933 goto exit;
1934 }
1935
1936 qsort(db->netifcon->array, db->netifcon->count, sizeof(db->netifcon->array), cil_post_netifcon_compare);
1937 qsort(db->genfscon->array, db->genfscon->count, sizeof(db->genfscon->array), cil_post_genfscon_compare);
1938 qsort(db->portcon->array, db->portcon->count, sizeof(db->portcon->array), cil_post_portcon_compare);
1939 qsort(db->nodecon->array, db->nodecon->count, sizeof(db->nodecon->array), cil_post_nodecon_compare);
1940 qsort(db->fsuse->array, db->fsuse->count, sizeof(db->fsuse->array), cil_post_fsuse_compare);
1941 qsort(db->filecon->array, db->filecon->count, sizeof(db->filecon->array), cil_post_filecon_compare);
1942 qsort(db->pirqcon->array, db->pirqcon->count, sizeof(db->pirqcon->array), cil_post_pirqcon_compare);
1943 qsort(db->iomemcon->array, db->iomemcon->count, sizeof(db->iomemcon->array), cil_post_iomemcon_compare);
1944 qsort(db->ioportcon->array, db->ioportcon->count, sizeof(db->ioportcon->array), cil_post_ioportcon_compare);
1945 qsort(db->pcidevicecon->array, db->pcidevicecon->count, sizeof(db->pcidevicecon->array), cil_post_pcidevicecon_compare);
1946 qsort(db->devicetreecon->array, db->devicetreecon->count, sizeof(db->devicetreecon->array), cil_post_devicetreecon_compare);
1947
1948 exit:
1949 return rc;
1950 }
1951
cil_post_verify(struct cil_db * db)1952 static int cil_post_verify(struct cil_db *db)
1953 {
1954 int rc = SEPOL_ERR;
1955 int avrule_cnt = 0;
1956 int handleunknown = -1;
1957 int mls = -1;
1958 int nseuserdflt = 0;
1959 int pass = 0;
1960 struct cil_args_verify extra_args;
1961 struct cil_complex_symtab csymtab;
1962
1963 cil_complex_symtab_init(&csymtab, CIL_CLASS_SYM_SIZE);
1964
1965 extra_args.db = db;
1966 extra_args.csymtab = &csymtab;
1967 extra_args.avrule_cnt = &avrule_cnt;
1968 extra_args.handleunknown = &handleunknown;
1969 extra_args.mls = &mls;
1970 extra_args.nseuserdflt = &nseuserdflt;
1971 extra_args.pass = &pass;
1972
1973 for (pass = 0; pass < 2; pass++) {
1974 rc = cil_tree_walk(db->ast->root, __cil_verify_helper, NULL, NULL, &extra_args);
1975 if (rc != SEPOL_OK) {
1976 cil_log(CIL_ERR, "Failed to verify cil database\n");
1977 goto exit;
1978 }
1979 }
1980
1981 if (db->handle_unknown == -1) {
1982 if (handleunknown == -1) {
1983 db->handle_unknown = SEPOL_DENY_UNKNOWN;
1984 } else {
1985 db->handle_unknown = handleunknown;
1986 }
1987 }
1988
1989 if (db->mls == -1) {
1990 if (mls == -1) {
1991 db->mls = CIL_FALSE;
1992 } else {
1993 db->mls = mls;
1994 }
1995 }
1996
1997 if (avrule_cnt == 0) {
1998 cil_log(CIL_ERR, "Policy must include at least one avrule\n");
1999 rc = SEPOL_ERR;
2000 goto exit;
2001 }
2002
2003 if (nseuserdflt > 1) {
2004 cil_log(CIL_ERR, "Policy cannot contain more than one selinuxuserdefault, found: %d\n", nseuserdflt);
2005 rc = SEPOL_ERR;
2006 goto exit;
2007 }
2008
2009 exit:
2010 cil_complex_symtab_destroy(&csymtab);
2011 return rc;
2012 }
2013
cil_pre_verify(struct cil_db * db)2014 static int cil_pre_verify(struct cil_db *db)
2015 {
2016 int rc = SEPOL_ERR;
2017 struct cil_args_verify extra_args;
2018
2019 extra_args.db = db;
2020
2021 rc = cil_tree_walk(db->ast->root, __cil_pre_verify_helper, NULL, NULL, &extra_args);
2022 if (rc != SEPOL_OK) {
2023 cil_log(CIL_ERR, "Failed to verify cil database\n");
2024 goto exit;
2025 }
2026
2027 exit:
2028 return rc;
2029 }
2030
cil_post_process(struct cil_db * db)2031 int cil_post_process(struct cil_db *db)
2032 {
2033 int rc = SEPOL_ERR;
2034
2035 rc = cil_pre_verify(db);
2036 if (rc != SEPOL_OK) {
2037 cil_log(CIL_ERR, "Failed to verify cil database\n");
2038 goto exit;
2039 }
2040
2041 rc = cil_post_db(db);
2042 if (rc != SEPOL_OK) {
2043 cil_log(CIL_ERR, "Failed post db handling\n");
2044 goto exit;
2045 }
2046
2047 rc = cil_post_verify(db);
2048 if (rc != SEPOL_OK) {
2049 cil_log(CIL_ERR, "Failed to verify cil database\n");
2050 goto exit;
2051 }
2052
2053 exit:
2054 return rc;
2055
2056 }
2057