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
34 #include <sepol/policydb/conditional.h>
35
36 #include "cil_internal.h"
37 #include "cil_flavor.h"
38 #include "cil_log.h"
39 #include "cil_mem.h"
40 #include "cil_tree.h"
41 #include "cil_list.h"
42 #include "cil_build_ast.h"
43 #include "cil_resolve_ast.h"
44 #include "cil_reset_ast.h"
45 #include "cil_copy_ast.h"
46 #include "cil_verify.h"
47 #include "cil_strpool.h"
48 #include "cil_symtab.h"
49
50 struct cil_args_resolve {
51 struct cil_db *db;
52 enum cil_pass pass;
53 uint32_t *changed;
54 char *last_resolved_name;
55 struct cil_tree_node *optstack;
56 struct cil_tree_node *boolif;
57 struct cil_tree_node *macro;
58 struct cil_tree_node *blockstack;
59 struct cil_list *sidorder_lists;
60 struct cil_list *classorder_lists;
61 struct cil_list *unordered_classorder_lists;
62 struct cil_list *catorder_lists;
63 struct cil_list *sensitivityorder_lists;
64 struct cil_list *in_list;
65 };
66
__cil_insert_name(struct cil_db * db,hashtab_key_t key,struct cil_tree_node * ast_node)67 static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key, struct cil_tree_node *ast_node)
68 {
69 /* Currently only used for typetransition file names.
70 But could be used for any string that is passed as a parameter.
71 */
72 struct cil_tree_node *parent = ast_node->parent;
73 struct cil_macro *macro = NULL;
74 struct cil_name *name;
75 symtab_t *symtab;
76 enum cil_sym_index sym_index;
77 struct cil_symtab_datum *datum = NULL;
78
79 cil_flavor_to_symtab_index(CIL_NAME, &sym_index);
80 symtab = &((struct cil_root *)db->ast->root->data)->symtab[sym_index];
81
82 cil_symtab_get_datum(symtab, key, &datum);
83 if (datum != NULL) {
84 return (struct cil_name *)datum;
85 }
86
87 if (parent->flavor == CIL_CALL) {
88 struct cil_call *call = parent->data;
89 macro = call->macro;
90 } else if (parent->flavor == CIL_MACRO) {
91 macro = parent->data;
92 }
93 if (macro != NULL) {
94 struct cil_list_item *item;
95 cil_list_for_each(item, macro->params) {
96 if (((struct cil_param*)item->data)->str == key) {
97 return NULL;
98 }
99 }
100 }
101
102 cil_name_init(&name);
103 cil_symtab_insert(symtab, key, (struct cil_symtab_datum *)name, ast_node);
104 cil_list_append(db->names, CIL_NAME, name);
105
106 return name;
107 }
108
__cil_resolve_perms(symtab_t * class_symtab,symtab_t * common_symtab,struct cil_list * perm_strs,struct cil_list ** perm_datums,enum cil_flavor class_flavor)109 static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab, struct cil_list *perm_strs, struct cil_list **perm_datums, enum cil_flavor class_flavor)
110 {
111 int rc = SEPOL_ERR;
112 struct cil_list_item *curr;
113
114 cil_list_init(perm_datums, perm_strs->flavor);
115
116 cil_list_for_each(curr, perm_strs) {
117 if (curr->flavor == CIL_LIST) {
118 struct cil_list *sub_list;
119 rc = __cil_resolve_perms(class_symtab, common_symtab, curr->data, &sub_list, class_flavor);
120 if (rc != SEPOL_OK) {
121 cil_log(CIL_ERR, "Failed to resolve permission list\n");
122 goto exit;
123 }
124 cil_list_append(*perm_datums, CIL_LIST, sub_list);
125 } else if (curr->flavor == CIL_STRING) {
126 struct cil_symtab_datum *perm_datum = NULL;
127 rc = cil_symtab_get_datum(class_symtab, curr->data, &perm_datum);
128 if (rc == SEPOL_ENOENT) {
129 if (common_symtab) {
130 rc = cil_symtab_get_datum(common_symtab, curr->data, &perm_datum);
131 }
132 }
133 if (rc != SEPOL_OK) {
134 struct cil_list *empty_list;
135 if (class_flavor == CIL_MAP_CLASS) {
136 cil_log(CIL_ERR, "Failed to resolve permission %s for map class\n", (char*)curr->data);
137 goto exit;
138 }
139 cil_log(CIL_WARN, "Failed to resolve permission %s\n", (char*)curr->data);
140 /* Use an empty list to represent unknown perm */
141 cil_list_init(&empty_list, perm_strs->flavor);
142 cil_list_append(*perm_datums, CIL_LIST, empty_list);
143 } else {
144 cil_list_append(*perm_datums, CIL_DATUM, perm_datum);
145 }
146 } else {
147 cil_list_append(*perm_datums, curr->flavor, curr->data);
148 }
149 }
150
151 return SEPOL_OK;
152
153 exit:
154 return rc;
155 }
156
cil_resolve_classperms(struct cil_tree_node * current,struct cil_classperms * cp,void * extra_args)157 int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms *cp, void *extra_args)
158 {
159 int rc = SEPOL_ERR;
160 struct cil_symtab_datum *datum = NULL;
161 symtab_t *common_symtab = NULL;
162 struct cil_class *class;
163
164 rc = cil_resolve_name(current, cp->class_str, CIL_SYM_CLASSES, extra_args, &datum);
165 if (rc != SEPOL_OK) {
166 goto exit;
167 }
168
169 class = (struct cil_class *)datum;
170
171 if (class->common != NULL) {
172 common_symtab = &class->common->perms;
173 }
174
175 cp->class = class;
176
177 rc = __cil_resolve_perms(&class->perms, common_symtab, cp->perm_strs, &cp->perms, FLAVOR(datum));
178 if (rc != SEPOL_OK) {
179 goto exit;
180 }
181
182 return SEPOL_OK;
183
184 exit:
185 return rc;
186 }
187
cil_resolve_classperms_set(struct cil_tree_node * current,struct cil_classperms_set * cp_set,void * extra_args)188 int cil_resolve_classperms_set(struct cil_tree_node *current, struct cil_classperms_set *cp_set, void *extra_args)
189 {
190 int rc = SEPOL_ERR;
191 struct cil_symtab_datum *datum = NULL;
192
193 rc = cil_resolve_name(current, cp_set->set_str, CIL_SYM_CLASSPERMSETS, extra_args, &datum);
194 if (rc != SEPOL_OK) {
195 goto exit;
196 }
197 cp_set->set = (struct cil_classpermission*)datum;
198
199 /* This could be an anonymous classpermission */
200 if (datum->name == NULL) {
201 rc = cil_resolve_classperms_list(current, cp_set->set->classperms, extra_args);
202 if (rc != SEPOL_OK) {
203 goto exit;
204 }
205 }
206
207 return SEPOL_OK;
208
209 exit:
210 return rc;
211 }
212
cil_resolve_classperms_list(struct cil_tree_node * current,struct cil_list * cp_list,void * extra_args)213 int cil_resolve_classperms_list(struct cil_tree_node *current, struct cil_list *cp_list, void *extra_args)
214 {
215 int rc = SEPOL_ERR;
216 struct cil_list_item *curr;
217
218 cil_list_for_each(curr, cp_list) {
219 if (curr->flavor == CIL_CLASSPERMS) {
220 rc = cil_resolve_classperms(current, curr->data, extra_args);
221 if (rc != SEPOL_OK) {
222 goto exit;
223 }
224 } else {
225 rc = cil_resolve_classperms_set(current, curr->data, extra_args);
226 if (rc != SEPOL_OK) {
227 goto exit;
228 }
229 }
230 }
231
232 return SEPOL_OK;
233
234 exit:
235 return rc;
236 }
237
cil_resolve_classpermissionset(struct cil_tree_node * current,struct cil_classpermissionset * cps,void * extra_args)238 int cil_resolve_classpermissionset(struct cil_tree_node *current, struct cil_classpermissionset *cps, void *extra_args)
239 {
240 int rc = SEPOL_ERR;
241 struct cil_args_resolve *args = extra_args;
242 struct cil_list_item *curr;
243 struct cil_symtab_datum *datum;
244 struct cil_classpermission *cp;
245
246 rc = cil_resolve_name(current, cps->set_str, CIL_SYM_CLASSPERMSETS, args, &datum);
247 if (rc != SEPOL_OK) {
248 goto exit;
249 }
250
251 rc = cil_resolve_classperms_list(current, cps->classperms, extra_args);
252 if (rc != SEPOL_OK) {
253 goto exit;
254 }
255
256 cp = (struct cil_classpermission *)datum;
257
258 if (cp->classperms == NULL) {
259 cil_list_init(&cp->classperms, CIL_CLASSPERMS);
260 }
261
262 cil_list_for_each(curr, cps->classperms) {
263 cil_list_append(cp->classperms, curr->flavor, curr->data);
264 }
265
266 return SEPOL_OK;
267
268 exit:
269 return rc;
270 }
271
cil_type_used(struct cil_symtab_datum * datum,int used)272 void cil_type_used(struct cil_symtab_datum *datum, int used)
273 {
274 struct cil_typeattribute *attr = NULL;
275
276 if (FLAVOR(datum) == CIL_TYPEATTRIBUTE) {
277 attr = (struct cil_typeattribute*)datum;
278 attr->used |= used;
279 if ((attr->used & CIL_ATTR_EXPAND_TRUE) &&
280 (attr->used & CIL_ATTR_EXPAND_FALSE)) {
281 cil_log(CIL_WARN, "Conflicting use of expandtypeattribute. "
282 "Expandtypeattribute was set to both true or false for %s. "
283 "Resolving to false. \n", attr->datum.name);
284 attr->used &= ~CIL_ATTR_EXPAND_TRUE;
285 }
286 }
287 }
288
cil_resolve_permissionx(struct cil_tree_node * current,struct cil_permissionx * permx,void * extra_args)289 int cil_resolve_permissionx(struct cil_tree_node *current, struct cil_permissionx *permx, void *extra_args)
290 {
291 struct cil_symtab_datum *obj_datum = NULL;
292 int rc = SEPOL_ERR;
293
294 rc = cil_resolve_name(current, permx->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum);
295 if (rc != SEPOL_OK) {
296 goto exit;
297 }
298 permx->obj = (struct cil_class*)obj_datum;
299
300 return SEPOL_OK;
301
302 exit:
303 return rc;
304 }
305
cil_resolve_avrule(struct cil_tree_node * current,void * extra_args)306 int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args)
307 {
308 struct cil_args_resolve *args = extra_args;
309 struct cil_db *db = NULL;
310
311 struct cil_avrule *rule = current->data;
312 struct cil_symtab_datum *src_datum = NULL;
313 struct cil_symtab_datum *tgt_datum = NULL;
314 struct cil_symtab_datum *permx_datum = NULL;
315 int used;
316 int rc = SEPOL_ERR;
317
318 if (args != NULL) {
319 db = args->db;
320 }
321
322 rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, args, &src_datum);
323 if (rc != SEPOL_OK) {
324 goto exit;
325 }
326 rule->src = src_datum;
327
328 if (rule->tgt_str == CIL_KEY_SELF) {
329 rule->tgt = db->selftype;
330 } else {
331 rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, args, &tgt_datum);
332 if (rc != SEPOL_OK) {
333 goto exit;
334 }
335 rule->tgt = tgt_datum;
336 used = (rule->rule_kind == CIL_AVRULE_NEVERALLOW) ?
337 CIL_ATTR_NEVERALLOW : CIL_ATTR_AVRULE;
338 cil_type_used(src_datum, used); /* src not used if tgt is self */
339 cil_type_used(tgt_datum, used);
340 }
341
342 if (!rule->is_extended) {
343 rc = cil_resolve_classperms_list(current, rule->perms.classperms, extra_args);
344 if (rc != SEPOL_OK) {
345 goto exit;
346 }
347 } else {
348 if (rule->perms.x.permx_str != NULL) {
349 rc = cil_resolve_name(current, rule->perms.x.permx_str, CIL_SYM_PERMX, args, &permx_datum);
350 if (rc != SEPOL_OK) {
351 goto exit;
352 }
353 rule->perms.x.permx = (struct cil_permissionx*)permx_datum;
354 } else {
355 rc = cil_resolve_permissionx(current, rule->perms.x.permx, extra_args);
356 if (rc != SEPOL_OK) {
357 goto exit;
358 }
359 }
360 }
361
362 return SEPOL_OK;
363
364 exit:
365 return rc;
366 }
367
cil_resolve_type_rule(struct cil_tree_node * current,void * extra_args)368 int cil_resolve_type_rule(struct cil_tree_node *current, void *extra_args)
369 {
370 struct cil_type_rule *rule = current->data;
371 struct cil_symtab_datum *src_datum = NULL;
372 struct cil_symtab_datum *tgt_datum = NULL;
373 struct cil_symtab_datum *obj_datum = NULL;
374 struct cil_symtab_datum *result_datum = NULL;
375 struct cil_tree_node *result_node = NULL;
376 int rc = SEPOL_ERR;
377
378 rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, extra_args, &src_datum);
379 if (rc != SEPOL_OK) {
380 goto exit;
381 }
382 rule->src = src_datum;
383
384 rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum);
385 if (rc != SEPOL_OK) {
386 goto exit;
387 }
388 rule->tgt = tgt_datum;
389
390 rc = cil_resolve_name(current, rule->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum);
391 if (rc != SEPOL_OK) {
392 goto exit;
393 }
394 rule->obj = (struct cil_class*)obj_datum;
395
396 rc = cil_resolve_name(current, rule->result_str, CIL_SYM_TYPES, extra_args, &result_datum);
397 if (rc != SEPOL_OK) {
398 goto exit;
399 }
400
401 result_node = result_datum->nodes->head->data;
402
403 if (result_node->flavor != CIL_TYPE) {
404 cil_log(CIL_ERR, "Type rule result must be a type [%d]\n",result_node->flavor);
405 rc = SEPOL_ERR;
406 goto exit;
407 }
408 rule->result = result_datum;
409
410 return SEPOL_OK;
411
412 exit:
413 return rc;
414 }
415
cil_resolve_typeattributeset(struct cil_tree_node * current,void * extra_args)416 int cil_resolve_typeattributeset(struct cil_tree_node *current, void *extra_args)
417 {
418 struct cil_typeattributeset *attrtypes = current->data;
419 struct cil_symtab_datum *attr_datum = NULL;
420 struct cil_tree_node *attr_node = NULL;
421 struct cil_typeattribute *attr = NULL;
422 int rc = SEPOL_ERR;
423
424 rc = cil_resolve_name(current, attrtypes->attr_str, CIL_SYM_TYPES, extra_args, &attr_datum);
425 if (rc != SEPOL_OK) {
426 goto exit;
427 }
428
429 attr_node = attr_datum->nodes->head->data;
430
431 if (attr_node->flavor != CIL_TYPEATTRIBUTE) {
432 rc = SEPOL_ERR;
433 cil_log(CIL_ERR, "Attribute type not an attribute\n");
434 goto exit;
435 }
436
437 attr = (struct cil_typeattribute*)attr_datum;
438
439 rc = cil_resolve_expr(CIL_TYPEATTRIBUTESET, attrtypes->str_expr, &attrtypes->datum_expr, current, extra_args);
440 if (rc != SEPOL_OK) {
441 goto exit;
442 }
443
444 rc = cil_verify_no_self_reference(attr_datum, attrtypes->datum_expr);
445 if (rc != SEPOL_OK) {
446 goto exit;
447 }
448
449 if (attr->expr_list == NULL) {
450 cil_list_init(&attr->expr_list, CIL_TYPEATTRIBUTE);
451 }
452
453 cil_list_append(attr->expr_list, CIL_LIST, attrtypes->datum_expr);
454
455 return SEPOL_OK;
456
457 exit:
458 return rc;
459 }
460
cil_resolve_expandtypeattribute(struct cil_tree_node * current,void * extra_args)461 int cil_resolve_expandtypeattribute(struct cil_tree_node *current, void *extra_args)
462 {
463 struct cil_expandtypeattribute *expandattr = current->data;
464 struct cil_symtab_datum *attr_datum = NULL;
465 struct cil_tree_node *attr_node = NULL;
466 struct cil_list_item *curr;
467 int used;
468 int rc = SEPOL_ERR;
469
470 cil_list_init(&expandattr->attr_datums, CIL_TYPE);
471
472 cil_list_for_each(curr, expandattr->attr_strs) {
473 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_TYPES, extra_args, &attr_datum);
474 if (rc != SEPOL_OK) {
475 goto exit;
476 }
477
478 attr_node = attr_datum->nodes->head->data;
479
480 if (attr_node->flavor != CIL_TYPEATTRIBUTE) {
481 rc = SEPOL_ERR;
482 cil_log(CIL_ERR, "Attribute type not an attribute\n");
483 goto exit;
484 }
485 used = expandattr->expand ? CIL_ATTR_EXPAND_TRUE : CIL_ATTR_EXPAND_FALSE;
486 cil_type_used(attr_datum, used);
487 cil_list_append(expandattr->attr_datums, CIL_TYPE, attr_datum);
488 }
489
490 return SEPOL_OK;
491 exit:
492 return rc;
493 }
494
cil_resolve_aliasactual(struct cil_tree_node * current,void * extra_args,enum cil_flavor flavor,enum cil_flavor alias_flavor)495 int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_args, enum cil_flavor flavor, enum cil_flavor alias_flavor)
496 {
497 int rc = SEPOL_ERR;
498 enum cil_sym_index sym_index;
499 struct cil_aliasactual *aliasactual = current->data;
500 struct cil_symtab_datum *alias_datum = NULL;
501 struct cil_symtab_datum *actual_datum = NULL;
502 struct cil_alias *alias;
503
504 rc = cil_flavor_to_symtab_index(flavor, &sym_index);
505 if (rc != SEPOL_OK) {
506 goto exit;
507 }
508
509 rc = cil_resolve_name_keep_aliases(current, aliasactual->alias_str, sym_index, extra_args, &alias_datum);
510 if (rc != SEPOL_OK) {
511 goto exit;
512 }
513 if (NODE(alias_datum)->flavor != alias_flavor) {
514 cil_log(CIL_ERR, "%s is not an alias\n",alias_datum->name);
515 rc = SEPOL_ERR;
516 goto exit;
517 }
518
519 rc = cil_resolve_name(current, aliasactual->actual_str, sym_index, extra_args, &actual_datum);
520 if (rc != SEPOL_OK) {
521 goto exit;
522 }
523
524 if (NODE(actual_datum)->flavor != flavor && NODE(actual_datum)->flavor != alias_flavor) {
525 cil_log(CIL_ERR, "%s is a %s, but aliases a %s\n", alias_datum->name, cil_node_to_string(NODE(alias_datum)), cil_node_to_string(NODE(actual_datum)));
526 rc = SEPOL_ERR;
527 goto exit;
528 }
529
530 alias = (struct cil_alias *)alias_datum;
531
532 if (alias->actual != NULL) {
533 cil_log(CIL_ERR, "%s %s cannot bind more than one value\n", cil_node_to_string(NODE(alias_datum)), alias_datum->name);
534 rc = SEPOL_ERR;
535 goto exit;
536 }
537
538 alias->actual = actual_datum;
539
540 return SEPOL_OK;
541
542 exit:
543 return rc;
544 }
545
cil_resolve_alias_to_actual(struct cil_tree_node * current,enum cil_flavor flavor)546 int cil_resolve_alias_to_actual(struct cil_tree_node *current, enum cil_flavor flavor)
547 {
548 struct cil_alias *alias = current->data;
549 struct cil_alias *a1 = current->data;
550 struct cil_alias *a2 = current->data;
551 struct cil_tree_node *a1_node = NULL;
552 int steps = 0;
553 int limit = 2;
554
555 if (alias->actual == NULL) {
556 cil_tree_log(current, CIL_ERR, "Alias declared but not used");
557 return SEPOL_ERR;
558 }
559
560 a1_node = a1->datum.nodes->head->data;
561
562 while (flavor != a1_node->flavor) {
563 a1 = a1->actual;
564 a1_node = a1->datum.nodes->head->data;
565 steps += 1;
566
567 if (a1 == a2) {
568 cil_log(CIL_ERR, "Circular alias found: %s ", a1->datum.name);
569 a1 = a1->actual;
570 while (a1 != a2) {
571 cil_log(CIL_ERR, "%s ", a1->datum.name);
572 a1 = a1->actual;
573 }
574 cil_log(CIL_ERR,"\n");
575 return SEPOL_ERR;
576 }
577
578 if (steps == limit) {
579 steps = 0;
580 limit *= 2;
581 a2 = a1;
582 }
583 }
584
585 alias->actual = a1;
586
587 return SEPOL_OK;
588 }
589
cil_resolve_typepermissive(struct cil_tree_node * current,void * extra_args)590 int cil_resolve_typepermissive(struct cil_tree_node *current, void *extra_args)
591 {
592 struct cil_typepermissive *typeperm = current->data;
593 struct cil_symtab_datum *type_datum = NULL;
594 struct cil_tree_node *type_node = NULL;
595 int rc = SEPOL_ERR;
596
597 rc = cil_resolve_name(current, typeperm->type_str, CIL_SYM_TYPES, extra_args, &type_datum);
598 if (rc != SEPOL_OK) {
599 goto exit;
600 }
601
602 type_node = type_datum->nodes->head->data;
603
604 if (type_node->flavor != CIL_TYPE && type_node->flavor != CIL_TYPEALIAS) {
605 cil_log(CIL_ERR, "Typepermissive must be a type or type alias\n");
606 rc = SEPOL_ERR;
607 goto exit;
608 }
609
610 typeperm->type = type_datum;
611
612 return SEPOL_OK;
613
614 exit:
615 return rc;
616 }
617
cil_resolve_nametypetransition(struct cil_tree_node * current,void * extra_args)618 int cil_resolve_nametypetransition(struct cil_tree_node *current, void *extra_args)
619 {
620 struct cil_args_resolve *args = extra_args;
621 struct cil_nametypetransition *nametypetrans = current->data;
622 struct cil_symtab_datum *src_datum = NULL;
623 struct cil_symtab_datum *tgt_datum = NULL;
624 struct cil_symtab_datum *obj_datum = NULL;
625 struct cil_symtab_datum *name_datum = NULL;
626 struct cil_symtab_datum *result_datum = NULL;
627 struct cil_tree_node *result_node = NULL;
628 int rc = SEPOL_ERR;
629
630 rc = cil_resolve_name(current, nametypetrans->src_str, CIL_SYM_TYPES, extra_args, &src_datum);
631 if (rc != SEPOL_OK) {
632 goto exit;
633 }
634 nametypetrans->src = src_datum;
635
636 rc = cil_resolve_name(current, nametypetrans->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum);
637 if (rc != SEPOL_OK) {
638 goto exit;
639 }
640 nametypetrans->tgt = tgt_datum;
641
642 rc = cil_resolve_name(current, nametypetrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum);
643 if (rc != SEPOL_OK) {
644 goto exit;
645 }
646 nametypetrans->obj = (struct cil_class*)obj_datum;
647
648 nametypetrans->name = __cil_insert_name(args->db, nametypetrans->name_str, current);
649 if (nametypetrans->name == NULL) {
650 rc = cil_resolve_name(current, nametypetrans->name_str, CIL_SYM_NAMES, extra_args, &name_datum);
651 if (rc != SEPOL_OK) {
652 goto exit;
653 }
654 nametypetrans->name = (struct cil_name *)name_datum;
655 }
656
657 rc = cil_resolve_name(current, nametypetrans->result_str, CIL_SYM_TYPES, extra_args, &result_datum);
658 if (rc != SEPOL_OK) {
659 goto exit;
660 }
661
662 result_node = result_datum->nodes->head->data;
663
664 if (result_node->flavor != CIL_TYPE && result_node->flavor != CIL_TYPEALIAS) {
665 cil_log(CIL_ERR, "typetransition result is not a type or type alias\n");
666 rc = SEPOL_ERR;
667 goto exit;
668 }
669 nametypetrans->result = result_datum;
670
671 return SEPOL_OK;
672
673 exit:
674 return rc;
675 }
676
cil_resolve_rangetransition(struct cil_tree_node * current,void * extra_args)677 int cil_resolve_rangetransition(struct cil_tree_node *current, void *extra_args)
678 {
679 struct cil_rangetransition *rangetrans = current->data;
680 struct cil_symtab_datum *src_datum = NULL;
681 struct cil_symtab_datum *exec_datum = NULL;
682 struct cil_symtab_datum *obj_datum = NULL;
683 struct cil_symtab_datum *range_datum = NULL;
684 int rc = SEPOL_ERR;
685
686 rc = cil_resolve_name(current, rangetrans->src_str, CIL_SYM_TYPES, extra_args, &src_datum);
687 if (rc != SEPOL_OK) {
688 goto exit;
689 }
690 rangetrans->src = src_datum;
691
692 rc = cil_resolve_name(current, rangetrans->exec_str, CIL_SYM_TYPES, extra_args, &exec_datum);
693 if (rc != SEPOL_OK) {
694 goto exit;
695 }
696 rangetrans->exec = exec_datum;
697
698 rc = cil_resolve_name(current, rangetrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum);
699 if (rc != SEPOL_OK) {
700 goto exit;
701 }
702 rangetrans->obj = (struct cil_class*)obj_datum;
703
704 if (rangetrans->range_str != NULL) {
705 rc = cil_resolve_name(current, rangetrans->range_str, CIL_SYM_LEVELRANGES, extra_args, &range_datum);
706 if (rc != SEPOL_OK) {
707 goto exit;
708 }
709 rangetrans->range = (struct cil_levelrange*)range_datum;
710
711 /* This could still be an anonymous levelrange even if range_str is set, if range_str is a param_str*/
712 if (rangetrans->range->datum.name == NULL) {
713 rc = cil_resolve_levelrange(current, rangetrans->range, extra_args);
714 if (rc != SEPOL_OK) {
715 goto exit;
716 }
717 }
718 } else {
719 rc = cil_resolve_levelrange(current, rangetrans->range, extra_args);
720 if (rc != SEPOL_OK) {
721 goto exit;
722 }
723 }
724
725 return SEPOL_OK;
726
727 exit:
728 return rc;
729 }
730
__class_update_perm_values(hashtab_key_t k,hashtab_datum_t d,void * args)731 int __class_update_perm_values(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
732 {
733 struct cil_perm *perm = (struct cil_perm *)d;
734
735 perm->value += *((int *)args);
736
737 return SEPOL_OK;
738 }
739
cil_resolve_classcommon(struct cil_tree_node * current,void * extra_args)740 int cil_resolve_classcommon(struct cil_tree_node *current, void *extra_args)
741 {
742 struct cil_class *class = NULL;
743 struct cil_class *common = NULL;
744 struct cil_classcommon *clscom = current->data;
745 struct cil_symtab_datum *class_datum = NULL;
746 struct cil_symtab_datum *common_datum = NULL;
747 int rc = SEPOL_ERR;
748
749 rc = cil_resolve_name(current, clscom->class_str, CIL_SYM_CLASSES, extra_args, &class_datum);
750 if (rc != SEPOL_OK) {
751 goto exit;
752 }
753
754 rc = cil_resolve_name(current, clscom->common_str, CIL_SYM_COMMONS, extra_args, &common_datum);
755 if (rc != SEPOL_OK) {
756 goto exit;
757 }
758
759 class = (struct cil_class *)class_datum;
760 common = (struct cil_class *)common_datum;
761 if (class->common != NULL) {
762 cil_log(CIL_ERR, "class cannot be associeated with more than one common\n");
763 rc = SEPOL_ERR;
764 goto exit;
765 }
766
767 class->common = common;
768
769 cil_symtab_map(&class->perms, __class_update_perm_values, &common->num_perms);
770
771 class->num_perms += common->num_perms;
772 if (class->num_perms > CIL_PERMS_PER_CLASS) {
773 cil_tree_log(current, CIL_ERR, "Too many permissions in class '%s' when including common permissions", class->datum.name);
774 goto exit;
775 }
776
777 return SEPOL_OK;
778
779 exit:
780 return rc;
781 }
782
cil_resolve_classmapping(struct cil_tree_node * current,void * extra_args)783 int cil_resolve_classmapping(struct cil_tree_node *current, void *extra_args)
784 {
785 int rc = SEPOL_ERR;
786 struct cil_classmapping *mapping = current->data;
787 struct cil_class *map = NULL;
788 struct cil_perm *mp = NULL;
789 struct cil_symtab_datum *datum = NULL;
790 struct cil_list_item *curr;
791
792 rc = cil_resolve_name(current, mapping->map_class_str, CIL_SYM_CLASSES, extra_args, &datum);
793 if (rc != SEPOL_OK) {
794 goto exit;
795 }
796 map = (struct cil_class*)datum;
797
798 rc = cil_symtab_get_datum(&map->perms, mapping->map_perm_str, &datum);
799 if (rc != SEPOL_OK) {
800 goto exit;
801 }
802
803 mp = (struct cil_perm*)datum;
804
805 rc = cil_resolve_classperms_list(current, mapping->classperms, extra_args);
806 if (rc != SEPOL_OK) {
807 goto exit;
808 }
809
810 if (mp->classperms == NULL) {
811 cil_list_init(&mp->classperms, CIL_CLASSPERMS);
812 }
813
814 cil_list_for_each(curr, mapping->classperms) {
815 cil_list_append(mp->classperms, curr->flavor, curr->data);
816 }
817
818 return SEPOL_OK;
819
820 exit:
821 return rc;
822 }
823
cil_resolve_userrole(struct cil_tree_node * current,void * extra_args)824 int cil_resolve_userrole(struct cil_tree_node *current, void *extra_args)
825 {
826 struct cil_userrole *userrole = current->data;
827 struct cil_symtab_datum *user_datum = NULL;
828 struct cil_symtab_datum *role_datum = NULL;
829 int rc = SEPOL_ERR;
830
831 rc = cil_resolve_name(current, userrole->user_str, CIL_SYM_USERS, extra_args, &user_datum);
832 if (rc != SEPOL_OK) {
833 goto exit;
834 }
835 userrole->user = (struct cil_user*)user_datum;
836
837 rc = cil_resolve_name(current, userrole->role_str, CIL_SYM_ROLES, extra_args, &role_datum);
838 if (rc != SEPOL_OK) {
839 goto exit;
840 }
841 userrole->role = role_datum;
842
843 return SEPOL_OK;
844
845 exit:
846 return rc;
847 }
848
cil_resolve_userlevel(struct cil_tree_node * current,void * extra_args)849 int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args)
850 {
851 struct cil_userlevel *usrlvl = current->data;
852 struct cil_symtab_datum *user_datum = NULL;
853 struct cil_symtab_datum *lvl_datum = NULL;
854 struct cil_user *user = NULL;
855 struct cil_tree_node *user_node = NULL;
856 int rc = SEPOL_ERR;
857
858 rc = cil_resolve_name(current, usrlvl->user_str, CIL_SYM_USERS, extra_args, &user_datum);
859 if (rc != SEPOL_OK) {
860 goto exit;
861 }
862
863 user_node = user_datum->nodes->head->data;
864
865 if (user_node->flavor != CIL_USER) {
866 cil_log(CIL_ERR, "Userlevel must be a user\n");
867 rc = SEPOL_ERR;
868 goto exit;
869 }
870
871 user = (struct cil_user*)user_datum;
872
873 if (usrlvl->level_str != NULL) {
874 rc = cil_resolve_name(current, usrlvl->level_str, CIL_SYM_LEVELS, extra_args, &lvl_datum);
875 if (rc != SEPOL_OK) {
876 goto exit;
877 }
878 usrlvl->level = (struct cil_level*)lvl_datum;
879 user->dftlevel = usrlvl->level;
880
881 /* This could still be an anonymous level even if level_str is set, if level_str is a param_str*/
882 if (user->dftlevel->datum.name == NULL) {
883 rc = cil_resolve_level(current, user->dftlevel, extra_args);
884 if (rc != SEPOL_OK) {
885 goto exit;
886 }
887 }
888 } else if (usrlvl->level != NULL) {
889 rc = cil_resolve_level(current, usrlvl->level, extra_args);
890 if (rc != SEPOL_OK) {
891 goto exit;
892 }
893 user->dftlevel = usrlvl->level;
894 }
895
896 return SEPOL_OK;
897
898 exit:
899 return rc;
900 }
901
cil_resolve_userrange(struct cil_tree_node * current,void * extra_args)902 int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args)
903 {
904 struct cil_userrange *userrange = current->data;
905 struct cil_symtab_datum *user_datum = NULL;
906 struct cil_symtab_datum *range_datum = NULL;
907 struct cil_user *user = NULL;
908 struct cil_tree_node *user_node = NULL;
909 int rc = SEPOL_ERR;
910
911 rc = cil_resolve_name(current, userrange->user_str, CIL_SYM_USERS, extra_args, &user_datum);
912 if (rc != SEPOL_OK) {
913 goto exit;
914 }
915
916 user_node = user_datum->nodes->head->data;
917
918 if (user_node->flavor != CIL_USER) {
919 cil_log(CIL_ERR, "Userrange must be a user: %s\n", user_datum->fqn);
920 rc = SEPOL_ERR;
921 goto exit;
922 }
923
924 user = (struct cil_user*)user_datum;
925
926 if (userrange->range_str != NULL) {
927 rc = cil_resolve_name(current, userrange->range_str, CIL_SYM_LEVELRANGES, extra_args, &range_datum);
928 if (rc != SEPOL_OK) {
929 goto exit;
930 }
931 userrange->range = (struct cil_levelrange*)range_datum;
932 user->range = userrange->range;
933
934 /* This could still be an anonymous levelrange even if levelrange_str is set, if levelrange_str is a param_str*/
935 if (user->range->datum.name == NULL) {
936 rc = cil_resolve_levelrange(current, user->range, extra_args);
937 if (rc != SEPOL_OK) {
938 goto exit;
939 }
940 }
941 } else if (userrange->range != NULL) {
942 rc = cil_resolve_levelrange(current, userrange->range, extra_args);
943 if (rc != SEPOL_OK) {
944 goto exit;
945 }
946 user->range = userrange->range;
947 }
948
949 return SEPOL_OK;
950
951 exit:
952 return rc;
953 }
954
cil_resolve_userprefix(struct cil_tree_node * current,void * extra_args)955 int cil_resolve_userprefix(struct cil_tree_node *current, void *extra_args)
956 {
957 struct cil_userprefix *userprefix = current->data;
958 struct cil_symtab_datum *user_datum = NULL;
959 struct cil_tree_node *user_node = NULL;
960 int rc = SEPOL_ERR;
961
962 rc = cil_resolve_name(current, userprefix->user_str, CIL_SYM_USERS, extra_args, &user_datum);
963 if (rc != SEPOL_OK) {
964 goto exit;
965 }
966
967 user_node = user_datum->nodes->head->data;
968
969 if (user_node->flavor != CIL_USER) {
970 cil_log(CIL_ERR, "Userprefix must be a user: %s\n", user_datum->fqn);
971 rc = SEPOL_ERR;
972 goto exit;
973 }
974
975 userprefix->user = (struct cil_user*)user_datum;
976
977 exit:
978 return rc;
979 }
980
cil_resolve_selinuxuser(struct cil_tree_node * current,void * extra_args)981 int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args)
982 {
983 struct cil_selinuxuser *selinuxuser = current->data;
984 struct cil_symtab_datum *user_datum = NULL;
985 struct cil_symtab_datum *lvlrange_datum = NULL;
986 struct cil_tree_node *user_node = NULL;
987 int rc = SEPOL_ERR;
988
989 rc = cil_resolve_name(current, selinuxuser->user_str, CIL_SYM_USERS, extra_args, &user_datum);
990 if (rc != SEPOL_OK) {
991 goto exit;
992 }
993
994 user_node = user_datum->nodes->head->data;
995
996 if (user_node->flavor != CIL_USER) {
997 cil_log(CIL_ERR, "Selinuxuser must be a user: %s\n", user_datum->fqn);
998 rc = SEPOL_ERR;
999 goto exit;
1000 }
1001
1002 selinuxuser->user = (struct cil_user*)user_datum;
1003
1004 if (selinuxuser->range_str != NULL) {
1005 rc = cil_resolve_name(current, selinuxuser->range_str, CIL_SYM_LEVELRANGES, extra_args, &lvlrange_datum);
1006 if (rc != SEPOL_OK) {
1007 goto exit;
1008 }
1009 selinuxuser->range = (struct cil_levelrange*)lvlrange_datum;
1010
1011 /* This could still be an anonymous levelrange even if range_str is set, if range_str is a param_str*/
1012 if (selinuxuser->range->datum.name == NULL) {
1013 rc = cil_resolve_levelrange(current, selinuxuser->range, extra_args);
1014 if (rc != SEPOL_OK) {
1015 goto exit;
1016 }
1017 }
1018 } else if (selinuxuser->range != NULL) {
1019 rc = cil_resolve_levelrange(current, selinuxuser->range, extra_args);
1020 if (rc != SEPOL_OK) {
1021 goto exit;
1022 }
1023 }
1024
1025 rc = SEPOL_OK;
1026 exit:
1027 return rc;
1028 }
1029
cil_resolve_roletype(struct cil_tree_node * current,void * extra_args)1030 int cil_resolve_roletype(struct cil_tree_node *current, void *extra_args)
1031 {
1032 struct cil_roletype *roletype = current->data;
1033 struct cil_symtab_datum *role_datum = NULL;
1034 struct cil_symtab_datum *type_datum = NULL;
1035 int rc = SEPOL_ERR;
1036
1037 rc = cil_resolve_name(current, roletype->role_str, CIL_SYM_ROLES, extra_args, &role_datum);
1038 if (rc != SEPOL_OK) {
1039 goto exit;
1040 }
1041 roletype->role = (struct cil_role*)role_datum;
1042
1043 rc = cil_resolve_name(current, roletype->type_str, CIL_SYM_TYPES, extra_args, &type_datum);
1044 if (rc != SEPOL_OK) {
1045 goto exit;
1046 }
1047 roletype->type = (struct cil_type*)type_datum;
1048
1049 return SEPOL_OK;
1050
1051 exit:
1052 return rc;
1053 }
1054
cil_resolve_roletransition(struct cil_tree_node * current,void * extra_args)1055 int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args)
1056 {
1057 struct cil_roletransition *roletrans = current->data;
1058 struct cil_symtab_datum *src_datum = NULL;
1059 struct cil_symtab_datum *tgt_datum = NULL;
1060 struct cil_symtab_datum *obj_datum = NULL;
1061 struct cil_symtab_datum *result_datum = NULL;
1062 struct cil_tree_node *node = NULL;
1063 int rc = SEPOL_ERR;
1064
1065 rc = cil_resolve_name(current, roletrans->src_str, CIL_SYM_ROLES, extra_args, &src_datum);
1066 if (rc != SEPOL_OK) {
1067 goto exit;
1068 }
1069 roletrans->src = (struct cil_role*)src_datum;
1070
1071 rc = cil_resolve_name(current, roletrans->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum);
1072 if (rc != SEPOL_OK) {
1073 goto exit;
1074 }
1075 roletrans->tgt = tgt_datum;
1076
1077 rc = cil_resolve_name(current, roletrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum);
1078 if (rc != SEPOL_OK) {
1079 goto exit;
1080 }
1081 roletrans->obj = (struct cil_class*)obj_datum;
1082
1083 rc = cil_resolve_name(current, roletrans->result_str, CIL_SYM_ROLES, extra_args, &result_datum);
1084 if (rc != SEPOL_OK) {
1085 goto exit;
1086 }
1087 node = result_datum->nodes->head->data;
1088 if (node->flavor != CIL_ROLE) {
1089 rc = SEPOL_ERR;
1090 printf("%i\n", node->flavor);
1091 cil_log(CIL_ERR, "roletransition must result in a role, but %s is a %s\n", roletrans->result_str, cil_node_to_string(node));
1092 goto exit;
1093 }
1094 roletrans->result = (struct cil_role*)result_datum;
1095
1096 return SEPOL_OK;
1097
1098 exit:
1099 return rc;
1100 }
1101
cil_resolve_roleallow(struct cil_tree_node * current,void * extra_args)1102 int cil_resolve_roleallow(struct cil_tree_node *current, void *extra_args)
1103 {
1104 struct cil_roleallow *roleallow = current->data;
1105 struct cil_symtab_datum *src_datum = NULL;
1106 struct cil_symtab_datum *tgt_datum = NULL;
1107 int rc = SEPOL_ERR;
1108
1109 rc = cil_resolve_name(current, roleallow->src_str, CIL_SYM_ROLES, extra_args, &src_datum);
1110 if (rc != SEPOL_OK) {
1111 goto exit;
1112 }
1113 roleallow->src = (struct cil_role*)src_datum;
1114
1115 rc = cil_resolve_name(current, roleallow->tgt_str, CIL_SYM_ROLES, extra_args, &tgt_datum);
1116 if (rc != SEPOL_OK) {
1117 goto exit;
1118 }
1119 roleallow->tgt = (struct cil_role*)tgt_datum;
1120
1121 return SEPOL_OK;
1122
1123 exit:
1124 return rc;
1125 }
1126
cil_resolve_roleattributeset(struct cil_tree_node * current,void * extra_args)1127 int cil_resolve_roleattributeset(struct cil_tree_node *current, void *extra_args)
1128 {
1129 int rc = SEPOL_ERR;
1130 struct cil_roleattributeset *attrroles = current->data;
1131 struct cil_symtab_datum *attr_datum = NULL;
1132 struct cil_tree_node *attr_node = NULL;
1133 struct cil_roleattribute *attr = NULL;
1134
1135 rc = cil_resolve_name(current, attrroles->attr_str, CIL_SYM_ROLES, extra_args, &attr_datum);
1136 if (rc != SEPOL_OK) {
1137 goto exit;
1138 }
1139 attr_node = attr_datum->nodes->head->data;
1140
1141 if (attr_node->flavor != CIL_ROLEATTRIBUTE) {
1142 rc = SEPOL_ERR;
1143 cil_log(CIL_ERR, "Attribute role not an attribute\n");
1144 goto exit;
1145 }
1146 attr = (struct cil_roleattribute*)attr_datum;
1147
1148 rc = cil_resolve_expr(CIL_ROLEATTRIBUTESET, attrroles->str_expr, &attrroles->datum_expr, current, extra_args);
1149 if (rc != SEPOL_OK) {
1150 goto exit;
1151 }
1152
1153 rc = cil_verify_no_self_reference(attr_datum, attrroles->datum_expr);
1154 if (rc != SEPOL_OK) {
1155 goto exit;
1156 }
1157
1158 if (attr->expr_list == NULL) {
1159 cil_list_init(&attr->expr_list, CIL_ROLEATTRIBUTE);
1160 }
1161
1162 cil_list_append(attr->expr_list, CIL_LIST, attrroles->datum_expr);
1163
1164 return SEPOL_OK;
1165
1166 exit:
1167 return rc;
1168 }
1169
1170 struct cil_ordered_list {
1171 int merged;
1172 struct cil_list *list;
1173 struct cil_tree_node *node;
1174 };
1175
__cil_ordered_list_init(struct cil_ordered_list ** ordered)1176 void __cil_ordered_list_init(struct cil_ordered_list **ordered)
1177 {
1178 *ordered = cil_malloc(sizeof(**ordered));
1179
1180 (*ordered)->merged = CIL_FALSE;
1181 (*ordered)->list = NULL;
1182 (*ordered)->node = NULL;
1183 }
1184
__cil_ordered_list_destroy(struct cil_ordered_list ** ordered)1185 void __cil_ordered_list_destroy(struct cil_ordered_list **ordered)
1186 {
1187 cil_list_destroy(&(*ordered)->list, CIL_FALSE);
1188 (*ordered)->node = NULL;
1189 free(*ordered);
1190 *ordered = NULL;
1191 }
1192
__cil_ordered_lists_destroy(struct cil_list ** ordered_lists)1193 void __cil_ordered_lists_destroy(struct cil_list **ordered_lists)
1194 {
1195 struct cil_list_item *item = NULL;
1196
1197 if (ordered_lists == NULL || *ordered_lists == NULL) {
1198 return;
1199 }
1200
1201 item = (*ordered_lists)->head;
1202 while (item != NULL) {
1203 struct cil_list_item *next = item->next;
1204 struct cil_ordered_list *ordered = item->data;
1205 __cil_ordered_list_destroy(&ordered);
1206 free(item);
1207 item = next;
1208 }
1209 free(*ordered_lists);
1210 *ordered_lists = NULL;
1211 }
1212
__cil_ordered_lists_reset(struct cil_list ** ordered_lists)1213 void __cil_ordered_lists_reset(struct cil_list **ordered_lists)
1214 {
1215 __cil_ordered_lists_destroy(ordered_lists);
1216 cil_list_init(ordered_lists, CIL_LIST_ITEM);
1217 }
1218
__cil_ordered_item_insert(struct cil_list * old,struct cil_list_item * curr,struct cil_list_item * item)1219 struct cil_list_item *__cil_ordered_item_insert(struct cil_list *old, struct cil_list_item *curr, struct cil_list_item *item)
1220 {
1221 if (item->flavor == CIL_SID) {
1222 struct cil_sid *sid = item->data;
1223 if (sid->ordered == CIL_TRUE) {
1224 cil_log(CIL_ERR, "SID %s has already been merged into the ordered list\n", sid->datum.name);
1225 return NULL;
1226 }
1227 sid->ordered = CIL_TRUE;
1228 } else if (item->flavor == CIL_CLASS) {
1229 struct cil_class *class = item->data;
1230 if (class->ordered == CIL_TRUE) {
1231 cil_log(CIL_ERR, "Class %s has already been merged into the ordered list\n", class->datum.name);
1232 return NULL;
1233 }
1234 class->ordered = CIL_TRUE;
1235 } else if (item->flavor == CIL_CAT) {
1236 struct cil_cat *cat = item->data;
1237 if (cat->ordered == CIL_TRUE) {
1238 cil_log(CIL_ERR, "Category %s has already been merged into the ordered list\n", cat->datum.name);
1239 return NULL;
1240 }
1241 cat->ordered = CIL_TRUE;
1242 } else if (item->flavor == CIL_SENS) {
1243 struct cil_sens *sens = item->data;
1244 if (sens->ordered == CIL_TRUE) {
1245 cil_log(CIL_ERR, "Sensitivity %s has already been merged into the ordered list\n", sens->datum.name);
1246 return NULL;
1247 }
1248 sens->ordered = CIL_TRUE;
1249 }
1250
1251 return cil_list_insert(old, curr, item->flavor, item->data);
1252 }
1253
__cil_ordered_list_insert(struct cil_list * old,struct cil_list_item * ocurr,struct cil_list_item * nstart,struct cil_list_item * nstop)1254 int __cil_ordered_list_insert(struct cil_list *old, struct cil_list_item *ocurr, struct cil_list_item *nstart, struct cil_list_item *nstop)
1255 {
1256 struct cil_list_item *ncurr = NULL;
1257
1258 for (ncurr = nstart; ncurr != nstop; ncurr = ncurr->next) {
1259 ocurr = __cil_ordered_item_insert(old, ocurr, ncurr);
1260 if (ocurr == NULL) {
1261 return SEPOL_ERR;
1262 }
1263 }
1264 return SEPOL_OK;
1265 }
1266
__cil_ordered_find_match(struct cil_list_item * t,struct cil_list_item * i)1267 struct cil_list_item *__cil_ordered_find_match(struct cil_list_item *t, struct cil_list_item *i)
1268 {
1269 while (i) {
1270 if (i->data == t->data) {
1271 return i;
1272 }
1273 i = i->next;
1274 }
1275 return NULL;
1276 }
1277
__cil_ordered_lists_merge(struct cil_list * old,struct cil_list * new)1278 int __cil_ordered_lists_merge(struct cil_list *old, struct cil_list *new)
1279 {
1280 struct cil_list_item *omatch = NULL;
1281 struct cil_list_item *ofirst = old->head;
1282 struct cil_list_item *ocurr = NULL;
1283 struct cil_list_item *oprev = NULL;
1284 struct cil_list_item *nmatch = NULL;
1285 struct cil_list_item *nfirst = new->head;
1286 struct cil_list_item *ncurr = NULL;
1287 int rc = SEPOL_ERR;
1288
1289 if (nfirst == NULL) {
1290 return SEPOL_OK;
1291 }
1292
1293 if (ofirst == NULL) {
1294 /* First list added */
1295 rc = __cil_ordered_list_insert(old, NULL, nfirst, NULL);
1296 return rc;
1297 }
1298
1299 /* Find a match between the new list and the old one */
1300 for (nmatch = nfirst; nmatch; nmatch = nmatch->next) {
1301 omatch = __cil_ordered_find_match(nmatch, ofirst);
1302 if (omatch) {
1303 break;
1304 }
1305 }
1306
1307 if (!nmatch) {
1308 /* List cannot be merged yet */
1309 return SEPOL_ERR;
1310 }
1311
1312 if (nmatch != nfirst && omatch != ofirst) {
1313 /* Potential ordering conflict--try again later */
1314 return SEPOL_ERR;
1315 }
1316
1317 if (nmatch != nfirst) {
1318 /* Prepend the beginning of the new list up to the first match to the old list */
1319 rc = __cil_ordered_list_insert(old, NULL, nfirst, nmatch);
1320 if (rc != SEPOL_OK) {
1321 return rc;
1322 }
1323 }
1324
1325 /* In the overlapping protion, add items from the new list not in the old list */
1326 ncurr = nmatch->next;
1327 ocurr = omatch->next;
1328 oprev = omatch;
1329 while (ncurr && ocurr) {
1330 if (ncurr->data == ocurr->data) {
1331 oprev = ocurr;
1332 ocurr = ocurr->next;
1333 ncurr = ncurr->next;
1334 } else {
1335 /* Handle gap in old: old = (A C) new = (A B C) */
1336 nmatch = __cil_ordered_find_match(ocurr, ncurr->next);
1337 if (nmatch) {
1338 rc = __cil_ordered_list_insert(old, oprev, ncurr, nmatch);
1339 if (rc != SEPOL_OK) {
1340 return rc;
1341 }
1342 oprev = ocurr;
1343 ocurr = ocurr->next;
1344 ncurr = nmatch->next;
1345 continue;
1346 }
1347 /* Handle gap in new: old = (A B C) new = (A C) */
1348 omatch = __cil_ordered_find_match(ncurr, ocurr->next);
1349 if (omatch) {
1350 /* Nothing to insert, just skip */
1351 oprev = omatch;
1352 ocurr = omatch->next;
1353 ncurr = ncurr->next;
1354 continue;
1355 } else {
1356 return SEPOL_ERR;
1357 }
1358 }
1359 }
1360
1361 if (ncurr) {
1362 /* Add the rest of the items from the new list */
1363 rc = __cil_ordered_list_insert(old, old->tail, ncurr, NULL);
1364 if (rc != SEPOL_OK) {
1365 return rc;
1366 }
1367 }
1368
1369 return SEPOL_OK;
1370 }
1371
insert_unordered(struct cil_list * merged,struct cil_list * unordered)1372 static int insert_unordered(struct cil_list *merged, struct cil_list *unordered)
1373 {
1374 struct cil_list_item *curr = NULL;
1375 struct cil_ordered_list *unordered_list = NULL;
1376 struct cil_list_item *item = NULL;
1377 struct cil_list_item *ret = NULL;
1378 int rc = SEPOL_ERR;
1379
1380 cil_list_for_each(curr, unordered) {
1381 unordered_list = curr->data;
1382
1383 cil_list_for_each(item, unordered_list->list) {
1384 if (cil_list_contains(merged, item->data)) {
1385 /* item was declared in an ordered statement, which supercedes
1386 * all unordered statements */
1387 if (item->flavor == CIL_CLASS) {
1388 cil_log(CIL_WARN, "Ignoring '%s' as it has already been declared in classorder.\n", ((struct cil_class*)(item->data))->datum.name);
1389 }
1390 continue;
1391 }
1392
1393 ret = __cil_ordered_item_insert(merged, merged->tail, item);
1394 if (ret == NULL) {
1395 rc = SEPOL_ERR;
1396 goto exit;
1397 }
1398 }
1399 }
1400
1401 rc = SEPOL_OK;
1402
1403 exit:
1404 return rc;
1405 }
1406
__cil_ordered_lists_merge_all(struct cil_list ** ordered_lists,struct cil_list ** unordered_lists)1407 struct cil_list *__cil_ordered_lists_merge_all(struct cil_list **ordered_lists, struct cil_list **unordered_lists)
1408 {
1409 struct cil_list *composite = NULL;
1410 struct cil_list_item *curr = NULL;
1411 int changed = CIL_TRUE;
1412 int waiting = 1;
1413 int rc = SEPOL_ERR;
1414
1415 cil_list_init(&composite, CIL_LIST_ITEM);
1416
1417 while (waiting && changed == CIL_TRUE) {
1418 changed = CIL_FALSE;
1419 waiting = 0;
1420 cil_list_for_each(curr, *ordered_lists) {
1421 struct cil_ordered_list *ordered_list = curr->data;
1422 if (ordered_list->merged == CIL_FALSE) {
1423 rc = __cil_ordered_lists_merge(composite, ordered_list->list);
1424 if (rc != SEPOL_OK) {
1425 /* Can't merge yet */
1426 waiting++;
1427 } else {
1428 ordered_list->merged = CIL_TRUE;
1429 changed = CIL_TRUE;
1430 }
1431 }
1432 }
1433 if (waiting > 0 && changed == CIL_FALSE) {
1434 cil_list_for_each(curr, *ordered_lists) {
1435 struct cil_ordered_list *ordered_list = curr->data;
1436 if (ordered_list->merged == CIL_FALSE) {
1437 cil_tree_log(ordered_list->node, CIL_ERR, "Unable to merge ordered list");
1438 }
1439 }
1440 goto exit;
1441 }
1442 }
1443
1444 if (unordered_lists != NULL) {
1445 rc = insert_unordered(composite, *unordered_lists);
1446 if (rc != SEPOL_OK) {
1447 goto exit;
1448 }
1449 }
1450
1451 __cil_ordered_lists_destroy(ordered_lists);
1452 __cil_ordered_lists_destroy(unordered_lists);
1453
1454 return composite;
1455
1456 exit:
1457 __cil_ordered_lists_destroy(ordered_lists);
1458 __cil_ordered_lists_destroy(unordered_lists);
1459 cil_list_destroy(&composite, CIL_FALSE);
1460 return NULL;
1461 }
1462
cil_resolve_classorder(struct cil_tree_node * current,void * extra_args)1463 int cil_resolve_classorder(struct cil_tree_node *current, void *extra_args)
1464 {
1465 struct cil_args_resolve *args = extra_args;
1466 struct cil_list *classorder_list = args->classorder_lists;
1467 struct cil_list *unordered_classorder_list = args->unordered_classorder_lists;
1468 struct cil_classorder *classorder = current->data;
1469 struct cil_list *new = NULL;
1470 struct cil_list_item *curr = NULL;
1471 struct cil_symtab_datum *datum = NULL;
1472 struct cil_ordered_list *class_list = NULL;
1473 int rc = SEPOL_ERR;
1474 int unordered = CIL_FALSE;
1475
1476 cil_list_init(&new, CIL_CLASSORDER);
1477
1478 cil_list_for_each(curr, classorder->class_list_str) {
1479 if (curr->data == CIL_KEY_UNORDERED) {
1480 unordered = CIL_TRUE;
1481 continue;
1482 }
1483
1484 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum);
1485 if (rc != SEPOL_OK) {
1486 cil_log(CIL_ERR, "Failed to resolve class %s in classorder\n", (char *)curr->data);
1487 goto exit;
1488 }
1489 cil_list_append(new, CIL_CLASS, datum);
1490 }
1491
1492 __cil_ordered_list_init(&class_list);
1493 class_list->list = new;
1494 class_list->node = current;
1495 if (unordered) {
1496 cil_list_append(unordered_classorder_list, CIL_CLASSORDER, class_list);
1497 } else {
1498 cil_list_append(classorder_list, CIL_CLASSORDER, class_list);
1499 }
1500
1501 return SEPOL_OK;
1502
1503 exit:
1504 cil_list_destroy(&new, CIL_FALSE);
1505 return rc;
1506 }
1507
cil_resolve_sidorder(struct cil_tree_node * current,void * extra_args)1508 int cil_resolve_sidorder(struct cil_tree_node *current, void *extra_args)
1509 {
1510 struct cil_args_resolve *args = extra_args;
1511 struct cil_list *sidorder_list = args->sidorder_lists;
1512 struct cil_sidorder *sidorder = current->data;
1513 struct cil_list *new = NULL;
1514 struct cil_list_item *curr = NULL;
1515 struct cil_symtab_datum *datum = NULL;
1516 struct cil_ordered_list *ordered = NULL;
1517 int rc = SEPOL_ERR;
1518
1519 cil_list_init(&new, CIL_SIDORDER);
1520
1521 cil_list_for_each(curr, sidorder->sid_list_str) {
1522 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SIDS, extra_args, &datum);
1523 if (rc != SEPOL_OK) {
1524 cil_log(CIL_ERR, "Failed to resolve sid %s in sidorder\n", (char *)curr->data);
1525 goto exit;
1526 }
1527 cil_list_append(new, CIL_SID, datum);
1528 }
1529
1530 __cil_ordered_list_init(&ordered);
1531 ordered->list = new;
1532 ordered->node = current;
1533 cil_list_append(sidorder_list, CIL_SIDORDER, ordered);
1534
1535 return SEPOL_OK;
1536
1537 exit:
1538 return rc;
1539 }
1540
cil_set_cat_values(struct cil_list * ordered_cats,struct cil_db * db)1541 void cil_set_cat_values(struct cil_list *ordered_cats, struct cil_db *db)
1542 {
1543 struct cil_list_item *curr;
1544 int v = 0;
1545
1546 cil_list_for_each(curr, ordered_cats) {
1547 struct cil_cat *cat = curr->data;
1548 cat->value = v;
1549 v++;
1550 }
1551
1552 db->num_cats = v;
1553 }
1554
cil_resolve_catorder(struct cil_tree_node * current,void * extra_args)1555 int cil_resolve_catorder(struct cil_tree_node *current, void *extra_args)
1556 {
1557 struct cil_args_resolve *args = extra_args;
1558 struct cil_list *catorder_list = args->catorder_lists;
1559 struct cil_catorder *catorder = current->data;
1560 struct cil_list *new = NULL;
1561 struct cil_list_item *curr = NULL;
1562 struct cil_symtab_datum *cat_datum;
1563 struct cil_cat *cat = NULL;
1564 struct cil_ordered_list *ordered = NULL;
1565 int rc = SEPOL_ERR;
1566
1567 cil_list_init(&new, CIL_CATORDER);
1568
1569 cil_list_for_each(curr, catorder->cat_list_str) {
1570 struct cil_tree_node *node = NULL;
1571 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CATS, extra_args, &cat_datum);
1572 if (rc != SEPOL_OK) {
1573 cil_log(CIL_ERR, "Failed to resolve category %s in categoryorder\n", (char *)curr->data);
1574 goto exit;
1575 }
1576 node = cat_datum->nodes->head->data;
1577 if (node->flavor != CIL_CAT) {
1578 cil_log(CIL_ERR, "%s is not a category. Only categories are allowed in categoryorder statements\n", cat_datum->name);
1579 rc = SEPOL_ERR;
1580 goto exit;
1581 }
1582 cat = (struct cil_cat *)cat_datum;
1583 cil_list_append(new, CIL_CAT, cat);
1584 }
1585
1586 __cil_ordered_list_init(&ordered);
1587 ordered->list = new;
1588 ordered->node = current;
1589 cil_list_append(catorder_list, CIL_CATORDER, ordered);
1590
1591 return SEPOL_OK;
1592
1593 exit:
1594 return rc;
1595 }
1596
cil_resolve_sensitivityorder(struct cil_tree_node * current,void * extra_args)1597 int cil_resolve_sensitivityorder(struct cil_tree_node *current, void *extra_args)
1598 {
1599 struct cil_args_resolve *args = extra_args;
1600 struct cil_list *sensitivityorder_list = args->sensitivityorder_lists;
1601 struct cil_sensorder *sensorder = current->data;
1602 struct cil_list *new = NULL;
1603 struct cil_list_item *curr = NULL;
1604 struct cil_symtab_datum *datum = NULL;
1605 struct cil_ordered_list *ordered = NULL;
1606 int rc = SEPOL_ERR;
1607
1608 cil_list_init(&new, CIL_LIST_ITEM);
1609
1610 cil_list_for_each(curr, sensorder->sens_list_str) {
1611 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SENS, extra_args, &datum);
1612 if (rc != SEPOL_OK) {
1613 cil_log(CIL_ERR, "Failed to resolve sensitivty %s in sensitivityorder\n", (char *)curr->data);
1614 goto exit;
1615 }
1616 cil_list_append(new, CIL_SENS, datum);
1617 }
1618
1619 __cil_ordered_list_init(&ordered);
1620 ordered->list = new;
1621 ordered->node = current;
1622 cil_list_append(sensitivityorder_list, CIL_SENSITIVITYORDER, ordered);
1623
1624 return SEPOL_OK;
1625
1626 exit:
1627 return rc;
1628 }
1629
cil_resolve_cats(struct cil_tree_node * current,struct cil_cats * cats,void * extra_args)1630 int cil_resolve_cats(struct cil_tree_node *current, struct cil_cats *cats, void *extra_args)
1631 {
1632 int rc = SEPOL_ERR;
1633
1634 rc = cil_resolve_expr(CIL_CATSET, cats->str_expr, &cats->datum_expr, current, extra_args);
1635 if (rc != SEPOL_OK) {
1636 goto exit;
1637 }
1638
1639 return SEPOL_OK;
1640
1641 exit:
1642 return rc;
1643 }
1644
1645
cil_resolve_catset(struct cil_tree_node * current,struct cil_catset * catset,void * extra_args)1646 int cil_resolve_catset(struct cil_tree_node *current, struct cil_catset *catset, void *extra_args)
1647 {
1648 int rc = SEPOL_ERR;
1649
1650 rc = cil_resolve_cats(current, catset->cats, extra_args);
1651 if (rc != SEPOL_OK) {
1652 goto exit;
1653 }
1654
1655 rc = cil_verify_no_self_reference((struct cil_symtab_datum *)catset, catset->cats->datum_expr);
1656 if (rc != SEPOL_OK) {
1657 cil_list_destroy(&catset->cats->datum_expr, CIL_FALSE);
1658 goto exit;
1659 }
1660
1661 exit:
1662 return rc;
1663 }
1664
cil_resolve_senscat(struct cil_tree_node * current,void * extra_args)1665 int cil_resolve_senscat(struct cil_tree_node *current, void *extra_args)
1666 {
1667 int rc = SEPOL_ERR;
1668 struct cil_senscat *senscat = current->data;
1669 struct cil_symtab_datum *sens_datum;
1670 struct cil_sens *sens = NULL;
1671
1672 rc = cil_resolve_name(current, (char*)senscat->sens_str, CIL_SYM_SENS, extra_args, &sens_datum);
1673 if (rc != SEPOL_OK) {
1674 cil_log(CIL_ERR, "Failed to find sensitivity\n");
1675 goto exit;
1676 }
1677
1678 rc = cil_resolve_cats(current, senscat->cats, extra_args);
1679 if (rc != SEPOL_OK) {
1680 goto exit;
1681 }
1682
1683 sens = (struct cil_sens *)sens_datum;
1684
1685 if (sens->cats_list == NULL ) {
1686 cil_list_init(&sens->cats_list, CIL_CAT);
1687 }
1688
1689 cil_list_append(sens->cats_list, CIL_CAT, senscat->cats);
1690
1691 return SEPOL_OK;
1692
1693 exit:
1694 return rc;
1695 }
1696
cil_resolve_level(struct cil_tree_node * current,struct cil_level * level,void * extra_args)1697 int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, void *extra_args)
1698 {
1699 struct cil_symtab_datum *sens_datum = NULL;
1700 int rc = SEPOL_ERR;
1701
1702 rc = cil_resolve_name(current, (char*)level->sens_str, CIL_SYM_SENS, extra_args, &sens_datum);
1703 if (rc != SEPOL_OK) {
1704 cil_log(CIL_ERR, "Failed to find sensitivity\n");
1705 goto exit;
1706 }
1707
1708 level->sens = (struct cil_sens *)sens_datum;
1709
1710 if (level->cats != NULL) {
1711 rc = cil_resolve_cats(current, level->cats, extra_args);
1712 if (rc != SEPOL_OK) {
1713 goto exit;
1714 }
1715 }
1716
1717 return SEPOL_OK;
1718
1719 exit:
1720 return rc;
1721 }
1722
cil_resolve_levelrange(struct cil_tree_node * current,struct cil_levelrange * lvlrange,void * extra_args)1723 int cil_resolve_levelrange(struct cil_tree_node *current, struct cil_levelrange *lvlrange, void *extra_args)
1724 {
1725 struct cil_symtab_datum *low_datum = NULL;
1726 struct cil_symtab_datum *high_datum = NULL;
1727 int rc = SEPOL_ERR;
1728
1729 if (lvlrange->low_str != NULL) {
1730 rc = cil_resolve_name(current, lvlrange->low_str, CIL_SYM_LEVELS, extra_args, &low_datum);
1731 if (rc != SEPOL_OK) {
1732 goto exit;
1733 }
1734 lvlrange->low = (struct cil_level*)low_datum;
1735
1736 /* This could still be an anonymous level even if low_str is set, if low_str is a param_str */
1737 if (lvlrange->low->datum.name == NULL) {
1738 rc = cil_resolve_level(current, lvlrange->low, extra_args);
1739 if (rc != SEPOL_OK) {
1740 goto exit;
1741 }
1742 }
1743 } else if (lvlrange->low != NULL) {
1744 rc = cil_resolve_level(current, lvlrange->low, extra_args);
1745 if (rc != SEPOL_OK) {
1746 goto exit;
1747 }
1748 }
1749
1750 if (lvlrange->high_str != NULL) {
1751 rc = cil_resolve_name(current, lvlrange->high_str, CIL_SYM_LEVELS, extra_args, &high_datum);
1752 if (rc != SEPOL_OK) {
1753 goto exit;
1754 }
1755 lvlrange->high = (struct cil_level*)high_datum;
1756
1757 /* This could still be an anonymous level even if high_str is set, if high_str is a param_str */
1758 if (lvlrange->high->datum.name == NULL) {
1759 rc = cil_resolve_level(current, lvlrange->high, extra_args);
1760 if (rc != SEPOL_OK) {
1761 goto exit;
1762 }
1763 }
1764 } else if (lvlrange->high != NULL) {
1765 rc = cil_resolve_level(current, lvlrange->high, extra_args);
1766 if (rc != SEPOL_OK) {
1767 goto exit;
1768 }
1769 }
1770
1771 return SEPOL_OK;
1772
1773 exit:
1774 return rc;
1775 }
1776
cil_resolve_constrain(struct cil_tree_node * current,void * extra_args)1777 int cil_resolve_constrain(struct cil_tree_node *current, void *extra_args)
1778 {
1779 struct cil_constrain *cons = current->data;
1780 int rc = SEPOL_ERR;
1781
1782 rc = cil_resolve_classperms_list(current, cons->classperms, extra_args);
1783 if (rc != SEPOL_OK) {
1784 goto exit;
1785 }
1786
1787 rc = cil_resolve_expr(CIL_CONSTRAIN, cons->str_expr, &cons->datum_expr, current, extra_args);
1788 if (rc != SEPOL_OK) {
1789 goto exit;
1790 }
1791
1792 return SEPOL_OK;
1793
1794 exit:
1795 return rc;
1796 }
1797
cil_resolve_validatetrans(struct cil_tree_node * current,void * extra_args)1798 int cil_resolve_validatetrans(struct cil_tree_node *current, void *extra_args)
1799 {
1800 struct cil_validatetrans *validtrans = current->data;
1801 struct cil_args_resolve *args = extra_args;
1802 struct cil_symtab_datum *class_datum = NULL;
1803 int rc = SEPOL_ERR;
1804
1805 rc = cil_resolve_name(current, validtrans->class_str, CIL_SYM_CLASSES, args, &class_datum);
1806 if (rc != SEPOL_OK) {
1807 goto exit;
1808 }
1809 validtrans->class = (struct cil_class*)class_datum;
1810
1811 rc = cil_resolve_expr(CIL_VALIDATETRANS, validtrans->str_expr, &validtrans->datum_expr, current, extra_args);
1812 if (rc != SEPOL_OK) {
1813 goto exit;
1814 }
1815
1816 return SEPOL_OK;
1817
1818 exit:
1819 return rc;
1820 }
1821
cil_resolve_context(struct cil_tree_node * current,struct cil_context * context,void * extra_args)1822 int cil_resolve_context(struct cil_tree_node *current, struct cil_context *context, void *extra_args)
1823 {
1824 struct cil_symtab_datum *user_datum = NULL;
1825 struct cil_symtab_datum *role_datum = NULL;
1826 struct cil_symtab_datum *type_datum = NULL;
1827 struct cil_tree_node *node = NULL;
1828 struct cil_symtab_datum *lvlrange_datum = NULL;
1829
1830 int rc = SEPOL_ERR;
1831
1832 rc = cil_resolve_name(current, context->user_str, CIL_SYM_USERS, extra_args, &user_datum);
1833 if (rc != SEPOL_OK) {
1834 goto exit;
1835 }
1836
1837 node = user_datum->nodes->head->data;
1838
1839 if (node->flavor != CIL_USER) {
1840 cil_log(CIL_ERR, "Context user must be a user: %s\n", user_datum->fqn);
1841 rc = SEPOL_ERR;
1842 goto exit;
1843 }
1844
1845 context->user = (struct cil_user*)user_datum;
1846
1847 rc = cil_resolve_name(current, context->role_str, CIL_SYM_ROLES, extra_args, &role_datum);
1848 if (rc != SEPOL_OK) {
1849 goto exit;
1850 }
1851
1852 node = role_datum->nodes->head->data;
1853 if (node->flavor != CIL_ROLE) {
1854 rc = SEPOL_ERR;
1855 cil_log(CIL_ERR, "Context role not a role: %s\n", role_datum->fqn);
1856 goto exit;
1857 }
1858
1859 context->role = (struct cil_role*)role_datum;
1860
1861 rc = cil_resolve_name(current, context->type_str, CIL_SYM_TYPES, extra_args, &type_datum);
1862 if (rc != SEPOL_OK) {
1863 goto exit;
1864 }
1865
1866 node = type_datum->nodes->head->data;
1867
1868 if (node->flavor != CIL_TYPE && node->flavor != CIL_TYPEALIAS) {
1869 rc = SEPOL_ERR;
1870 cil_log(CIL_ERR, "Type not a type or type alias\n");
1871 goto exit;
1872 }
1873 context->type = type_datum;
1874
1875 if (context->range_str != NULL) {
1876 rc = cil_resolve_name(current, context->range_str, CIL_SYM_LEVELRANGES, extra_args, &lvlrange_datum);
1877 if (rc != SEPOL_OK) {
1878 goto exit;
1879 }
1880 context->range = (struct cil_levelrange*)lvlrange_datum;
1881
1882 /* This could still be an anonymous levelrange even if levelrange_str is set, if levelrange_str is a param_str*/
1883 if (context->range->datum.name == NULL) {
1884 rc = cil_resolve_levelrange(current, context->range, extra_args);
1885 if (rc != SEPOL_OK) {
1886 goto exit;
1887 }
1888 }
1889 } else if (context->range != NULL) {
1890 rc = cil_resolve_levelrange(current, context->range, extra_args);
1891 if (rc != SEPOL_OK) {
1892 goto exit;
1893 }
1894 }
1895
1896 return SEPOL_OK;
1897
1898 exit:
1899 return rc;
1900 }
1901
cil_resolve_filecon(struct cil_tree_node * current,void * extra_args)1902 int cil_resolve_filecon(struct cil_tree_node *current, void *extra_args)
1903 {
1904 struct cil_filecon *filecon = current->data;
1905 struct cil_symtab_datum *context_datum = NULL;
1906 int rc = SEPOL_ERR;
1907
1908 if (filecon->context_str != NULL) {
1909 rc = cil_resolve_name(current, filecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
1910 if (rc != SEPOL_OK) {
1911 return rc;
1912 }
1913 filecon->context = (struct cil_context*)context_datum;
1914 } else if (filecon->context != NULL) {
1915 rc = cil_resolve_context(current, filecon->context, extra_args);
1916 if (rc != SEPOL_OK) {
1917 return rc;
1918 }
1919 }
1920
1921 return SEPOL_OK;
1922 }
1923
cil_resolve_ibpkeycon(struct cil_tree_node * current,void * extra_args)1924 int cil_resolve_ibpkeycon(struct cil_tree_node *current, void *extra_args)
1925 {
1926 struct cil_ibpkeycon *ibpkeycon = current->data;
1927 struct cil_symtab_datum *context_datum = NULL;
1928 int rc = SEPOL_ERR;
1929
1930 if (ibpkeycon->context_str) {
1931 rc = cil_resolve_name(current, ibpkeycon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
1932 if (rc != SEPOL_OK)
1933 goto exit;
1934
1935 ibpkeycon->context = (struct cil_context *)context_datum;
1936 } else {
1937 rc = cil_resolve_context(current, ibpkeycon->context, extra_args);
1938 if (rc != SEPOL_OK)
1939 goto exit;
1940 }
1941
1942 return SEPOL_OK;
1943
1944 exit:
1945 return rc;
1946 }
1947
cil_resolve_portcon(struct cil_tree_node * current,void * extra_args)1948 int cil_resolve_portcon(struct cil_tree_node *current, void *extra_args)
1949 {
1950 struct cil_portcon *portcon = current->data;
1951 struct cil_symtab_datum *context_datum = NULL;
1952 int rc = SEPOL_ERR;
1953
1954 if (portcon->context_str != NULL) {
1955 rc = cil_resolve_name(current, portcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
1956 if (rc != SEPOL_OK) {
1957 goto exit;
1958 }
1959 portcon->context = (struct cil_context*)context_datum;
1960 } else {
1961 rc = cil_resolve_context(current, portcon->context, extra_args);
1962 if (rc != SEPOL_OK) {
1963 goto exit;
1964 }
1965 }
1966
1967 return SEPOL_OK;
1968
1969 exit:
1970 return rc;
1971 }
1972
cil_resolve_genfscon(struct cil_tree_node * current,void * extra_args)1973 int cil_resolve_genfscon(struct cil_tree_node *current, void *extra_args)
1974 {
1975 struct cil_genfscon *genfscon = current->data;
1976 struct cil_symtab_datum *context_datum = NULL;
1977 int rc = SEPOL_ERR;
1978
1979 if (genfscon->context_str != NULL) {
1980 rc = cil_resolve_name(current, genfscon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
1981 if (rc != SEPOL_OK) {
1982 goto exit;
1983 }
1984 genfscon->context = (struct cil_context*)context_datum;
1985 } else {
1986 rc = cil_resolve_context(current, genfscon->context, extra_args);
1987 if (rc != SEPOL_OK) {
1988 goto exit;
1989 }
1990 }
1991
1992 return SEPOL_OK;
1993
1994 exit:
1995 return rc;
1996 }
1997
cil_resolve_nodecon(struct cil_tree_node * current,void * extra_args)1998 int cil_resolve_nodecon(struct cil_tree_node *current, void *extra_args)
1999 {
2000 struct cil_nodecon *nodecon = current->data;
2001 struct cil_symtab_datum *addr_datum = NULL;
2002 struct cil_symtab_datum *mask_datum = NULL;
2003 struct cil_symtab_datum *context_datum = NULL;
2004 int rc = SEPOL_ERR;
2005
2006 if (nodecon->addr_str != NULL) {
2007 rc = cil_resolve_name(current, nodecon->addr_str, CIL_SYM_IPADDRS, extra_args, &addr_datum);
2008 if (rc != SEPOL_OK) {
2009 goto exit;
2010 }
2011 nodecon->addr = (struct cil_ipaddr*)addr_datum;
2012 }
2013
2014 if (nodecon->mask_str != NULL) {
2015 rc = cil_resolve_name(current, nodecon->mask_str, CIL_SYM_IPADDRS, extra_args, &mask_datum);
2016 if (rc != SEPOL_OK) {
2017 goto exit;
2018 }
2019 nodecon->mask = (struct cil_ipaddr*)mask_datum;
2020 }
2021
2022 if (nodecon->context_str != NULL) {
2023 rc = cil_resolve_name(current, nodecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
2024 if (rc != SEPOL_OK) {
2025 goto exit;
2026 }
2027 nodecon->context = (struct cil_context*)context_datum;
2028 } else {
2029 rc = cil_resolve_context(current, nodecon->context, extra_args);
2030 if (rc != SEPOL_OK) {
2031 goto exit;
2032 }
2033 }
2034
2035 if (nodecon->addr->family != nodecon->mask->family) {
2036 cil_log(CIL_ERR, "Nodecon ip address not in the same family\n");
2037 rc = SEPOL_ERR;
2038 goto exit;
2039 }
2040
2041
2042 return SEPOL_OK;
2043
2044 exit:
2045 return rc;
2046 }
2047
cil_resolve_netifcon(struct cil_tree_node * current,void * extra_args)2048 int cil_resolve_netifcon(struct cil_tree_node *current, void *extra_args)
2049 {
2050 struct cil_netifcon *netifcon = current->data;
2051 struct cil_symtab_datum *ifcon_datum = NULL;
2052 struct cil_symtab_datum *packcon_datum = NULL;
2053
2054 int rc = SEPOL_ERR;
2055
2056 if (netifcon->if_context_str != NULL) {
2057 rc = cil_resolve_name(current, netifcon->if_context_str, CIL_SYM_CONTEXTS, extra_args, &ifcon_datum);
2058 if (rc != SEPOL_OK) {
2059 goto exit;
2060 }
2061 netifcon->if_context = (struct cil_context*)ifcon_datum;
2062 } else {
2063 rc = cil_resolve_context(current, netifcon->if_context, extra_args);
2064 if (rc != SEPOL_OK) {
2065 goto exit;
2066 }
2067 }
2068
2069 if (netifcon->packet_context_str != NULL) {
2070 rc = cil_resolve_name(current, netifcon->packet_context_str, CIL_SYM_CONTEXTS, extra_args, &packcon_datum);
2071 if (rc != SEPOL_OK) {
2072 goto exit;
2073 }
2074 netifcon->packet_context = (struct cil_context*)packcon_datum;
2075 } else {
2076 rc = cil_resolve_context(current, netifcon->packet_context, extra_args);
2077 if (rc != SEPOL_OK) {
2078 goto exit;
2079 }
2080 }
2081 return SEPOL_OK;
2082
2083 exit:
2084 return rc;
2085 }
2086
cil_resolve_ibendportcon(struct cil_tree_node * current,void * extra_args)2087 int cil_resolve_ibendportcon(struct cil_tree_node *current, void *extra_args)
2088 {
2089 struct cil_ibendportcon *ibendportcon = current->data;
2090 struct cil_symtab_datum *con_datum = NULL;
2091
2092 int rc = SEPOL_ERR;
2093
2094 if (ibendportcon->context_str) {
2095 rc = cil_resolve_name(current, ibendportcon->context_str, CIL_SYM_CONTEXTS, extra_args, &con_datum);
2096 if (rc != SEPOL_OK)
2097 goto exit;
2098
2099 ibendportcon->context = (struct cil_context *)con_datum;
2100 } else {
2101 rc = cil_resolve_context(current, ibendportcon->context, extra_args);
2102 if (rc != SEPOL_OK)
2103 goto exit;
2104 }
2105
2106 return SEPOL_OK;
2107
2108 exit:
2109 return rc;
2110 }
2111
cil_resolve_pirqcon(struct cil_tree_node * current,void * extra_args)2112 int cil_resolve_pirqcon(struct cil_tree_node *current, void *extra_args)
2113 {
2114 struct cil_pirqcon *pirqcon = current->data;
2115 struct cil_symtab_datum *context_datum = NULL;
2116 int rc = SEPOL_ERR;
2117
2118 if (pirqcon->context_str != NULL) {
2119 rc = cil_resolve_name(current, pirqcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
2120 if (rc != SEPOL_OK) {
2121 goto exit;
2122 }
2123 pirqcon->context = (struct cil_context*)context_datum;
2124 } else {
2125 rc = cil_resolve_context(current, pirqcon->context, extra_args);
2126 if (rc != SEPOL_OK) {
2127 goto exit;
2128 }
2129 }
2130
2131 return SEPOL_OK;
2132
2133 exit:
2134 return rc;
2135 }
2136
cil_resolve_iomemcon(struct cil_tree_node * current,void * extra_args)2137 int cil_resolve_iomemcon(struct cil_tree_node *current, void *extra_args)
2138 {
2139 struct cil_iomemcon *iomemcon = current->data;
2140 struct cil_symtab_datum *context_datum = NULL;
2141 int rc = SEPOL_ERR;
2142
2143 if (iomemcon->context_str != NULL) {
2144 rc = cil_resolve_name(current, iomemcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
2145 if (rc != SEPOL_OK) {
2146 goto exit;
2147 }
2148 iomemcon->context = (struct cil_context*)context_datum;
2149 } else {
2150 rc = cil_resolve_context(current, iomemcon->context, extra_args);
2151 if (rc != SEPOL_OK) {
2152 goto exit;
2153 }
2154 }
2155
2156 return SEPOL_OK;
2157
2158 exit:
2159 return rc;
2160 }
2161
cil_resolve_ioportcon(struct cil_tree_node * current,void * extra_args)2162 int cil_resolve_ioportcon(struct cil_tree_node *current, void *extra_args)
2163 {
2164 struct cil_ioportcon *ioportcon = current->data;
2165 struct cil_symtab_datum *context_datum = NULL;
2166 int rc = SEPOL_ERR;
2167
2168 if (ioportcon->context_str != NULL) {
2169 rc = cil_resolve_name(current, ioportcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
2170 if (rc != SEPOL_OK) {
2171 goto exit;
2172 }
2173 ioportcon->context = (struct cil_context*)context_datum;
2174 } else {
2175 rc = cil_resolve_context(current, ioportcon->context, extra_args);
2176 if (rc != SEPOL_OK) {
2177 goto exit;
2178 }
2179 }
2180
2181 return SEPOL_OK;
2182
2183 exit:
2184 return rc;
2185 }
2186
cil_resolve_pcidevicecon(struct cil_tree_node * current,void * extra_args)2187 int cil_resolve_pcidevicecon(struct cil_tree_node *current, void *extra_args)
2188 {
2189 struct cil_pcidevicecon *pcidevicecon = current->data;
2190 struct cil_symtab_datum *context_datum = NULL;
2191 int rc = SEPOL_ERR;
2192
2193 if (pcidevicecon->context_str != NULL) {
2194 rc = cil_resolve_name(current, pcidevicecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
2195 if (rc != SEPOL_OK) {
2196 goto exit;
2197 }
2198 pcidevicecon->context = (struct cil_context*)context_datum;
2199 } else {
2200 rc = cil_resolve_context(current, pcidevicecon->context, extra_args);
2201 if (rc != SEPOL_OK) {
2202 goto exit;
2203 }
2204 }
2205
2206 return SEPOL_OK;
2207
2208 exit:
2209 return rc;
2210 }
2211
cil_resolve_devicetreecon(struct cil_tree_node * current,void * extra_args)2212 int cil_resolve_devicetreecon(struct cil_tree_node *current, void *extra_args)
2213 {
2214 struct cil_devicetreecon *devicetreecon = current->data;
2215 struct cil_symtab_datum *context_datum = NULL;
2216 int rc = SEPOL_ERR;
2217
2218 if (devicetreecon->context_str != NULL) {
2219 rc = cil_resolve_name(current, devicetreecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
2220 if (rc != SEPOL_OK) {
2221 goto exit;
2222 }
2223 devicetreecon->context = (struct cil_context*)context_datum;
2224 } else {
2225 rc = cil_resolve_context(current, devicetreecon->context, extra_args);
2226 if (rc != SEPOL_OK) {
2227 goto exit;
2228 }
2229 }
2230
2231 return SEPOL_OK;
2232
2233 exit:
2234 return rc;
2235 }
2236
cil_resolve_fsuse(struct cil_tree_node * current,void * extra_args)2237 int cil_resolve_fsuse(struct cil_tree_node *current, void *extra_args)
2238 {
2239 struct cil_fsuse *fsuse = current->data;
2240 struct cil_symtab_datum *context_datum = NULL;
2241 int rc = SEPOL_ERR;
2242
2243 if (fsuse->context_str != NULL) {
2244 rc = cil_resolve_name(current, fsuse->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
2245 if (rc != SEPOL_OK) {
2246 goto exit;
2247 }
2248 fsuse->context = (struct cil_context*)context_datum;
2249 } else {
2250 rc = cil_resolve_context(current, fsuse->context, extra_args);
2251 if (rc != SEPOL_OK) {
2252 goto exit;
2253 }
2254 }
2255
2256 return SEPOL_OK;
2257
2258 exit:
2259 return rc;
2260 }
2261
cil_resolve_sidcontext(struct cil_tree_node * current,void * extra_args)2262 int cil_resolve_sidcontext(struct cil_tree_node *current, void *extra_args)
2263 {
2264 struct cil_sidcontext *sidcon = current->data;
2265 struct cil_symtab_datum *sid_datum = NULL;
2266 struct cil_symtab_datum *context_datum = NULL;
2267 struct cil_sid *sid = NULL;
2268
2269 int rc = SEPOL_ERR;
2270
2271 rc = cil_resolve_name(current, sidcon->sid_str, CIL_SYM_SIDS, extra_args, &sid_datum);
2272 if (rc != SEPOL_OK) {
2273 goto exit;
2274 }
2275 sid = (struct cil_sid*)sid_datum;
2276
2277 if (sidcon->context_str != NULL) {
2278 rc = cil_resolve_name(current, sidcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
2279 if (rc != SEPOL_OK) {
2280 goto exit;
2281 }
2282 sidcon->context = (struct cil_context*)context_datum;
2283 } else if (sidcon->context != NULL) {
2284 rc = cil_resolve_context(current, sidcon->context, extra_args);
2285 if (rc != SEPOL_OK) {
2286 goto exit;
2287 }
2288 }
2289
2290 if (sid->context != NULL) {
2291 cil_log(CIL_ERR, "sid's cannot be associated with more than one context\n");
2292 rc = SEPOL_ERR;
2293 goto exit;
2294 }
2295
2296 sid->context = sidcon->context;
2297
2298 return SEPOL_OK;
2299
2300 exit:
2301 return rc;
2302 }
2303
cil_resolve_blockinherit_link(struct cil_tree_node * current,void * extra_args)2304 int cil_resolve_blockinherit_link(struct cil_tree_node *current, void *extra_args)
2305 {
2306 struct cil_blockinherit *inherit = current->data;
2307 struct cil_symtab_datum *block_datum = NULL;
2308 struct cil_tree_node *node = NULL;
2309 int rc = SEPOL_ERR;
2310
2311 rc = cil_resolve_name(current, inherit->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum);
2312 if (rc != SEPOL_OK) {
2313 goto exit;
2314 }
2315
2316 node = block_datum->nodes->head->data;
2317
2318 if (node->flavor != CIL_BLOCK) {
2319 cil_log(CIL_ERR, "%s is not a block\n", cil_node_to_string(node));
2320 rc = SEPOL_ERR;
2321 goto exit;
2322 }
2323
2324 inherit->block = (struct cil_block *)block_datum;
2325
2326 if (inherit->block->bi_nodes == NULL) {
2327 cil_list_init(&inherit->block->bi_nodes, CIL_NODE);
2328 }
2329 cil_list_append(inherit->block->bi_nodes, CIL_NODE, current);
2330
2331 return SEPOL_OK;
2332
2333 exit:
2334 return rc;
2335 }
2336
cil_print_recursive_blockinherit(struct cil_tree_node * bi_node,struct cil_tree_node * terminating_node)2337 void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_tree_node *terminating_node)
2338 {
2339 struct cil_list *trace = NULL;
2340 struct cil_list_item *item = NULL;
2341 struct cil_tree_node *curr = NULL;
2342
2343 cil_list_init(&trace, CIL_NODE);
2344
2345 for (curr = bi_node; curr != terminating_node; curr = curr->parent) {
2346 if (curr->flavor == CIL_BLOCK) {
2347 cil_list_prepend(trace, CIL_NODE, curr);
2348 } else {
2349 if (curr != bi_node) {
2350 cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_blockinherit *)curr->data)->block));
2351 }
2352 cil_list_prepend(trace, CIL_NODE, curr);
2353 }
2354 }
2355 cil_list_prepend(trace, CIL_NODE, terminating_node);
2356
2357 cil_list_for_each(item, trace) {
2358 curr = item->data;
2359 if (curr->flavor == CIL_BLOCK) {
2360 cil_tree_log(curr, CIL_ERR, "block %s", DATUM(curr->data)->name);
2361 } else {
2362 cil_tree_log(curr, CIL_ERR, "blockinherit %s", ((struct cil_blockinherit *)curr->data)->block_str);
2363 }
2364 }
2365
2366 cil_list_destroy(&trace, CIL_FALSE);
2367 }
2368
cil_check_recursive_blockinherit(struct cil_tree_node * bi_node)2369 int cil_check_recursive_blockinherit(struct cil_tree_node *bi_node)
2370 {
2371 struct cil_tree_node *curr = NULL;
2372 struct cil_blockinherit *bi = NULL;
2373 struct cil_block *block = NULL;
2374 int rc = SEPOL_ERR;
2375
2376 bi = bi_node->data;
2377
2378 for (curr = bi_node->parent; curr != NULL; curr = curr->parent) {
2379 if (curr->flavor != CIL_BLOCK) {
2380 continue;
2381 }
2382
2383 block = curr->data;
2384
2385 if (block != bi->block) {
2386 continue;
2387 }
2388
2389 cil_log(CIL_ERR, "Recursive blockinherit found:\n");
2390 cil_print_recursive_blockinherit(bi_node, curr);
2391
2392 rc = SEPOL_ERR;
2393 goto exit;
2394 }
2395
2396 rc = SEPOL_OK;
2397
2398 exit:
2399 return rc;
2400 }
2401
cil_resolve_blockinherit_copy(struct cil_tree_node * current,void * extra_args)2402 int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_args)
2403 {
2404 struct cil_block *block = current->data;
2405 struct cil_args_resolve *args = extra_args;
2406 struct cil_db *db = NULL;
2407 struct cil_list_item *item = NULL;
2408 int rc = SEPOL_ERR;
2409
2410 // This block is not inherited
2411 if (block->bi_nodes == NULL) {
2412 rc = SEPOL_OK;
2413 goto exit;
2414 }
2415
2416 db = args->db;
2417
2418 // Make sure this is the original block and not a merged block from a blockinherit
2419 if (current != block->datum.nodes->head->data) {
2420 rc = SEPOL_OK;
2421 goto exit;
2422 }
2423
2424 cil_list_for_each(item, block->bi_nodes) {
2425 rc = cil_check_recursive_blockinherit(item->data);
2426 if (rc != SEPOL_OK) {
2427 goto exit;
2428 }
2429
2430 rc = cil_copy_ast(db, current, item->data);
2431 if (rc != SEPOL_OK) {
2432 cil_log(CIL_ERR, "Failed to copy block contents into blockinherit\n");
2433 goto exit;
2434 }
2435 }
2436
2437 return SEPOL_OK;
2438
2439 exit:
2440 return rc;
2441 }
2442
cil_resolve_blockabstract(struct cil_tree_node * current,void * extra_args)2443 int cil_resolve_blockabstract(struct cil_tree_node *current, void *extra_args)
2444 {
2445 struct cil_blockabstract *abstract = current->data;
2446 struct cil_symtab_datum *block_datum = NULL;
2447 struct cil_tree_node *block_node = NULL;
2448 int rc = SEPOL_ERR;
2449
2450 rc = cil_resolve_name(current, abstract->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum);
2451 if (rc != SEPOL_OK) {
2452 goto exit;
2453 }
2454
2455 block_node = block_datum->nodes->head->data;
2456 if (block_node->flavor != CIL_BLOCK) {
2457 cil_log(CIL_ERR, "Failed to resolve blockabstract to a block, rc: %d\n", rc);
2458 goto exit;
2459 }
2460
2461 ((struct cil_block*)block_datum)->is_abstract = CIL_TRUE;
2462
2463 return SEPOL_OK;
2464
2465 exit:
2466 return rc;
2467 }
2468
cil_resolve_in(struct cil_tree_node * current,void * extra_args)2469 int cil_resolve_in(struct cil_tree_node *current, void *extra_args)
2470 {
2471 struct cil_in *in = current->data;
2472 struct cil_args_resolve *args = extra_args;
2473 struct cil_db *db = NULL;
2474 struct cil_symtab_datum *block_datum = NULL;
2475 struct cil_tree_node *block_node = NULL;
2476 int rc = SEPOL_ERR;
2477
2478 if (args != NULL) {
2479 db = args->db;
2480 }
2481
2482 rc = cil_resolve_name(current, in->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum);
2483 if (rc != SEPOL_OK) {
2484 goto exit;
2485 }
2486
2487 block_node = block_datum->nodes->head->data;
2488
2489 rc = cil_copy_ast(db, current, block_node);
2490 if (rc != SEPOL_OK) {
2491 printf("Failed to copy in, rc: %d\n", rc);
2492 goto exit;
2493 }
2494
2495 cil_tree_children_destroy(current);
2496 current->cl_head = NULL;
2497 current->cl_tail = NULL;
2498
2499 return SEPOL_OK;
2500
2501 exit:
2502 return rc;
2503 }
2504
cil_resolve_in_list(void * extra_args)2505 int cil_resolve_in_list(void *extra_args)
2506 {
2507 struct cil_args_resolve *args = extra_args;
2508 struct cil_list *ins = args->in_list;
2509 struct cil_list_item *curr = NULL;
2510 struct cil_tree_node *node = NULL;
2511 struct cil_tree_node *last_failed_node = NULL;
2512 struct cil_in *in = NULL;
2513 struct cil_symtab_datum *block_datum = NULL;
2514 int resolved = 0;
2515 int unresolved = 0;
2516 int rc = SEPOL_ERR;
2517
2518 do {
2519 resolved = 0;
2520 unresolved = 0;
2521
2522 cil_list_for_each(curr, ins) {
2523 if (curr->flavor != CIL_NODE) {
2524 continue;
2525 }
2526
2527 node = curr->data;
2528 in = node->data;
2529
2530 rc = cil_resolve_name(node, in->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum);
2531 if (rc != SEPOL_OK) {
2532 unresolved++;
2533 last_failed_node = node;
2534 } else {
2535 rc = cil_resolve_in(node, extra_args);
2536 if (rc != SEPOL_OK) {
2537 goto exit;
2538 }
2539
2540 resolved++;
2541 curr->data = NULL;
2542 curr->flavor = CIL_NONE;
2543 }
2544 }
2545
2546 if (unresolved > 0 && resolved == 0) {
2547 cil_tree_log(last_failed_node, CIL_ERR, "Failed to resolve in-statement");
2548 rc = SEPOL_ERR;
2549 goto exit;
2550 }
2551
2552 } while (unresolved > 0);
2553
2554 rc = SEPOL_OK;
2555
2556 exit:
2557 return rc;
2558 }
2559
2560
cil_resolve_bounds(struct cil_tree_node * current,void * extra_args,enum cil_flavor flavor,enum cil_flavor attr_flavor)2561 int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil_flavor flavor, enum cil_flavor attr_flavor)
2562 {
2563 int rc = SEPOL_ERR;
2564 struct cil_bounds *bounds = current->data;
2565 enum cil_sym_index index;
2566 struct cil_symtab_datum *parent_datum = NULL;
2567 struct cil_symtab_datum *child_datum = NULL;
2568
2569 rc = cil_flavor_to_symtab_index(flavor, &index);
2570 if (rc != SEPOL_OK) {
2571 goto exit;
2572 }
2573
2574 rc = cil_resolve_name(current, bounds->parent_str, index, extra_args, &parent_datum);
2575 if (rc != SEPOL_OK) {
2576 goto exit;
2577 }
2578 if (NODE(parent_datum)->flavor == attr_flavor) {
2579 cil_log(CIL_ERR, "Bounds parent %s is an attribute\n", bounds->parent_str);
2580 rc = SEPOL_ERR;
2581 goto exit;
2582 }
2583
2584
2585 rc = cil_resolve_name(current, bounds->child_str, index, extra_args, &child_datum);
2586 if (rc != SEPOL_OK) {
2587 goto exit;
2588 }
2589 if (NODE(child_datum)->flavor == attr_flavor) {
2590 cil_log(CIL_ERR, "Bounds child %s is an attribute\n", bounds->child_str);
2591 rc = SEPOL_ERR;
2592 goto exit;
2593 }
2594
2595 switch (flavor) {
2596 case CIL_USER: {
2597 struct cil_user *user = (struct cil_user *)child_datum;
2598
2599 if (user->bounds != NULL) {
2600 cil_tree_log(NODE(user->bounds), CIL_ERR, "User %s already bound by parent", bounds->child_str);
2601 rc = SEPOL_ERR;
2602 goto exit;
2603 }
2604
2605 user->bounds = (struct cil_user *)parent_datum;
2606 break;
2607 }
2608 case CIL_ROLE: {
2609 struct cil_role *role = (struct cil_role *)child_datum;
2610
2611 if (role->bounds != NULL) {
2612 cil_tree_log(NODE(role->bounds), CIL_ERR, "Role %s already bound by parent", bounds->child_str);
2613 rc = SEPOL_ERR;
2614 goto exit;
2615 }
2616
2617 role->bounds = (struct cil_role *)parent_datum;
2618 break;
2619 }
2620 case CIL_TYPE: {
2621 struct cil_type *type = (struct cil_type *)child_datum;
2622
2623 if (type->bounds != NULL) {
2624 cil_tree_log(NODE(type->bounds), CIL_ERR, "Type %s already bound by parent", bounds->child_str);
2625 rc = SEPOL_ERR;
2626 goto exit;
2627 }
2628
2629 type->bounds = (struct cil_type *)parent_datum;
2630 break;
2631 }
2632 default:
2633 break;
2634 }
2635
2636 return SEPOL_OK;
2637
2638 exit:
2639 cil_tree_log(current, CIL_ERR, "Bad bounds statement");
2640 return rc;
2641 }
2642
cil_resolve_default(struct cil_tree_node * current,void * extra_args)2643 int cil_resolve_default(struct cil_tree_node *current, void *extra_args)
2644 {
2645 int rc = SEPOL_ERR;
2646 struct cil_default *def = current->data;
2647 struct cil_list_item *curr;
2648 struct cil_symtab_datum *datum;
2649
2650 cil_list_init(&def->class_datums, def->flavor);
2651
2652 cil_list_for_each(curr, def->class_strs) {
2653 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum);
2654 if (rc != SEPOL_OK) {
2655 goto exit;
2656 }
2657 cil_list_append(def->class_datums, CIL_CLASS, datum);
2658 }
2659
2660 return SEPOL_OK;
2661
2662 exit:
2663 return rc;
2664 }
2665
cil_resolve_defaultrange(struct cil_tree_node * current,void * extra_args)2666 int cil_resolve_defaultrange(struct cil_tree_node *current, void *extra_args)
2667 {
2668 int rc = SEPOL_ERR;
2669 struct cil_defaultrange *def = current->data;
2670 struct cil_list_item *curr;
2671 struct cil_symtab_datum *datum;
2672
2673 cil_list_init(&def->class_datums, CIL_DEFAULTRANGE);
2674
2675 cil_list_for_each(curr, def->class_strs) {
2676 rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum);
2677 if (rc != SEPOL_OK) {
2678 goto exit;
2679 }
2680 cil_list_append(def->class_datums, CIL_CLASS, datum);
2681 }
2682
2683 return SEPOL_OK;
2684
2685 exit:
2686 return rc;
2687 }
2688
cil_print_recursive_call(struct cil_tree_node * call_node,struct cil_tree_node * terminating_node)2689 void cil_print_recursive_call(struct cil_tree_node *call_node, struct cil_tree_node *terminating_node)
2690 {
2691 struct cil_list *trace = NULL;
2692 struct cil_list_item * item = NULL;
2693 struct cil_tree_node *curr = NULL;
2694
2695 cil_list_init(&trace, CIL_NODE);
2696
2697 for (curr = call_node; curr != terminating_node; curr = curr->parent) {
2698 if (curr->flavor == CIL_CALL) {
2699 if (curr != call_node) {
2700 cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_call *)curr->data)->macro));
2701 }
2702 cil_list_prepend(trace, CIL_NODE, curr);
2703 }
2704 }
2705
2706 if (terminating_node->flavor == CIL_MACRO) {
2707 cil_list_prepend(trace, CIL_NODE, terminating_node);
2708 } else {
2709 cil_list_prepend(trace, CIL_NODE, NODE(((struct cil_call *)terminating_node->data)->macro));
2710 }
2711
2712 cil_list_for_each(item, trace) {
2713 curr = item->data;
2714 if (curr->flavor == CIL_MACRO) {
2715 cil_tree_log(curr, CIL_ERR, "macro %s", DATUM(curr->data)->name);
2716 } else {
2717 cil_tree_log(curr, CIL_ERR, "call %s", ((struct cil_call *)curr->data)->macro_str);
2718 }
2719 }
2720
2721 cil_list_destroy(&trace, CIL_FALSE);
2722 }
2723
cil_check_recursive_call(struct cil_tree_node * call_node,struct cil_tree_node * macro_node)2724 int cil_check_recursive_call(struct cil_tree_node *call_node, struct cil_tree_node *macro_node)
2725 {
2726 struct cil_tree_node *curr = NULL;
2727 struct cil_call * call = NULL;
2728 int rc = SEPOL_ERR;
2729
2730 for (curr = call_node; curr != NULL; curr = curr->parent) {
2731 if (curr->flavor == CIL_CALL) {
2732 if (curr == call_node) {
2733 continue;
2734 }
2735
2736 call = curr->data;
2737 if (call->macro != macro_node->data) {
2738 continue;
2739 }
2740 } else if (curr->flavor == CIL_MACRO) {
2741 if (curr != macro_node) {
2742 rc = SEPOL_OK;
2743 goto exit;
2744 }
2745 } else {
2746 continue;
2747 }
2748
2749 cil_log(CIL_ERR, "Recursive macro call found:\n");
2750 cil_print_recursive_call(call_node, curr);
2751
2752 rc = SEPOL_ERR;
2753 goto exit;
2754 }
2755
2756 rc = SEPOL_OK;
2757 exit:
2758 return rc;
2759 }
2760
cil_resolve_call1(struct cil_tree_node * current,void * extra_args)2761 int cil_resolve_call1(struct cil_tree_node *current, void *extra_args)
2762 {
2763 struct cil_call *new_call = current->data;
2764 struct cil_args_resolve *args = extra_args;
2765 struct cil_db *db = NULL;
2766 struct cil_tree_node *macro_node = NULL;
2767 struct cil_symtab_datum *macro_datum = NULL;
2768 int rc = SEPOL_ERR;
2769
2770 if (args != NULL) {
2771 db = args->db;
2772 }
2773
2774 rc = cil_resolve_name(current, new_call->macro_str, CIL_SYM_BLOCKS, extra_args, ¯o_datum);
2775 if (rc != SEPOL_OK) {
2776 goto exit;
2777 }
2778
2779 macro_node = macro_datum->nodes->head->data;
2780
2781 if (macro_node->flavor != CIL_MACRO) {
2782 printf("Failed to resolve %s to a macro\n", new_call->macro_str);
2783 rc = SEPOL_ERR;
2784 goto exit;
2785 }
2786 new_call->macro = (struct cil_macro*)macro_datum;
2787
2788 if (new_call->macro->params != NULL ) {
2789
2790 struct cil_list_item *item;
2791 struct cil_args *new_arg = NULL;
2792 struct cil_tree_node *pc = NULL;
2793
2794 if (new_call->args_tree == NULL) {
2795 cil_tree_log(current, CIL_ERR, "Missing arguments");
2796 rc = SEPOL_ERR;
2797 goto exit;
2798 }
2799
2800 pc = new_call->args_tree->root->cl_head;
2801
2802 cil_list_init(&new_call->args, CIL_LIST_ITEM);
2803
2804 cil_list_for_each(item, new_call->macro->params) {
2805 enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor;
2806
2807 if (pc == NULL) {
2808 cil_tree_log(current, CIL_ERR, "Missing arguments");
2809 rc = SEPOL_ERR;
2810 goto exit;
2811 }
2812 if (item->flavor != CIL_PARAM) {
2813 rc = SEPOL_ERR;
2814 goto exit;
2815 }
2816
2817 cil_args_init(&new_arg);
2818
2819 switch (flavor) {
2820 case CIL_NAME: {
2821 struct cil_name *name;
2822 name = __cil_insert_name(args->db, pc->data, current);
2823 if (name != NULL) {
2824 new_arg->arg = (struct cil_symtab_datum *)name;
2825 } else {
2826 new_arg->arg_str = pc->data;
2827 }
2828 }
2829 break;
2830 case CIL_TYPE:
2831 new_arg->arg_str = pc->data;
2832 break;
2833 case CIL_ROLE:
2834 new_arg->arg_str = pc->data;
2835 break;
2836 case CIL_USER:
2837 new_arg->arg_str = pc->data;
2838 break;
2839 case CIL_SENS:
2840 new_arg->arg_str = pc->data;
2841 break;
2842 case CIL_CAT:
2843 new_arg->arg_str = pc->data;
2844 break;
2845 case CIL_BOOL:
2846 new_arg->arg_str = pc->data;
2847 break;
2848 case CIL_CATSET: {
2849 if (pc->cl_head != NULL) {
2850 struct cil_catset *catset = NULL;
2851 struct cil_tree_node *cat_node = NULL;
2852 cil_catset_init(&catset);
2853 rc = cil_fill_cats(pc, &catset->cats);
2854 if (rc != SEPOL_OK) {
2855 cil_destroy_catset(catset);
2856 goto exit;
2857 }
2858 cil_tree_node_init(&cat_node);
2859 cat_node->flavor = CIL_CATSET;
2860 cat_node->data = catset;
2861 cil_list_append(((struct cil_symtab_datum*)catset)->nodes,
2862 CIL_LIST_ITEM, cat_node);
2863 new_arg->arg = (struct cil_symtab_datum*)catset;
2864 } else {
2865 new_arg->arg_str = pc->data;
2866 }
2867
2868 break;
2869 }
2870 case CIL_LEVEL: {
2871 if (pc->cl_head != NULL) {
2872 struct cil_level *level = NULL;
2873 struct cil_tree_node *lvl_node = NULL;
2874 cil_level_init(&level);
2875
2876 rc = cil_fill_level(pc->cl_head, level);
2877 if (rc != SEPOL_OK) {
2878 cil_log(CIL_ERR, "Failed to create anonymous level, rc: %d\n", rc);
2879 cil_destroy_level(level);
2880 goto exit;
2881 }
2882 cil_tree_node_init(&lvl_node);
2883 lvl_node->flavor = CIL_LEVEL;
2884 lvl_node->data = level;
2885 cil_list_append(((struct cil_symtab_datum*)level)->nodes,
2886 CIL_LIST_ITEM, lvl_node);
2887 new_arg->arg = (struct cil_symtab_datum*)level;
2888 } else {
2889 new_arg->arg_str = pc->data;
2890 }
2891
2892 break;
2893 }
2894 case CIL_LEVELRANGE: {
2895 if (pc->cl_head != NULL) {
2896 struct cil_levelrange *range = NULL;
2897 struct cil_tree_node *range_node = NULL;
2898 cil_levelrange_init(&range);
2899
2900 rc = cil_fill_levelrange(pc->cl_head, range);
2901 if (rc != SEPOL_OK) {
2902 cil_log(CIL_ERR, "Failed to create anonymous levelrange, rc: %d\n", rc);
2903 cil_destroy_levelrange(range);
2904 goto exit;
2905 }
2906 cil_tree_node_init(&range_node);
2907 range_node->flavor = CIL_LEVELRANGE;
2908 range_node->data = range;
2909 cil_list_append(((struct cil_symtab_datum*)range)->nodes,
2910 CIL_LIST_ITEM, range_node);
2911 new_arg->arg = (struct cil_symtab_datum*)range;
2912 } else {
2913 new_arg->arg_str = pc->data;
2914 }
2915
2916 break;
2917 }
2918 case CIL_IPADDR: {
2919 if (pc->cl_head != NULL) {
2920 struct cil_ipaddr *ipaddr = NULL;
2921 struct cil_tree_node *addr_node = NULL;
2922 cil_ipaddr_init(&ipaddr);
2923
2924 rc = cil_fill_ipaddr(pc->cl_head, ipaddr);
2925 if (rc != SEPOL_OK) {
2926 cil_log(CIL_ERR, "Failed to create anonymous ip address, rc; %d\n", rc);
2927 cil_destroy_ipaddr(ipaddr);
2928 goto exit;
2929 }
2930 cil_tree_node_init(&addr_node);
2931 addr_node->flavor = CIL_IPADDR;
2932 addr_node->data = ipaddr;
2933 cil_list_append(((struct cil_symtab_datum*)ipaddr)->nodes,
2934 CIL_LIST_ITEM, addr_node);
2935 new_arg->arg = (struct cil_symtab_datum*)ipaddr;
2936 } else {
2937 new_arg->arg_str = pc->data;
2938 }
2939
2940 break;
2941 }
2942 case CIL_CLASS:
2943 new_arg->arg_str = pc->data;
2944 break;
2945 case CIL_MAP_CLASS:
2946 new_arg->arg_str = pc->data;
2947 break;
2948 case CIL_CLASSPERMISSION: {
2949 if (pc->cl_head != NULL) {
2950 struct cil_classpermission *cp = NULL;
2951 struct cil_tree_node *cp_node = NULL;
2952
2953 cil_classpermission_init(&cp);
2954 rc = cil_fill_classperms_list(pc, &cp->classperms);
2955 if (rc != SEPOL_OK) {
2956 cil_log(CIL_ERR, "Failed to create anonymous classpermission\n");
2957 cil_destroy_classpermission(cp);
2958 goto exit;
2959 }
2960 cil_tree_node_init(&cp_node);
2961 cp_node->flavor = CIL_CLASSPERMISSION;
2962 cp_node->data = cp;
2963 cil_list_append(cp->datum.nodes, CIL_LIST_ITEM, cp_node);
2964 new_arg->arg = (struct cil_symtab_datum*)cp;
2965 } else {
2966 new_arg->arg_str = pc->data;
2967 }
2968 break;
2969 }
2970 default:
2971 cil_log(CIL_ERR, "Unexpected flavor: %d\n",
2972 (((struct cil_param*)item->data)->flavor));
2973 rc = SEPOL_ERR;
2974 goto exit;
2975 }
2976 new_arg->param_str = ((struct cil_param*)item->data)->str;
2977 new_arg->flavor = flavor;
2978
2979 cil_list_append(new_call->args, CIL_ARGS, new_arg);
2980
2981 pc = pc->next;
2982 }
2983
2984 if (pc != NULL) {
2985 cil_tree_log(current, CIL_ERR, "Unexpected arguments");
2986 rc = SEPOL_ERR;
2987 goto exit;
2988 }
2989 } else if (new_call->args_tree != NULL) {
2990 cil_tree_log(current, CIL_ERR, "Unexpected arguments");
2991 rc = SEPOL_ERR;
2992 goto exit;
2993 }
2994
2995 if (new_call->copied == 0) {
2996 new_call->copied = 1;
2997
2998 rc = cil_check_recursive_call(current, macro_node);
2999 if (rc != SEPOL_OK) {
3000 goto exit;
3001 }
3002
3003 rc = cil_copy_ast(db, macro_node, current);
3004 if (rc != SEPOL_OK) {
3005 cil_log(CIL_ERR, "Failed to copy macro, rc: %d\n", rc);
3006 goto exit;
3007 }
3008 }
3009
3010 return SEPOL_OK;
3011
3012 exit:
3013 return rc;
3014 }
3015
cil_resolve_call2(struct cil_tree_node * current,void * extra_args)3016 int cil_resolve_call2(struct cil_tree_node *current, void *extra_args)
3017 {
3018 struct cil_call *new_call = current->data;
3019 int rc = SEPOL_ERR;
3020 enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
3021 struct cil_list_item *item;
3022
3023 if (new_call->args == NULL) {
3024 rc = SEPOL_OK;
3025 goto exit;
3026 }
3027
3028 cil_list_for_each(item, new_call->args) {
3029 struct cil_args *arg = item->data;
3030 if (arg->arg == NULL && arg->arg_str == NULL) {
3031 cil_log(CIL_ERR, "Arguments not created correctly\n");
3032 rc = SEPOL_ERR;
3033 goto exit;
3034 }
3035
3036 switch (arg->flavor) {
3037 case CIL_NAME:
3038 if (arg->arg != NULL) {
3039 continue; /* No need to resolve */
3040 } else {
3041 sym_index = CIL_SYM_NAMES;
3042 }
3043 break;
3044 case CIL_LEVEL:
3045 if (arg->arg_str == NULL && arg->arg != NULL) {
3046 continue; // anonymous, no need to resolve
3047 } else {
3048 sym_index = CIL_SYM_LEVELS;
3049 }
3050 break;
3051 case CIL_LEVELRANGE:
3052 if (arg->arg_str == NULL && arg->arg != NULL) {
3053 continue; // anonymous, no need to resolve
3054 } else {
3055 sym_index = CIL_SYM_LEVELRANGES;
3056 }
3057 break;
3058 case CIL_CATSET:
3059 if (arg->arg_str == NULL && arg->arg != NULL) {
3060 continue; // anonymous, no need to resolve
3061 } else {
3062 sym_index = CIL_SYM_CATS;
3063 }
3064 break;
3065 case CIL_IPADDR:
3066 if (arg->arg_str == NULL && arg->arg != NULL) {
3067 continue; // anonymous, no need to resolve
3068 } else {
3069 sym_index = CIL_SYM_IPADDRS;
3070 }
3071 break;
3072 case CIL_CLASSPERMISSION:
3073 if (arg->arg_str == NULL && arg->arg != NULL) {
3074 continue;
3075 } else {
3076 sym_index = CIL_SYM_CLASSPERMSETS;
3077 }
3078 break;
3079 case CIL_TYPE:
3080 if (arg->arg_str == NULL && arg->arg != NULL) {
3081 continue; // anonymous, no need to resolve
3082 } else {
3083 sym_index = CIL_SYM_TYPES;
3084 }
3085 break;
3086 case CIL_ROLE:
3087 sym_index = CIL_SYM_ROLES;
3088 break;
3089 case CIL_USER:
3090 sym_index = CIL_SYM_USERS;
3091 break;
3092 case CIL_SENS:
3093 sym_index = CIL_SYM_SENS;
3094 break;
3095 case CIL_CAT:
3096 sym_index = CIL_SYM_CATS;
3097 break;
3098 case CIL_CLASS:
3099 case CIL_MAP_CLASS:
3100 sym_index = CIL_SYM_CLASSES;
3101 break;
3102 case CIL_BOOL:
3103 sym_index = CIL_SYM_BOOLS;
3104 break;
3105 default:
3106 rc = SEPOL_ERR;
3107 goto exit;
3108 }
3109
3110 if (sym_index != CIL_SYM_UNKNOWN) {
3111 rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg));
3112 if (rc != SEPOL_OK) {
3113 goto exit;
3114 }
3115 }
3116 }
3117
3118 return SEPOL_OK;
3119
3120 exit:
3121 return rc;
3122 }
3123
cil_resolve_name_call_args(struct cil_call * call,char * name,enum cil_sym_index sym_index,struct cil_symtab_datum ** datum)3124 int cil_resolve_name_call_args(struct cil_call *call, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum)
3125 {
3126 struct cil_list_item *item;
3127 enum cil_sym_index param_index = CIL_SYM_UNKNOWN;
3128 int rc = SEPOL_ERR;
3129
3130 if (call == NULL || name == NULL) {
3131 goto exit;
3132 }
3133
3134 if (call->args == NULL) {
3135 goto exit;
3136 }
3137
3138 cil_list_for_each(item, call->args) {
3139 struct cil_args * arg = item->data;
3140 rc = cil_flavor_to_symtab_index(arg->flavor, ¶m_index);
3141 if (param_index == sym_index) {
3142 if (name == arg->param_str) {
3143 *datum = arg->arg;
3144 rc = SEPOL_OK;
3145 goto exit;
3146 }
3147 }
3148 }
3149
3150 return SEPOL_ERR;
3151
3152 exit:
3153 return rc;
3154 }
3155
cil_resolve_expr(enum cil_flavor expr_type,struct cil_list * str_expr,struct cil_list ** datum_expr,struct cil_tree_node * parent,void * extra_args)3156 int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struct cil_list **datum_expr, struct cil_tree_node *parent, void *extra_args)
3157 {
3158 int rc = SEPOL_ERR;
3159 struct cil_list_item *curr;
3160 struct cil_symtab_datum *res_datum = NULL;
3161 enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
3162
3163 switch (str_expr->flavor) {
3164 case CIL_BOOL:
3165 sym_index = CIL_SYM_BOOLS;
3166 break;
3167 case CIL_TUNABLE:
3168 sym_index = CIL_SYM_TUNABLES;
3169 break;
3170 case CIL_TYPE:
3171 sym_index = CIL_SYM_TYPES;
3172 break;
3173 case CIL_ROLE:
3174 sym_index = CIL_SYM_ROLES;
3175 break;
3176 case CIL_USER:
3177 sym_index = CIL_SYM_USERS;
3178 break;
3179 case CIL_CAT:
3180 sym_index = CIL_SYM_CATS;
3181 break;
3182 default:
3183 break;
3184 }
3185
3186 cil_list_init(datum_expr, str_expr->flavor);
3187
3188 cil_list_for_each(curr, str_expr) {
3189 switch (curr->flavor) {
3190 case CIL_STRING:
3191 rc = cil_resolve_name(parent, curr->data, sym_index, extra_args, &res_datum);
3192 if (rc != SEPOL_OK) {
3193 goto exit;
3194 }
3195
3196 if (sym_index == CIL_SYM_TYPES && (expr_type == CIL_CONSTRAIN || expr_type == CIL_VALIDATETRANS)) {
3197 cil_type_used(res_datum, CIL_ATTR_CONSTRAINT);
3198 }
3199
3200 cil_list_append(*datum_expr, CIL_DATUM, res_datum);
3201 break;
3202 case CIL_LIST: {
3203 struct cil_list *datum_sub_expr;
3204 rc = cil_resolve_expr(expr_type, curr->data, &datum_sub_expr, parent, extra_args);
3205 if (rc != SEPOL_OK) {
3206 cil_list_destroy(&datum_sub_expr, CIL_TRUE);
3207 goto exit;
3208 }
3209 cil_list_append(*datum_expr, CIL_LIST, datum_sub_expr);
3210 break;
3211 }
3212 default:
3213 cil_list_append(*datum_expr, curr->flavor, curr->data);
3214 break;
3215 }
3216 }
3217 return SEPOL_OK;
3218
3219 exit:
3220 return rc;
3221 }
3222
cil_resolve_boolif(struct cil_tree_node * current,void * extra_args)3223 int cil_resolve_boolif(struct cil_tree_node *current, void *extra_args)
3224 {
3225 int rc = SEPOL_ERR;
3226 struct cil_booleanif *bif = (struct cil_booleanif*)current->data;
3227
3228 rc = cil_resolve_expr(CIL_BOOLEANIF, bif->str_expr, &bif->datum_expr, current, extra_args);
3229 if (rc != SEPOL_OK) {
3230 goto exit;
3231 }
3232
3233 return SEPOL_OK;
3234
3235 exit:
3236 return rc;
3237 }
3238
3239 static int __cil_evaluate_tunable_expr(struct cil_list_item *curr);
3240
__cil_evaluate_tunable_expr_helper(struct cil_list_item * curr)3241 static int __cil_evaluate_tunable_expr_helper(struct cil_list_item *curr)
3242 {
3243 if (curr == NULL) {
3244 return CIL_FALSE;
3245 } else if (curr->flavor == CIL_DATUM) {
3246 struct cil_tunable *tun = curr->data;
3247 return tun->value;
3248 } else if (curr->flavor == CIL_LIST) {
3249 struct cil_list *l = curr->data;
3250 return __cil_evaluate_tunable_expr(l->head);
3251 } else {
3252 return CIL_FALSE;
3253 }
3254 }
3255
__cil_evaluate_tunable_expr(struct cil_list_item * curr)3256 static int __cil_evaluate_tunable_expr(struct cil_list_item *curr)
3257 {
3258 /* Assumes expression is well-formed */
3259
3260 if (curr == NULL) {
3261 return CIL_FALSE;
3262 } else if (curr->flavor == CIL_OP) {
3263 uint16_t v1, v2;
3264 enum cil_flavor op_flavor = (enum cil_flavor)curr->data;
3265
3266 v1 = __cil_evaluate_tunable_expr_helper(curr->next);
3267
3268 if (op_flavor == CIL_NOT) return !v1;
3269
3270 v2 = __cil_evaluate_tunable_expr_helper(curr->next->next);
3271
3272 if (op_flavor == CIL_AND) return (v1 && v2);
3273 else if (op_flavor == CIL_OR) return (v1 || v2);
3274 else if (op_flavor == CIL_XOR) return (v1 ^ v2);
3275 else if (op_flavor == CIL_EQ) return (v1 == v2);
3276 else if (op_flavor == CIL_NEQ) return (v1 != v2);
3277 else return CIL_FALSE;
3278 } else {
3279 uint16_t v;
3280 for (;curr; curr = curr->next) {
3281 v = __cil_evaluate_tunable_expr_helper(curr);
3282 if (v) return v;
3283 }
3284 return CIL_FALSE;
3285 }
3286 }
3287
cil_resolve_tunif(struct cil_tree_node * current,void * extra_args)3288 int cil_resolve_tunif(struct cil_tree_node *current, void *extra_args)
3289 {
3290 struct cil_args_resolve *args = extra_args;
3291 struct cil_db *db = NULL;
3292 int rc = SEPOL_ERR;
3293 struct cil_tunableif *tif = (struct cil_tunableif*)current->data;
3294 uint16_t result = CIL_FALSE;
3295 struct cil_tree_node *true_node = NULL;
3296 struct cil_tree_node *false_node = NULL;
3297 struct cil_condblock *cb = NULL;
3298
3299 if (args != NULL) {
3300 db = args->db;
3301 }
3302
3303 rc = cil_resolve_expr(CIL_TUNABLEIF, tif->str_expr, &tif->datum_expr, current, extra_args);
3304 if (rc != SEPOL_OK) {
3305 goto exit;
3306 }
3307
3308 result = __cil_evaluate_tunable_expr(tif->datum_expr->head);
3309
3310 if (current->cl_head != NULL && current->cl_head->flavor == CIL_CONDBLOCK) {
3311 cb = current->cl_head->data;
3312 if (cb->flavor == CIL_CONDTRUE) {
3313 true_node = current->cl_head;
3314 } else if (cb->flavor == CIL_CONDFALSE) {
3315 false_node = current->cl_head;
3316 }
3317 }
3318
3319 if (current->cl_head != NULL && current->cl_head->next != NULL && current->cl_head->next->flavor == CIL_CONDBLOCK) {
3320 cb = current->cl_head->next->data;
3321 if (cb->flavor == CIL_CONDTRUE) {
3322 true_node = current->cl_head->next;
3323 } else if (cb->flavor == CIL_CONDFALSE) {
3324 false_node = current->cl_head->next;
3325 }
3326 }
3327
3328 if (result == CIL_TRUE) {
3329 if (true_node != NULL) {
3330 rc = cil_copy_ast(db, true_node, current->parent);
3331 if (rc != SEPOL_OK) {
3332 goto exit;
3333 }
3334 }
3335 } else {
3336 if (false_node != NULL) {
3337 rc = cil_copy_ast(db, false_node, current->parent);
3338 if (rc != SEPOL_OK) {
3339 goto exit;
3340 }
3341 }
3342 }
3343
3344 cil_tree_children_destroy(current);
3345 current->cl_head = NULL;
3346 current->cl_tail = NULL;
3347
3348 return SEPOL_OK;
3349
3350 exit:
3351 return rc;
3352 }
3353
cil_resolve_userattributeset(struct cil_tree_node * current,void * extra_args)3354 int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args)
3355 {
3356 int rc = SEPOL_ERR;
3357 struct cil_userattributeset *attrusers = current->data;
3358 struct cil_symtab_datum *attr_datum = NULL;
3359 struct cil_tree_node *attr_node = NULL;
3360 struct cil_userattribute *attr = NULL;
3361
3362 rc = cil_resolve_name(current, attrusers->attr_str, CIL_SYM_USERS, extra_args, &attr_datum);
3363 if (rc != SEPOL_OK) {
3364 goto exit;
3365 }
3366 attr_node = attr_datum->nodes->head->data;
3367
3368 if (attr_node->flavor != CIL_USERATTRIBUTE) {
3369 rc = SEPOL_ERR;
3370 cil_log(CIL_ERR, "Attribute user not an attribute\n");
3371 goto exit;
3372 }
3373 attr = (struct cil_userattribute*)attr_datum;
3374
3375 rc = cil_resolve_expr(CIL_USERATTRIBUTESET, attrusers->str_expr, &attrusers->datum_expr, current, extra_args);
3376 if (rc != SEPOL_OK) {
3377 goto exit;
3378 }
3379
3380 rc = cil_verify_no_self_reference(attr_datum, attrusers->datum_expr);
3381 if (rc != SEPOL_OK) {
3382 goto exit;
3383 }
3384
3385 if (attr->expr_list == NULL) {
3386 cil_list_init(&attr->expr_list, CIL_USERATTRIBUTE);
3387 }
3388
3389 cil_list_append(attr->expr_list, CIL_LIST, attrusers->datum_expr);
3390
3391 return SEPOL_OK;
3392
3393 exit:
3394 return rc;
3395 }
3396
__cil_resolve_ast_node(struct cil_tree_node * node,void * extra_args)3397 int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
3398 {
3399 int rc = SEPOL_OK;
3400 struct cil_args_resolve *args = extra_args;
3401 enum cil_pass pass = 0;
3402 struct cil_list *ins;
3403
3404 if (node == NULL || args == NULL) {
3405 goto exit;
3406 }
3407 ins = args->in_list;
3408
3409 pass = args->pass;
3410 switch (pass) {
3411 case CIL_PASS_TIF:
3412 if (node->flavor == CIL_TUNABLEIF) {
3413 rc = cil_resolve_tunif(node, args);
3414 }
3415 break;
3416 case CIL_PASS_IN:
3417 if (node->flavor == CIL_IN) {
3418 // due to ordering issues, in statements are just gathered here and
3419 // resolved together in cil_resolve_in_list once all are found
3420 cil_list_prepend(ins, CIL_NODE, node);
3421 }
3422 break;
3423 case CIL_PASS_BLKIN_LINK:
3424 if (node->flavor == CIL_BLOCKINHERIT) {
3425 rc = cil_resolve_blockinherit_link(node, args);
3426 }
3427 break;
3428 case CIL_PASS_BLKIN_COPY:
3429 if (node->flavor == CIL_BLOCK) {
3430 rc = cil_resolve_blockinherit_copy(node, args);
3431 }
3432 break;
3433 case CIL_PASS_BLKABS:
3434 if (node->flavor == CIL_BLOCKABSTRACT) {
3435 rc = cil_resolve_blockabstract(node, args);
3436 }
3437 break;
3438 case CIL_PASS_MACRO:
3439 if (node->flavor == CIL_CALL && args->macro != NULL) {
3440 rc = cil_resolve_call1(node, args);
3441 }
3442 break;
3443 case CIL_PASS_CALL1:
3444 if (node->flavor == CIL_CALL) {
3445 rc = cil_resolve_call1(node, args);
3446 }
3447 break;
3448 case CIL_PASS_CALL2:
3449 if (node->flavor == CIL_CALL) {
3450 rc = cil_resolve_call2(node, args);
3451 }
3452 break;
3453 case CIL_PASS_ALIAS1:
3454 switch (node->flavor) {
3455 case CIL_TYPEALIASACTUAL:
3456 rc = cil_resolve_aliasactual(node, args, CIL_TYPE, CIL_TYPEALIAS);
3457 break;
3458 case CIL_SENSALIASACTUAL:
3459 rc = cil_resolve_aliasactual(node, args, CIL_SENS, CIL_SENSALIAS);
3460 break;
3461 case CIL_CATALIASACTUAL:
3462 rc = cil_resolve_aliasactual(node, args, CIL_CAT, CIL_CATALIAS);
3463 break;
3464 default:
3465 break;
3466 }
3467 break;
3468 case CIL_PASS_ALIAS2:
3469 switch (node->flavor) {
3470 case CIL_TYPEALIAS:
3471 rc = cil_resolve_alias_to_actual(node, CIL_TYPE);
3472 break;
3473 case CIL_SENSALIAS:
3474 rc = cil_resolve_alias_to_actual(node, CIL_SENS);
3475 break;
3476 case CIL_CATALIAS:
3477 rc = cil_resolve_alias_to_actual(node, CIL_CAT);
3478 break;
3479 default:
3480 break;
3481 }
3482 break;
3483 case CIL_PASS_MISC1:
3484 switch (node->flavor) {
3485 case CIL_SIDORDER:
3486 rc = cil_resolve_sidorder(node, args);
3487 break;
3488 case CIL_CLASSORDER:
3489 rc = cil_resolve_classorder(node, args);
3490 break;
3491 case CIL_CATORDER:
3492 rc = cil_resolve_catorder(node, args);
3493 break;
3494 case CIL_SENSITIVITYORDER:
3495 rc = cil_resolve_sensitivityorder(node, args);
3496 break;
3497 case CIL_BOOLEANIF:
3498 rc = cil_resolve_boolif(node, args);
3499 break;
3500 default:
3501 break;
3502 }
3503 break;
3504 case CIL_PASS_MLS:
3505 switch (node->flavor) {
3506 case CIL_CATSET:
3507 rc = cil_resolve_catset(node, (struct cil_catset*)node->data, args);
3508 break;
3509 default:
3510 break;
3511 }
3512 break;
3513 case CIL_PASS_MISC2:
3514 switch (node->flavor) {
3515 case CIL_SENSCAT:
3516 rc = cil_resolve_senscat(node, args);
3517 break;
3518 case CIL_CLASSCOMMON:
3519 rc = cil_resolve_classcommon(node, args);
3520 break;
3521 default:
3522 break;
3523 }
3524 break;
3525 case CIL_PASS_MISC3:
3526 switch (node->flavor) {
3527 case CIL_TYPEATTRIBUTESET:
3528 rc = cil_resolve_typeattributeset(node, args);
3529 break;
3530 case CIL_EXPANDTYPEATTRIBUTE:
3531 rc = cil_resolve_expandtypeattribute(node, args);
3532 break;
3533 case CIL_TYPEBOUNDS:
3534 rc = cil_resolve_bounds(node, args, CIL_TYPE, CIL_TYPEATTRIBUTE);
3535 break;
3536 case CIL_TYPEPERMISSIVE:
3537 rc = cil_resolve_typepermissive(node, args);
3538 break;
3539 case CIL_NAMETYPETRANSITION:
3540 rc = cil_resolve_nametypetransition(node, args);
3541 break;
3542 case CIL_RANGETRANSITION:
3543 rc = cil_resolve_rangetransition(node, args);
3544 break;
3545 case CIL_CLASSPERMISSIONSET:
3546 rc = cil_resolve_classpermissionset(node, (struct cil_classpermissionset*)node->data, args);
3547 break;
3548 case CIL_CLASSMAPPING:
3549 rc = cil_resolve_classmapping(node, args);
3550 break;
3551 case CIL_AVRULE:
3552 case CIL_AVRULEX:
3553 rc = cil_resolve_avrule(node, args);
3554 break;
3555 case CIL_PERMISSIONX:
3556 rc = cil_resolve_permissionx(node, (struct cil_permissionx*)node->data, args);
3557 break;
3558 case CIL_TYPE_RULE:
3559 rc = cil_resolve_type_rule(node, args);
3560 break;
3561 case CIL_USERROLE:
3562 rc = cil_resolve_userrole(node, args);
3563 break;
3564 case CIL_USERLEVEL:
3565 rc = cil_resolve_userlevel(node, args);
3566 break;
3567 case CIL_USERRANGE:
3568 rc = cil_resolve_userrange(node, args);
3569 break;
3570 case CIL_USERBOUNDS:
3571 rc = cil_resolve_bounds(node, args, CIL_USER, CIL_USERATTRIBUTE);
3572 break;
3573 case CIL_USERPREFIX:
3574 rc = cil_resolve_userprefix(node, args);
3575 break;
3576 case CIL_SELINUXUSER:
3577 case CIL_SELINUXUSERDEFAULT:
3578 rc = cil_resolve_selinuxuser(node, args);
3579 break;
3580 case CIL_ROLEATTRIBUTESET:
3581 rc = cil_resolve_roleattributeset(node, args);
3582 break;
3583 case CIL_ROLETYPE:
3584 rc = cil_resolve_roletype(node, args);
3585 break;
3586 case CIL_ROLETRANSITION:
3587 rc = cil_resolve_roletransition(node, args);
3588 break;
3589 case CIL_ROLEALLOW:
3590 rc = cil_resolve_roleallow(node, args);
3591 break;
3592 case CIL_ROLEBOUNDS:
3593 rc = cil_resolve_bounds(node, args, CIL_ROLE, CIL_ROLEATTRIBUTE);
3594 break;
3595 case CIL_LEVEL:
3596 rc = cil_resolve_level(node, (struct cil_level*)node->data, args);
3597 break;
3598 case CIL_LEVELRANGE:
3599 rc = cil_resolve_levelrange(node, (struct cil_levelrange*)node->data, args);
3600 break;
3601 case CIL_CONSTRAIN:
3602 rc = cil_resolve_constrain(node, args);
3603 break;
3604 case CIL_MLSCONSTRAIN:
3605 rc = cil_resolve_constrain(node, args);
3606 break;
3607 case CIL_VALIDATETRANS:
3608 case CIL_MLSVALIDATETRANS:
3609 rc = cil_resolve_validatetrans(node, args);
3610 break;
3611 case CIL_CONTEXT:
3612 rc = cil_resolve_context(node, (struct cil_context*)node->data, args);
3613 break;
3614 case CIL_FILECON:
3615 rc = cil_resolve_filecon(node, args);
3616 break;
3617 case CIL_IBPKEYCON:
3618 rc = cil_resolve_ibpkeycon(node, args);
3619 break;
3620 case CIL_PORTCON:
3621 rc = cil_resolve_portcon(node, args);
3622 break;
3623 case CIL_NODECON:
3624 rc = cil_resolve_nodecon(node, args);
3625 break;
3626 case CIL_GENFSCON:
3627 rc = cil_resolve_genfscon(node, args);
3628 break;
3629 case CIL_NETIFCON:
3630 rc = cil_resolve_netifcon(node, args);
3631 break;
3632 case CIL_IBENDPORTCON:
3633 rc = cil_resolve_ibendportcon(node, args);
3634 break;
3635 case CIL_PIRQCON:
3636 rc = cil_resolve_pirqcon(node, args);
3637 break;
3638 case CIL_IOMEMCON:
3639 rc = cil_resolve_iomemcon(node, args);
3640 break;
3641 case CIL_IOPORTCON:
3642 rc = cil_resolve_ioportcon(node, args);
3643 break;
3644 case CIL_PCIDEVICECON:
3645 rc = cil_resolve_pcidevicecon(node, args);
3646 break;
3647 case CIL_DEVICETREECON:
3648 rc = cil_resolve_devicetreecon(node, args);
3649 break;
3650 case CIL_FSUSE:
3651 rc = cil_resolve_fsuse(node, args);
3652 break;
3653 case CIL_SIDCONTEXT:
3654 rc = cil_resolve_sidcontext(node, args);
3655 break;
3656 case CIL_DEFAULTUSER:
3657 case CIL_DEFAULTROLE:
3658 case CIL_DEFAULTTYPE:
3659 rc = cil_resolve_default(node, args);
3660 break;
3661 case CIL_DEFAULTRANGE:
3662 rc = cil_resolve_defaultrange(node, args);
3663 break;
3664 case CIL_USERATTRIBUTESET:
3665 rc = cil_resolve_userattributeset(node, args);
3666 break;
3667 default:
3668 break;
3669 }
3670 break;
3671 default:
3672 break;
3673 }
3674
3675 return rc;
3676
3677 exit:
3678 return rc;
3679 }
3680
__cil_resolve_ast_node_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)3681 int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
3682 {
3683 int rc = SEPOL_ERR;
3684 struct cil_args_resolve *args = extra_args;
3685 enum cil_pass pass = args->pass;
3686 struct cil_tree_node *optstack = args->optstack;
3687 struct cil_tree_node *boolif = args->boolif;
3688 struct cil_tree_node *blockstack = args->blockstack;
3689 struct cil_tree_node *macro = args->macro;
3690
3691 if (node == NULL) {
3692 goto exit;
3693 }
3694
3695 if (optstack != NULL) {
3696 if (node->flavor == CIL_TUNABLE || node->flavor == CIL_MACRO) {
3697 /* tuanbles and macros are not allowed in optionals*/
3698 cil_tree_log(node, CIL_ERR, "%s statement is not allowed in optionals", cil_node_to_string(node));
3699 rc = SEPOL_ERR;
3700 goto exit;
3701 }
3702 }
3703
3704 if (blockstack != NULL) {
3705 if (node->flavor == CIL_CAT || node->flavor == CIL_SENS) {
3706 cil_tree_log(node, CIL_ERR, "%s statement is not allowed in blocks", cil_node_to_string(node));
3707 rc = SEPOL_ERR;
3708 goto exit;
3709 }
3710 }
3711
3712 if (macro != NULL) {
3713 if (node->flavor == CIL_BLOCKINHERIT ||
3714 node->flavor == CIL_BLOCK ||
3715 node->flavor == CIL_BLOCKABSTRACT ||
3716 node->flavor == CIL_MACRO) {
3717 cil_tree_log(node, CIL_ERR, "%s statement is not allowed in macros", cil_node_to_string(node));
3718 rc = SEPOL_ERR;
3719 goto exit;
3720 }
3721 }
3722
3723 if (boolif != NULL) {
3724 if (!(node->flavor == CIL_CONDBLOCK ||
3725 node->flavor == CIL_AVRULE ||
3726 node->flavor == CIL_TYPE_RULE ||
3727 node->flavor == CIL_CALL ||
3728 node->flavor == CIL_TUNABLEIF ||
3729 node->flavor == CIL_NAMETYPETRANSITION)) {
3730 if (((struct cil_booleanif*)boolif->data)->preserved_tunable) {
3731 cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs (tunableif treated as a booleanif)", cil_node_to_string(node));
3732 } else {
3733 cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs", cil_node_to_string(node));
3734 }
3735 rc = SEPOL_ERR;
3736 goto exit;
3737 }
3738 }
3739
3740 if (node->flavor == CIL_MACRO) {
3741 if (pass != CIL_PASS_TIF && pass != CIL_PASS_MACRO) {
3742 *finished = CIL_TREE_SKIP_HEAD;
3743 rc = SEPOL_OK;
3744 goto exit;
3745 }
3746 }
3747
3748 if (node->flavor == CIL_BLOCK && ((((struct cil_block*)node->data)->is_abstract == CIL_TRUE) && (pass > CIL_PASS_BLKABS))) {
3749 *finished = CIL_TREE_SKIP_HEAD;
3750 rc = SEPOL_OK;
3751 goto exit;
3752 }
3753
3754 rc = __cil_resolve_ast_node(node, extra_args);
3755 if (rc == SEPOL_ENOENT) {
3756 enum cil_log_level lvl = CIL_ERR;
3757
3758 if (optstack != NULL) {
3759 lvl = CIL_WARN;
3760
3761 struct cil_optional *opt = (struct cil_optional *)optstack->data;
3762 struct cil_tree_node *opt_node = opt->datum.nodes->head->data;
3763 cil_tree_log(opt_node, lvl, "Disabling optional '%s'", opt->datum.name);
3764 /* disable an optional if something failed to resolve */
3765 opt->enabled = CIL_FALSE;
3766 rc = SEPOL_OK;
3767 }
3768
3769 cil_tree_log(node, lvl, "Failed to resolve %s statement", cil_node_to_string(node));
3770 goto exit;
3771 }
3772
3773 return rc;
3774
3775 exit:
3776 return rc;
3777 }
3778
__cil_resolve_ast_first_child_helper(struct cil_tree_node * current,void * extra_args)3779 int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *extra_args)
3780 {
3781 int rc = SEPOL_ERR;
3782 struct cil_args_resolve *args = extra_args;
3783 struct cil_tree_node *optstack = NULL;
3784 struct cil_tree_node *parent = NULL;
3785 struct cil_tree_node *blockstack = NULL;
3786 struct cil_tree_node *new = NULL;
3787
3788 if (current == NULL || extra_args == NULL) {
3789 goto exit;
3790 }
3791
3792 optstack = args->optstack;
3793 parent = current->parent;
3794 blockstack = args->blockstack;
3795
3796 if (parent->flavor == CIL_OPTIONAL || parent->flavor == CIL_BLOCK) {
3797 /* push this node onto a stack */
3798 cil_tree_node_init(&new);
3799
3800 new->data = parent->data;
3801 new->flavor = parent->flavor;
3802
3803 if (parent->flavor == CIL_OPTIONAL) {
3804 if (optstack != NULL) {
3805 optstack->parent = new;
3806 new->cl_head = optstack;
3807 }
3808 args->optstack = new;
3809 } else if (parent->flavor == CIL_BLOCK) {
3810 if (blockstack != NULL) {
3811 blockstack->parent = new;
3812 new->cl_head = blockstack;
3813 }
3814 args->blockstack = new;
3815 }
3816 } else if (parent->flavor == CIL_BOOLEANIF) {
3817 args->boolif = parent;
3818 } else if (parent->flavor == CIL_MACRO) {
3819 args->macro = parent;
3820 }
3821
3822 return SEPOL_OK;
3823
3824 exit:
3825 return rc;
3826
3827 }
3828
__cil_resolve_ast_last_child_helper(struct cil_tree_node * current,void * extra_args)3829 int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *extra_args)
3830 {
3831 int rc = SEPOL_ERR;
3832 struct cil_args_resolve *args = extra_args;
3833 struct cil_tree_node *parent = NULL;
3834 struct cil_tree_node *blockstack = NULL;
3835
3836 if (current == NULL || extra_args == NULL) {
3837 goto exit;
3838 }
3839
3840 parent = current->parent;
3841
3842 if (parent->flavor == CIL_MACRO) {
3843 args->macro = NULL;
3844 } else if (parent->flavor == CIL_OPTIONAL) {
3845 struct cil_tree_node *optstack;
3846
3847 if (((struct cil_optional *)parent->data)->enabled == CIL_FALSE) {
3848 *(args->changed) = CIL_TRUE;
3849 cil_tree_children_destroy(parent);
3850 }
3851
3852 /* pop off the stack */
3853 optstack = args->optstack;
3854 args->optstack = optstack->cl_head;
3855 if (optstack->cl_head) {
3856 optstack->cl_head->parent = NULL;
3857 }
3858 free(optstack);
3859 } else if (parent->flavor == CIL_BOOLEANIF) {
3860 args->boolif = NULL;
3861 } else if (parent->flavor == CIL_BLOCK) {
3862 /* pop off the stack */
3863 blockstack = args->blockstack;
3864 args->blockstack = blockstack->cl_head;
3865 if (blockstack->cl_head) {
3866 blockstack->cl_head->parent = NULL;
3867 }
3868 free(blockstack);
3869 }
3870
3871 return SEPOL_OK;
3872
3873 exit:
3874 return rc;
3875 }
3876
cil_destroy_tree_node_stack(struct cil_tree_node * curr)3877 static void cil_destroy_tree_node_stack(struct cil_tree_node *curr)
3878 {
3879 struct cil_tree_node *next;
3880 while (curr != NULL) {
3881 next = curr->cl_head;
3882 free(curr);
3883 curr = next;
3884 }
3885 }
3886
cil_resolve_ast(struct cil_db * db,struct cil_tree_node * current)3887 int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
3888 {
3889 int rc = SEPOL_ERR;
3890 struct cil_args_resolve extra_args;
3891 enum cil_pass pass = CIL_PASS_TIF;
3892 uint32_t changed = 0;
3893
3894 if (db == NULL || current == NULL) {
3895 return rc;
3896 }
3897
3898 extra_args.db = db;
3899 extra_args.pass = pass;
3900 extra_args.changed = &changed;
3901 extra_args.last_resolved_name = NULL;
3902 extra_args.optstack = NULL;
3903 extra_args.boolif= NULL;
3904 extra_args.macro = NULL;
3905 extra_args.sidorder_lists = NULL;
3906 extra_args.classorder_lists = NULL;
3907 extra_args.unordered_classorder_lists = NULL;
3908 extra_args.catorder_lists = NULL;
3909 extra_args.sensitivityorder_lists = NULL;
3910 extra_args.in_list = NULL;
3911 extra_args.blockstack = NULL;
3912
3913 cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM);
3914 cil_list_init(&extra_args.classorder_lists, CIL_LIST_ITEM);
3915 cil_list_init(&extra_args.unordered_classorder_lists, CIL_LIST_ITEM);
3916 cil_list_init(&extra_args.catorder_lists, CIL_LIST_ITEM);
3917 cil_list_init(&extra_args.sensitivityorder_lists, CIL_LIST_ITEM);
3918 cil_list_init(&extra_args.in_list, CIL_IN);
3919 for (pass = CIL_PASS_TIF; pass < CIL_PASS_NUM; pass++) {
3920 extra_args.pass = pass;
3921 rc = cil_tree_walk(current, __cil_resolve_ast_node_helper, __cil_resolve_ast_first_child_helper, __cil_resolve_ast_last_child_helper, &extra_args);
3922 if (rc != SEPOL_OK) {
3923 cil_log(CIL_INFO, "Pass %i of resolution failed\n", pass);
3924 goto exit;
3925 }
3926
3927 if (pass == CIL_PASS_IN) {
3928 rc = cil_resolve_in_list(&extra_args);
3929 if (rc != SEPOL_OK) {
3930 goto exit;
3931 }
3932 cil_list_destroy(&extra_args.in_list, CIL_FALSE);
3933 }
3934
3935 if (pass == CIL_PASS_MISC1) {
3936 db->sidorder = __cil_ordered_lists_merge_all(&extra_args.sidorder_lists, NULL);
3937 if (db->sidorder == NULL) {
3938 rc = SEPOL_ERR;
3939 goto exit;
3940 }
3941 db->classorder = __cil_ordered_lists_merge_all(&extra_args.classorder_lists, &extra_args.unordered_classorder_lists);
3942 if (db->classorder == NULL) {
3943 rc = SEPOL_ERR;
3944 goto exit;
3945 }
3946 db->catorder = __cil_ordered_lists_merge_all(&extra_args.catorder_lists, NULL);
3947 if (db->catorder == NULL) {
3948 rc = SEPOL_ERR;
3949 goto exit;
3950 }
3951 cil_set_cat_values(db->catorder, db);
3952 db->sensitivityorder = __cil_ordered_lists_merge_all(&extra_args.sensitivityorder_lists, NULL);
3953 if (db->sensitivityorder == NULL) {
3954 rc = SEPOL_ERR;
3955 goto exit;
3956 }
3957
3958 rc = __cil_verify_ordered(current, CIL_SID);
3959 if (rc != SEPOL_OK) {
3960 goto exit;
3961 }
3962
3963 rc = __cil_verify_ordered(current, CIL_CLASS);
3964 if (rc != SEPOL_OK) {
3965 goto exit;
3966 }
3967
3968 rc = __cil_verify_ordered(current, CIL_CAT);
3969 if (rc != SEPOL_OK) {
3970 goto exit;
3971 }
3972
3973 rc = __cil_verify_ordered(current, CIL_SENS);
3974 if (rc != SEPOL_OK) {
3975 goto exit;
3976 }
3977 }
3978
3979 if (changed && (pass > CIL_PASS_CALL1)) {
3980 /* Need to re-resolve because an optional was disabled that contained
3981 * one or more declarations. We only need to reset to the call1 pass
3982 * because things done in the preceeding passes aren't allowed in
3983 * optionals, and thus can't be disabled.
3984 * Note: set pass to CIL_PASS_CALL1 because the pass++ will increment
3985 * it to CIL_PASS_CALL2
3986 */
3987 cil_log(CIL_INFO, "Resetting declarations\n");
3988
3989 if (pass >= CIL_PASS_MISC1) {
3990 __cil_ordered_lists_reset(&extra_args.sidorder_lists);
3991 __cil_ordered_lists_reset(&extra_args.classorder_lists);
3992 __cil_ordered_lists_reset(&extra_args.unordered_classorder_lists);
3993 __cil_ordered_lists_reset(&extra_args.catorder_lists);
3994 __cil_ordered_lists_reset(&extra_args.sensitivityorder_lists);
3995 cil_list_destroy(&db->sidorder, CIL_FALSE);
3996 cil_list_destroy(&db->classorder, CIL_FALSE);
3997 cil_list_destroy(&db->catorder, CIL_FALSE);
3998 cil_list_destroy(&db->sensitivityorder, CIL_FALSE);
3999 }
4000
4001 pass = CIL_PASS_CALL1;
4002
4003 rc = cil_reset_ast(current);
4004 if (rc != SEPOL_OK) {
4005 cil_log(CIL_ERR, "Failed to reset declarations\n");
4006 goto exit;
4007 }
4008 }
4009
4010 /* reset the arguments */
4011 changed = 0;
4012 while (extra_args.optstack != NULL) {
4013 cil_destroy_tree_node_stack(extra_args.optstack);
4014 extra_args.optstack = NULL;
4015 }
4016 while (extra_args.blockstack!= NULL) {
4017 cil_destroy_tree_node_stack(extra_args.blockstack);
4018 extra_args.blockstack = NULL;
4019 }
4020 }
4021
4022 rc = __cil_verify_initsids(db->sidorder);
4023 if (rc != SEPOL_OK) {
4024 goto exit;
4025 }
4026
4027 rc = SEPOL_OK;
4028 exit:
4029 cil_destroy_tree_node_stack(extra_args.optstack);
4030 cil_destroy_tree_node_stack(extra_args.blockstack);
4031 __cil_ordered_lists_destroy(&extra_args.sidorder_lists);
4032 __cil_ordered_lists_destroy(&extra_args.classorder_lists);
4033 __cil_ordered_lists_destroy(&extra_args.catorder_lists);
4034 __cil_ordered_lists_destroy(&extra_args.sensitivityorder_lists);
4035 __cil_ordered_lists_destroy(&extra_args.unordered_classorder_lists);
4036 cil_list_destroy(&extra_args.in_list, CIL_FALSE);
4037
4038 return rc;
4039 }
4040
__cil_resolve_name_with_root(struct cil_db * db,char * name,enum cil_sym_index sym_index,struct cil_symtab_datum ** datum)4041 static int __cil_resolve_name_with_root(struct cil_db *db, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum)
4042 {
4043 symtab_t *symtab = &((struct cil_root *)db->ast->root->data)->symtab[sym_index];
4044
4045 return cil_symtab_get_datum(symtab, name, datum);
4046 }
4047
__cil_resolve_name_with_parents(struct cil_tree_node * node,char * name,enum cil_sym_index sym_index,struct cil_symtab_datum ** datum)4048 static int __cil_resolve_name_with_parents(struct cil_tree_node *node, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum)
4049 {
4050 int rc = SEPOL_ERR;
4051 symtab_t *symtab = NULL;
4052
4053 while (node != NULL && rc != SEPOL_OK) {
4054 switch (node->flavor) {
4055 case CIL_ROOT:
4056 goto exit;
4057 break;
4058 case CIL_BLOCK:
4059 symtab = &((struct cil_block*)node->data)->symtab[sym_index];
4060 rc = cil_symtab_get_datum(symtab, name, datum);
4061 break;
4062 case CIL_BLOCKINHERIT: {
4063 struct cil_blockinherit *inherit = node->data;
4064 rc = __cil_resolve_name_with_parents(node->parent, name, sym_index, datum);
4065 if (rc != SEPOL_OK) {
4066 /* Continue search in original block's parent */
4067 rc = __cil_resolve_name_with_parents(NODE(inherit->block), name, sym_index, datum);
4068 goto exit;
4069 }
4070 }
4071 break;
4072 case CIL_MACRO: {
4073 struct cil_macro *macro = node->data;
4074 symtab = ¯o->symtab[sym_index];
4075 rc = cil_symtab_get_datum(symtab, name, datum);
4076 }
4077 break;
4078 case CIL_CALL: {
4079 struct cil_call *call = node->data;
4080 rc = cil_resolve_name_call_args(call, name, sym_index, datum);
4081 if (rc != SEPOL_OK) {
4082 /* Continue search in macro's parent */
4083 rc = __cil_resolve_name_with_parents(NODE(call->macro)->parent, name, sym_index, datum);
4084 }
4085 }
4086 break;
4087 case CIL_IN:
4088 /* In block symtabs only exist before resolving the AST */
4089 case CIL_CONDBLOCK:
4090 /* Cond block symtabs only exist before resolving the AST */
4091 default:
4092 break;
4093 }
4094
4095 node = node->parent;
4096 }
4097
4098 exit:
4099 return rc;
4100 }
4101
__cil_resolve_name_helper(struct cil_db * db,struct cil_tree_node * node,char * name,enum cil_sym_index sym_index,struct cil_symtab_datum ** datum)4102 static int __cil_resolve_name_helper(struct cil_db *db, struct cil_tree_node *node, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum)
4103 {
4104 int rc = SEPOL_ERR;
4105
4106 rc = __cil_resolve_name_with_parents(node, name, sym_index, datum);
4107 if (rc != SEPOL_OK) {
4108 rc = __cil_resolve_name_with_root(db, name, sym_index, datum);
4109 }
4110 return rc;
4111 }
4112
cil_resolve_name(struct cil_tree_node * ast_node,char * name,enum cil_sym_index sym_index,void * extra_args,struct cil_symtab_datum ** datum)4113 int cil_resolve_name(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum)
4114 {
4115 int rc = SEPOL_ERR;
4116 struct cil_tree_node *node = NULL;
4117
4118 rc = cil_resolve_name_keep_aliases(ast_node, name, sym_index, extra_args, datum);
4119 if (rc != SEPOL_OK) {
4120 goto exit;
4121 }
4122
4123 /* If this datum is an alias, then return the actual node
4124 * This depends on aliases already being processed
4125 */
4126 node = NODE(*datum);
4127 if (node->flavor == CIL_TYPEALIAS || node->flavor == CIL_SENSALIAS
4128 || node->flavor == CIL_CATALIAS) {
4129 struct cil_alias *alias = (struct cil_alias *)(*datum);
4130 if (alias->actual) {
4131 *datum = alias->actual;
4132 }
4133 }
4134
4135 rc = SEPOL_OK;
4136
4137 exit:
4138 return rc;
4139 }
4140
cil_resolve_name_keep_aliases(struct cil_tree_node * ast_node,char * name,enum cil_sym_index sym_index,void * extra_args,struct cil_symtab_datum ** datum)4141 int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum)
4142 {
4143 int rc = SEPOL_ERR;
4144 struct cil_args_resolve *args = extra_args;
4145 struct cil_db *db = args->db;
4146 struct cil_tree_node *node = NULL;
4147
4148 if (name == NULL) {
4149 cil_log(CIL_ERR, "Invalid call to cil_resolve_name\n");
4150 goto exit;
4151 }
4152
4153 *datum = NULL;
4154
4155 if (strchr(name,'.') == NULL) {
4156 /* No '.' in name */
4157 rc = __cil_resolve_name_helper(db, ast_node->parent, name, sym_index, datum);
4158 if (rc != SEPOL_OK) {
4159 goto exit;
4160 }
4161 } else {
4162 char *sp = NULL;
4163 char *name_dup = cil_strdup(name);
4164 char *current = strtok_r(name_dup, ".", &sp);
4165 char *next = strtok_r(NULL, ".", &sp);
4166 symtab_t *symtab = NULL;
4167
4168 if (current == NULL) {
4169 /* Only dots */
4170 cil_tree_log(ast_node, CIL_ERR, "Invalid name %s", name);
4171 free(name_dup);
4172 goto exit;
4173 }
4174
4175 node = ast_node;
4176 if (*name == '.') {
4177 /* Leading '.' */
4178 symtab = &((struct cil_root *)db->ast->root->data)->symtab[CIL_SYM_BLOCKS];
4179 } else {
4180 rc = __cil_resolve_name_helper(db, node->parent, current, CIL_SYM_BLOCKS, datum);
4181 if (rc != SEPOL_OK) {
4182 free(name_dup);
4183 goto exit;
4184 }
4185 symtab = (*datum)->symtab;
4186 }
4187 /* Keep looking up blocks by name until only last part of name remains */
4188 while (next != NULL) {
4189 rc = cil_symtab_get_datum(symtab, current, datum);
4190 if (rc != SEPOL_OK) {
4191 free(name_dup);
4192 goto exit;
4193 }
4194 node = NODE(*datum);
4195 if (node->flavor == CIL_BLOCK) {
4196 symtab = &((struct cil_block*)node->data)->symtab[CIL_SYM_BLOCKS];
4197 } else {
4198 if (ast_node->flavor != CIL_IN) {
4199 cil_log(CIL_WARN, "Can only use %s name for name resolution in \"in\" blocks\n", cil_node_to_string(node));
4200 free(name_dup);
4201 rc = SEPOL_ERR;
4202 goto exit;
4203 }
4204 if (node->flavor == CIL_MACRO) {
4205 struct cil_macro *macro = node->data;
4206 symtab = ¯o->symtab[sym_index];
4207 } else {
4208 /* optional */
4209 symtab = (*datum)->symtab;
4210 }
4211 }
4212 current = next;
4213 next = strtok_r(NULL, ".", &sp);
4214 }
4215 symtab = &(symtab[sym_index]);
4216 rc = cil_symtab_get_datum(symtab, current, datum);
4217 free(name_dup);
4218 if (rc != SEPOL_OK) {
4219 goto exit;
4220 }
4221 }
4222
4223 rc = SEPOL_OK;
4224
4225 exit:
4226 if (rc != SEPOL_OK) {
4227 *datum = NULL;
4228 }
4229
4230 args->last_resolved_name = name;
4231
4232 return rc;
4233 }
4234