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