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