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