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