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