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 <assert.h>
33 #include <netinet/in.h>
34 
35 #include <sepol/policydb/policydb.h>
36 #include <sepol/policydb/polcaps.h>
37 #include <sepol/policydb/conditional.h>
38 #include <sepol/policydb/constraint.h>
39 #include <sepol/policydb/flask.h>
40 
41 #include "cil_internal.h"
42 #include "cil_flavor.h"
43 #include "cil_log.h"
44 #include "cil_mem.h"
45 #include "cil_tree.h"
46 #include "cil_binary.h"
47 #include "cil_symtab.h"
48 
49 /* There are 44000 filename_trans in current fedora policy. 1.33 times this is the recommended
50  * size of a hashtable. The next power of 2 of this is 2 ** 16.
51  */
52 #define FILENAME_TRANS_TABLE_SIZE 1 << 16
53 #define RANGE_TRANS_TABLE_SIZE 1 << 13
54 #define ROLE_TRANS_TABLE_SIZE 1 << 10
55 
56 struct cil_args_binary {
57 	const struct cil_db *db;
58 	policydb_t *pdb;
59 	struct cil_list *neverallows;
60 	int pass;
61 	hashtab_t filename_trans_table;
62 	hashtab_t range_trans_table;
63 	hashtab_t role_trans_table;
64 };
65 
66 struct cil_args_booleanif {
67 	const struct cil_db *db;
68 	policydb_t *pdb;
69 	cond_node_t *cond_node;
70 	enum cil_flavor cond_flavor;
71 	struct cil_list *neverallows;
72 	hashtab_t filename_trans_table;
73 };
74 
75 struct cil_neverallow {
76 	struct cil_tree_node *node;
77 	struct cil_list *rules;
78 };
79 
80 struct cil_neverallow_rule {
81 	struct cil_symtab_datum *src;
82 	struct cil_symtab_datum *tgt;
83 	uint32_t class;
84 	uint32_t perms;
85 };
86 
cil_neverallows_list_destroy(struct cil_list * neverallows)87 void cil_neverallows_list_destroy(struct cil_list *neverallows)
88 {
89 	struct cil_list_item *i;
90 	struct cil_list_item *j;
91 
92 	cil_list_for_each(i, neverallows) {
93 		struct cil_neverallow *neverallow = i->data;
94 		cil_list_for_each(j, neverallow->rules) {
95 			struct cil_neverallow_rule *rule = j->data;
96 			free(rule);
97 		}
98 		cil_list_destroy(&neverallow->rules, CIL_FALSE);
99 		free(neverallow);
100 	}
101 	cil_list_destroy(&neverallows, CIL_FALSE);
102 }
103 
__cil_get_sepol_user_datum(policydb_t * pdb,struct cil_symtab_datum * datum,user_datum_t ** sepol_user)104 static int __cil_get_sepol_user_datum(policydb_t *pdb, struct cil_symtab_datum *datum, user_datum_t **sepol_user)
105 {
106 	*sepol_user = hashtab_search(pdb->p_users.table, datum->fqn);
107 	if (*sepol_user == NULL) {
108 		cil_log(CIL_INFO, "Failed to find user %s in sepol hashtab\n", datum->fqn);
109 		return SEPOL_ERR;
110 	}
111 
112 	return SEPOL_OK;
113 }
114 
__cil_get_sepol_role_datum(policydb_t * pdb,struct cil_symtab_datum * datum,role_datum_t ** sepol_role)115 static int __cil_get_sepol_role_datum(policydb_t *pdb, struct cil_symtab_datum *datum, role_datum_t **sepol_role)
116 {
117 	*sepol_role = hashtab_search(pdb->p_roles.table, datum->fqn);
118 	if (*sepol_role == NULL) {
119 		cil_log(CIL_INFO, "Failed to find role %s in sepol hashtab\n", datum->fqn);
120 		return SEPOL_ERR;
121 	}
122 
123 	return SEPOL_OK;
124 }
125 
__cil_get_sepol_type_datum(policydb_t * pdb,struct cil_symtab_datum * datum,type_datum_t ** sepol_type)126 static int __cil_get_sepol_type_datum(policydb_t *pdb, struct cil_symtab_datum *datum, type_datum_t **sepol_type)
127 {
128 	*sepol_type = hashtab_search(pdb->p_types.table, datum->fqn);
129 	if (*sepol_type == NULL) {
130 		cil_log(CIL_INFO, "Failed to find type %s in sepol hashtab\n", datum->fqn);
131 		return SEPOL_ERR;
132 	}
133 
134 	return SEPOL_OK;
135 }
136 
__cil_get_sepol_class_datum(policydb_t * pdb,struct cil_symtab_datum * datum,class_datum_t ** sepol_class)137 static int __cil_get_sepol_class_datum(policydb_t *pdb, struct cil_symtab_datum *datum, class_datum_t **sepol_class)
138 {
139 	*sepol_class = hashtab_search(pdb->p_classes.table, datum->fqn);
140 	if (*sepol_class == NULL) {
141 		cil_log(CIL_INFO, "Failed to find class %s in sepol hashtab\n", datum->fqn);
142 		return SEPOL_ERR;
143 	}
144 
145 	return SEPOL_OK;
146 }
147 
__cil_get_sepol_cat_datum(policydb_t * pdb,struct cil_symtab_datum * datum,cat_datum_t ** sepol_cat)148 static int __cil_get_sepol_cat_datum(policydb_t *pdb, struct cil_symtab_datum *datum, cat_datum_t **sepol_cat)
149 {
150 	*sepol_cat = hashtab_search(pdb->p_cats.table, datum->fqn);
151 	if (*sepol_cat == NULL) {
152 		cil_log(CIL_INFO, "Failed to find category %s in sepol hashtab\n", datum->fqn);
153 		return SEPOL_ERR;
154 	}
155 
156 	return SEPOL_OK;
157 }
158 
__cil_get_sepol_level_datum(policydb_t * pdb,struct cil_symtab_datum * datum,level_datum_t ** sepol_level)159 static int __cil_get_sepol_level_datum(policydb_t *pdb, struct cil_symtab_datum *datum, level_datum_t **sepol_level)
160 {
161 	*sepol_level = hashtab_search(pdb->p_levels.table, datum->fqn);
162 	if (*sepol_level == NULL) {
163 		cil_log(CIL_INFO, "Failed to find level %s in sepol hashtab\n", datum->fqn);
164 		return SEPOL_ERR;
165 	}
166 
167 	return SEPOL_OK;
168 }
169 
__cil_expand_role(struct cil_symtab_datum * datum,ebitmap_t * new)170 static int __cil_expand_role(struct cil_symtab_datum *datum, ebitmap_t *new)
171 {
172 	struct cil_tree_node *node = datum->nodes->head->data;
173 
174 	if (node->flavor == CIL_ROLEATTRIBUTE) {
175 		struct cil_roleattribute *attr = (struct cil_roleattribute *)datum;
176 		if (ebitmap_cpy(new, attr->roles)) {
177 			cil_log(CIL_ERR, "Failed to copy role bits\n");
178 			goto exit;
179 		}
180 	} else {
181 		struct cil_role *role = (struct cil_role *)datum;
182 		ebitmap_init(new);
183 		if (ebitmap_set_bit(new, role->value, 1)) {
184 			cil_log(CIL_ERR, "Failed to set role bit\n");
185 			ebitmap_destroy(new);
186 			goto exit;
187 		}
188 	}
189 
190 	return SEPOL_OK;
191 
192 exit:
193 	return SEPOL_ERR;
194 }
195 
__cil_expand_type(struct cil_symtab_datum * datum,ebitmap_t * new)196 static int __cil_expand_type(struct cil_symtab_datum *datum, ebitmap_t *new)
197 {
198 	struct cil_tree_node *node = datum->nodes->head->data;
199 
200 	if (node->flavor == CIL_TYPEATTRIBUTE) {
201 		struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
202 		if (ebitmap_cpy(new, attr->types)) {
203 			cil_log(CIL_ERR, "Failed to copy type bits\n");
204 			goto exit;
205 		}
206 	} else {
207 		struct cil_type *type = (struct cil_type *)datum;
208 		ebitmap_init(new);
209 		if (ebitmap_set_bit(new, type->value, 1)) {
210 			cil_log(CIL_ERR, "Failed to set type bit\n");
211 			ebitmap_destroy(new);
212 			goto exit;
213 		}
214 	}
215 
216 	return SEPOL_OK;
217 
218 exit:
219 	return SEPOL_ERR;
220 }
221 
cil_add_ocontext(ocontext_t ** head,ocontext_t ** tail)222 static ocontext_t *cil_add_ocontext(ocontext_t **head, ocontext_t **tail)
223 {
224 	ocontext_t *new = cil_malloc(sizeof(ocontext_t));
225 	memset(new, 0, sizeof(ocontext_t));
226 	if (*tail) {
227 		(*tail)->next = new;
228 	} else {
229 		*head = new;
230 	}
231 	*tail = new;
232 
233 	return new;
234 }
235 
__add_classes_from_classperms_list(struct cil_list * classperms,struct cil_list * class_list)236 static void __add_classes_from_classperms_list(struct cil_list *classperms, struct cil_list *class_list)
237 {
238 	struct cil_list_item *curr;
239 
240 	cil_list_for_each(curr, classperms) {
241 		if (curr->flavor == CIL_CLASSPERMS) {
242 			struct cil_classperms *cp = curr->data;
243 			if (FLAVOR(cp->class) == CIL_CLASS) {
244 				cil_list_append(class_list, CIL_CLASS, cp->class);
245 			} else { /* MAP */
246 				struct cil_list_item *i = NULL;
247 				cil_list_for_each(i, cp->perms) {
248 					struct cil_perm *cmp = i->data;
249 					__add_classes_from_classperms_list(cmp->classperms, class_list);
250 				}
251 			}
252 		} else { /* SET */
253 			struct cil_classperms_set *cp_set = curr->data;
254 			struct cil_classpermission *cp = cp_set->set;
255 			__add_classes_from_classperms_list(cp->classperms, class_list);
256 		}
257 	}
258 }
259 
__add_classes_from_map_perms(hashtab_key_t k,hashtab_datum_t d,void * args)260 static int __add_classes_from_map_perms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
261 {
262 	struct cil_list *class_list = args;
263 	struct cil_perm *cmp = (struct cil_perm *)d;
264 
265 	__add_classes_from_classperms_list(cmp->classperms, class_list);
266 
267 	return SEPOL_OK;
268 }
269 
cil_expand_class(struct cil_class * class)270 static struct cil_list *cil_expand_class(struct cil_class *class)
271 {
272 	struct cil_list *class_list;
273 
274 	cil_list_init(&class_list, CIL_CLASS);
275 
276 	if (FLAVOR(class) == CIL_CLASS) {
277 		cil_list_append(class_list, CIL_CLASS, class);
278 	} else { /* MAP */
279 		cil_symtab_map(&class->perms, __add_classes_from_map_perms, class_list);
280 	}
281 
282 	return class_list;
283 }
284 
cil_common_to_policydb(policydb_t * pdb,struct cil_class * cil_common,common_datum_t ** common_out)285 int cil_common_to_policydb(policydb_t *pdb, struct cil_class *cil_common, common_datum_t **common_out)
286 {
287 	int rc = SEPOL_ERR;
288 	uint32_t value = 0;
289 	char *key = NULL;
290 	struct cil_tree_node *node = cil_common->datum.nodes->head->data;
291 	struct cil_tree_node *cil_perm = node->cl_head;
292 	common_datum_t *sepol_common = cil_malloc(sizeof(*sepol_common));
293 	memset(sepol_common, 0, sizeof(common_datum_t));
294 
295 	key = cil_strdup(cil_common->datum.fqn);
296 	rc = symtab_insert(pdb, SYM_COMMONS, key, sepol_common, SCOPE_DECL, 0, &value);
297 	if (rc != SEPOL_OK) {
298 		free(sepol_common);
299 		goto exit;
300 	}
301 	sepol_common->s.value = value;
302 
303 	rc = symtab_init(&sepol_common->permissions, PERM_SYMTAB_SIZE);
304 	if (rc != SEPOL_OK) {
305 		goto exit;
306 	}
307 
308 	while (cil_perm != NULL) {
309 		struct cil_perm *curr = cil_perm->data;
310 		perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm));
311 		memset(sepol_perm, 0, sizeof(perm_datum_t));
312 
313 		key = cil_strdup(curr->datum.fqn);
314 		rc = hashtab_insert(sepol_common->permissions.table, key, sepol_perm);
315 		if (rc != SEPOL_OK) {
316 			free(sepol_perm);
317 			goto exit;
318 		}
319 		sepol_perm->s.value = sepol_common->permissions.nprim + 1;
320 		sepol_common->permissions.nprim++;
321 		cil_perm = cil_perm->next;
322 	}
323 
324 	*common_out = sepol_common;
325 
326 	return SEPOL_OK;
327 
328 exit:
329 	free(key);
330 	return rc;
331 }
332 
cil_classorder_to_policydb(policydb_t * pdb,const struct cil_db * db)333 int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
334 {
335 	int rc = SEPOL_ERR;
336 	struct cil_list_item *curr_class;
337 
338 	cil_list_for_each(curr_class, db->classorder) {
339 		struct cil_class *cil_class = curr_class->data;
340 		uint32_t value = 0;
341 		char *key = NULL;
342 		struct cil_tree_node *node = cil_class->datum.nodes->head->data;
343 		struct cil_tree_node *cil_perm = node->cl_head;
344 		common_datum_t *sepol_common = NULL;
345 		class_datum_t *sepol_class = cil_malloc(sizeof(*sepol_class));
346 		memset(sepol_class, 0, sizeof(class_datum_t));
347 
348 		key = cil_strdup(cil_class->datum.fqn);
349 		rc = symtab_insert(pdb, SYM_CLASSES, key, sepol_class, SCOPE_DECL, 0, &value);
350 		if (rc != SEPOL_OK) {
351 			free(sepol_class);
352 			free(key);
353 			goto exit;
354 		}
355 		sepol_class->s.value = value;
356 
357 		rc = symtab_init(&sepol_class->permissions, PERM_SYMTAB_SIZE);
358 		if (rc != SEPOL_OK) {
359 			goto exit;
360 		}
361 
362 		if (cil_class->common != NULL) {
363 			struct cil_class *cil_common = cil_class->common;
364 
365 			key = cil_class->common->datum.fqn;
366 			sepol_common = hashtab_search(pdb->p_commons.table, key);
367 			if (sepol_common == NULL) {
368 				rc = cil_common_to_policydb(pdb, cil_common, &sepol_common);
369 				if (rc != SEPOL_OK) {
370 					goto exit;
371 				}
372 			}
373 			sepol_class->comdatum = sepol_common;
374 			sepol_class->comkey = cil_strdup(key);
375 			sepol_class->permissions.nprim += sepol_common->permissions.nprim;
376 		}
377 
378 		while (cil_perm != NULL) {
379 			struct cil_perm *curr_perm = cil_perm->data;
380 			perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm));
381 			memset(sepol_perm, 0, sizeof(perm_datum_t));
382 
383 			key = cil_strdup(curr_perm->datum.fqn);
384 			rc = hashtab_insert(sepol_class->permissions.table, key, sepol_perm);
385 			if (rc != SEPOL_OK) {
386 				free(sepol_perm);
387 				free(key);
388 				goto exit;
389 			}
390 			sepol_perm->s.value = sepol_class->permissions.nprim + 1;
391 			sepol_class->permissions.nprim++;
392 			cil_perm = cil_perm->next;
393 		}
394 	}
395 
396 	return SEPOL_OK;
397 
398 exit:
399 	return rc;
400 }
401 
cil_role_to_policydb(policydb_t * pdb,struct cil_role * cil_role)402 int cil_role_to_policydb(policydb_t *pdb, struct cil_role *cil_role)
403 {
404 	int rc = SEPOL_ERR;
405 	uint32_t value = 0;
406 	char *key = NULL;
407 	role_datum_t *sepol_role = cil_malloc(sizeof(*sepol_role));
408 	role_datum_init(sepol_role);
409 
410 	if (cil_role->datum.fqn == CIL_KEY_OBJECT_R) {
411 		/* special case
412 		 * object_r defaults to 1 in libsepol symtab */
413 		rc = SEPOL_OK;
414 		goto exit;
415 	}
416 
417 	key = cil_strdup(cil_role->datum.fqn);
418 	rc = symtab_insert(pdb, SYM_ROLES, (hashtab_key_t)key, sepol_role, SCOPE_DECL, 0, &value);
419 	if (rc != SEPOL_OK) {
420 		goto exit;
421 	}
422 	if (ebitmap_set_bit(&sepol_role->dominates, value - 1, 1)) {
423 		cil_log(CIL_INFO, "Failed to set dominates bit for role\n");
424 		rc = SEPOL_ERR;
425 		goto exit;
426 	}
427 	sepol_role->s.value = value;
428 	return SEPOL_OK;
429 
430 exit:
431 	free(key);
432 	role_datum_destroy(sepol_role);
433 	free(sepol_role);
434 	return rc;
435 }
436 
cil_role_bounds_to_policydb(policydb_t * pdb,struct cil_role * cil_role)437 int cil_role_bounds_to_policydb(policydb_t *pdb, struct cil_role *cil_role)
438 {
439 	int rc = SEPOL_ERR;
440 	role_datum_t *sepol_role = NULL;
441 	role_datum_t *sepol_parent = NULL;
442 
443 	if (cil_role->bounds) {
444 		rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_role), &sepol_role);
445 		if (rc != SEPOL_OK) goto exit;
446 
447 		rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_role->bounds), &sepol_parent);
448 		if (rc != SEPOL_OK) goto exit;
449 
450 		sepol_role->bounds = sepol_parent->s.value;
451 	}
452 
453 	return SEPOL_OK;
454 
455 exit:
456 	cil_log(CIL_ERR, "Failed to insert role bounds for role %s\n", cil_role->datum.fqn);
457 	return SEPOL_ERR;
458 }
459 
cil_roletype_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_role * role)460 int cil_roletype_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_role *role)
461 {
462 	int rc = SEPOL_ERR;
463 
464 	if (role->types) {
465 		role_datum_t *sepol_role = NULL;
466 		type_datum_t *sepol_type = NULL;
467 		ebitmap_node_t *tnode;
468 		unsigned int i;
469 
470 		rc = __cil_get_sepol_role_datum(pdb, DATUM(role), &sepol_role);
471 		if (rc != SEPOL_OK) goto exit;
472 
473 		ebitmap_for_each_bit(role->types, tnode, i) {
474 			if (!ebitmap_get_bit(role->types, i)) continue;
475 
476 			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type);
477 			if (rc != SEPOL_OK) goto exit;
478 
479 			if (ebitmap_set_bit(&sepol_role->types.types, sepol_type->s.value - 1, 1)) {
480 				cil_log(CIL_INFO, "Failed to set type bit for role\n");
481 				rc = SEPOL_ERR;
482 				goto exit;
483 			}
484 		}
485 	}
486 
487 	return SEPOL_OK;
488 
489 exit:
490 	return rc;
491 }
492 
cil_type_to_policydb(policydb_t * pdb,struct cil_type * cil_type)493 int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type)
494 {
495 	int rc = SEPOL_ERR;
496 	uint32_t value = 0;
497 	char *key = NULL;
498 	type_datum_t *sepol_type = cil_malloc(sizeof(*sepol_type));
499 	type_datum_init(sepol_type);
500 
501 	sepol_type->flavor = TYPE_TYPE;
502 
503 	key = cil_strdup(cil_type->datum.fqn);
504 	rc = symtab_insert(pdb, SYM_TYPES, key, sepol_type, SCOPE_DECL, 0, &value);
505 	if (rc != SEPOL_OK) {
506 		goto exit;
507 	}
508 	sepol_type->s.value = value;
509 	sepol_type->primary = 1;
510 
511 	return SEPOL_OK;
512 
513 exit:
514 	free(key);
515 	type_datum_destroy(sepol_type);
516 	free(sepol_type);
517 	return rc;
518 }
519 
cil_type_bounds_to_policydb(policydb_t * pdb,struct cil_type * cil_type)520 int cil_type_bounds_to_policydb(policydb_t *pdb, struct cil_type *cil_type)
521 {
522 	int rc = SEPOL_ERR;
523 	type_datum_t *sepol_type = NULL;
524 	type_datum_t *sepol_parent = NULL;
525 
526 	if (cil_type->bounds) {
527 		rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_type), &sepol_type);
528 		if (rc != SEPOL_OK) goto exit;
529 
530 		rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_type->bounds), &sepol_parent);
531 		if (rc != SEPOL_OK) goto exit;
532 
533 		sepol_type->bounds = sepol_parent->s.value;
534 	}
535 
536 	return SEPOL_OK;
537 
538 exit:
539 	cil_log(CIL_ERR, "Failed to insert type bounds for type %s\n", cil_type->datum.fqn);
540 	return SEPOL_ERR;
541 }
542 
cil_typealias_to_policydb(policydb_t * pdb,struct cil_alias * cil_alias)543 int cil_typealias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias)
544 {
545 	int rc = SEPOL_ERR;
546 	char *key = NULL;
547 	type_datum_t *sepol_type = NULL;
548 	type_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_alias));
549 	type_datum_init(sepol_alias);
550 
551 	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_alias->actual), &sepol_type);
552 	if (rc != SEPOL_OK) goto exit;
553 
554 	sepol_alias->flavor = TYPE_TYPE;
555 
556 	key = cil_strdup(cil_alias->datum.fqn);
557 	rc = symtab_insert(pdb, SYM_TYPES, key, sepol_alias, SCOPE_DECL, 0, NULL);
558 	if (rc != SEPOL_OK) {
559 		goto exit;
560 	}
561 	sepol_alias->s.value = sepol_type->s.value;
562 	sepol_alias->primary = 0;
563 
564 	return SEPOL_OK;
565 
566 exit:
567 	free(key);
568 	type_datum_destroy(sepol_alias);
569 	free(sepol_alias);
570 	return rc;
571 }
572 
cil_typepermissive_to_policydb(policydb_t * pdb,struct cil_typepermissive * cil_typeperm)573 int cil_typepermissive_to_policydb(policydb_t *pdb, struct cil_typepermissive *cil_typeperm)
574 {
575 	int rc = SEPOL_ERR;
576 	type_datum_t *sepol_type = NULL;
577 
578 	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_typeperm->type), &sepol_type);
579 	if (rc != SEPOL_OK) goto exit;
580 
581 	if (ebitmap_set_bit(&pdb->permissive_map, sepol_type->s.value, 1)) {
582 		goto exit;
583 	}
584 
585 	return SEPOL_OK;
586 
587 exit:
588 	type_datum_destroy(sepol_type);
589 	free(sepol_type);
590 	return rc;
591 
592 }
593 
cil_typeattribute_to_policydb(policydb_t * pdb,struct cil_typeattribute * cil_attr)594 int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr)
595 {
596 	int rc = SEPOL_ERR;
597 	uint32_t value = 0;
598 	char *key = NULL;
599 	type_datum_t *sepol_attr = NULL;
600 
601 	if (cil_attr->used == CIL_FALSE) {
602 		return SEPOL_OK;
603 	}
604 
605 	sepol_attr = cil_malloc(sizeof(*sepol_attr));
606 	type_datum_init(sepol_attr);
607 
608 	sepol_attr->flavor = TYPE_ATTRIB;
609 
610 	key = cil_strdup(cil_attr->datum.fqn);
611 	rc = symtab_insert(pdb, SYM_TYPES, key, sepol_attr, SCOPE_DECL, 0, &value);
612 	if (rc != SEPOL_OK) {
613 		goto exit;
614 	}
615 	sepol_attr->s.value = value;
616 	sepol_attr->primary = 1;
617 
618 	return SEPOL_OK;
619 
620 exit:
621 	type_datum_destroy(sepol_attr);
622 	free(sepol_attr);
623 	return rc;
624 }
625 
__cil_typeattr_bitmap_init(policydb_t * pdb)626 int __cil_typeattr_bitmap_init(policydb_t *pdb)
627 {
628 	int rc = SEPOL_ERR;
629 
630 	pdb->type_attr_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t));
631 
632 	uint32_t i = 0;
633 	for (i = 0; i < pdb->p_types.nprim; i++) {
634 		ebitmap_init(&pdb->type_attr_map[i]);
635 		if (ebitmap_set_bit(&pdb->type_attr_map[i], i, 1)) {
636 			rc = SEPOL_ERR;
637 			goto exit;
638 		}
639 	}
640 
641 	return SEPOL_OK;
642 
643 exit:
644 	return rc;
645 }
646 
cil_typeattribute_to_bitmap(policydb_t * pdb,const struct cil_db * db,struct cil_typeattribute * cil_attr)647 int cil_typeattribute_to_bitmap(policydb_t *pdb, const struct cil_db *db, struct cil_typeattribute *cil_attr)
648 {
649 	int rc = SEPOL_ERR;
650 	uint32_t value = 0;
651 	type_datum_t *sepol_type = NULL;
652 	ebitmap_node_t *tnode;
653 	unsigned int i;
654 
655 	if (cil_attr->used == CIL_FALSE) {
656 		return SEPOL_OK;
657 	}
658 
659 	if (pdb->type_attr_map == NULL) {
660 		rc = __cil_typeattr_bitmap_init(pdb);
661 		if (rc != SEPOL_OK) {
662 			goto exit;
663 		}
664 	}
665 
666 	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_attr), &sepol_type);
667 	if (rc != SEPOL_OK) goto exit;
668 
669 	value = sepol_type->s.value;
670 
671 	ebitmap_for_each_bit(cil_attr->types, tnode, i) {
672 		if (!ebitmap_get_bit(cil_attr->types, i)) continue;
673 
674 		rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type);
675 		if (rc != SEPOL_OK) goto exit;
676 
677 		ebitmap_set_bit(&pdb->type_attr_map[sepol_type->s.value - 1], value - 1, 1);
678 	}
679 
680 	rc = SEPOL_OK;
681 exit:
682 	return rc;
683 }
684 
cil_policycap_to_policydb(policydb_t * pdb,struct cil_policycap * cil_polcap)685 int cil_policycap_to_policydb(policydb_t *pdb, struct cil_policycap *cil_polcap)
686 {
687 	int rc = SEPOL_ERR;
688 	int capnum;
689 
690 	capnum = sepol_polcap_getnum(cil_polcap->datum.fqn);
691 	if (capnum == -1) {
692 		goto exit;
693 	}
694 
695 	if (ebitmap_set_bit(&pdb->policycaps, capnum, 1)) {
696 		goto exit;
697 	}
698 
699 	return SEPOL_OK;
700 
701 exit:
702 	return rc;
703 }
704 
cil_user_to_policydb(policydb_t * pdb,struct cil_user * cil_user)705 int cil_user_to_policydb(policydb_t *pdb, struct cil_user *cil_user)
706 {
707 	int rc = SEPOL_ERR;
708 	uint32_t value = 0;
709 	char *key = NULL;
710 	user_datum_t *sepol_user = cil_malloc(sizeof(*sepol_user));
711 	user_datum_init(sepol_user);
712 
713 	key = cil_strdup(cil_user->datum.fqn);
714 	rc = symtab_insert(pdb, SYM_USERS, key, sepol_user, SCOPE_DECL, 0, &value);
715 	if (rc != SEPOL_OK) {
716 		goto exit;
717 	}
718 	sepol_user->s.value = value;
719 
720 	return SEPOL_OK;
721 
722 exit:
723 	free(key);
724 	user_datum_destroy(sepol_user);
725 	free(sepol_user);
726 	return rc;
727 }
728 
cil_user_bounds_to_policydb(policydb_t * pdb,struct cil_user * cil_user)729 int cil_user_bounds_to_policydb(policydb_t *pdb, struct cil_user *cil_user)
730 {
731 	int rc = SEPOL_ERR;
732 	user_datum_t *sepol_user = NULL;
733 	user_datum_t *sepol_parent = NULL;
734 
735 	if (cil_user->bounds) {
736 		rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user);
737 		if (rc != SEPOL_OK) goto exit;
738 
739 		rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user->bounds), &sepol_parent);
740 		if (rc != SEPOL_OK) goto exit;
741 
742 		sepol_user->bounds = sepol_parent->s.value;
743 	}
744 
745 	return SEPOL_OK;
746 
747 exit:
748 	cil_log(CIL_ERR, "Failed to insert user bounds for user %s\n", cil_user->datum.fqn);
749 	return SEPOL_ERR;
750 }
751 
cil_userrole_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_userrole * userrole)752 int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_userrole *userrole)
753 {
754 	int rc = SEPOL_ERR;
755 	user_datum_t *sepol_user = NULL;
756 	role_datum_t *sepol_role = NULL;
757 	ebitmap_t role_bitmap;
758 	ebitmap_node_t *rnode;
759 	unsigned int i;
760 
761 	rc = __cil_get_sepol_user_datum(pdb, DATUM(userrole->user), &sepol_user);
762 	if (rc != SEPOL_OK) goto exit;
763 
764 	rc = __cil_expand_role(userrole->role, &role_bitmap);
765 	if (rc != SEPOL_OK) goto exit;
766 
767 	ebitmap_for_each_bit(&role_bitmap, rnode, i) {
768 		if (!ebitmap_get_bit(&role_bitmap, i)) continue;
769 
770 		rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role);
771 		if (rc != SEPOL_OK) goto exit;
772 
773 		if (sepol_role->s.value == 1) {
774 			// role is object_r, ignore it since it is implicitly associated
775 			// with all users
776 			continue;
777 		}
778 
779 		if (ebitmap_set_bit(&sepol_user->roles.roles, sepol_role->s.value - 1, 1)) {
780 			cil_log(CIL_INFO, "Failed to set role bit for user\n");
781 			goto exit;
782 		}
783 	}
784 
785 	rc = SEPOL_OK;
786 
787 exit:
788 	ebitmap_destroy(&role_bitmap);
789 	return rc;
790 }
791 
cil_bool_to_policydb(policydb_t * pdb,struct cil_bool * cil_bool)792 int cil_bool_to_policydb(policydb_t *pdb, struct cil_bool *cil_bool)
793 {
794 	int rc = SEPOL_ERR;
795 	uint32_t value = 0;
796 	char *key = NULL;
797 	cond_bool_datum_t *sepol_bool = cil_malloc(sizeof(*sepol_bool));
798 	memset(sepol_bool, 0, sizeof(cond_bool_datum_t));
799 
800 	key = cil_strdup(cil_bool->datum.fqn);
801 	rc = symtab_insert(pdb, SYM_BOOLS, key, sepol_bool, SCOPE_DECL, 0, &value);
802 	if (rc != SEPOL_OK) {
803 		goto exit;
804 	}
805 	sepol_bool->s.value = value;
806 	sepol_bool->state = cil_bool->value;
807 
808 	return SEPOL_OK;
809 
810 exit:
811 	free(key);
812 	free(sepol_bool);
813 	return rc;
814 }
815 
cil_catorder_to_policydb(policydb_t * pdb,const struct cil_db * db)816 int cil_catorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
817 {
818 	int rc = SEPOL_ERR;
819 	uint32_t value = 0;
820 	char *key = NULL;
821 	struct cil_list_item *curr_cat;
822 	struct cil_cat *cil_cat = NULL;
823 	cat_datum_t *sepol_cat = NULL;
824 
825 	cil_list_for_each(curr_cat, db->catorder) {
826 		cil_cat = curr_cat->data;
827 		sepol_cat = cil_malloc(sizeof(*sepol_cat));
828 		cat_datum_init(sepol_cat);
829 
830 		key = cil_strdup(cil_cat->datum.fqn);
831 		rc = symtab_insert(pdb, SYM_CATS, key, sepol_cat, SCOPE_DECL, 0, &value);
832 		if (rc != SEPOL_OK) {
833 			goto exit;
834 		}
835 		sepol_cat->s.value = value;
836 	}
837 
838 	return SEPOL_OK;
839 
840 exit:
841 	free(key);
842 	cat_datum_destroy(sepol_cat);
843 	free(sepol_cat);
844 	return rc;
845 }
846 
cil_catalias_to_policydb(policydb_t * pdb,struct cil_alias * cil_alias)847 int cil_catalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias)
848 {
849 	int rc = SEPOL_ERR;
850 	char *key = NULL;
851 	cat_datum_t *sepol_cat;
852 	cat_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_cat));
853 	cat_datum_init(sepol_alias);
854 
855 	rc = __cil_get_sepol_cat_datum(pdb, DATUM(cil_alias->actual), &sepol_cat);
856 	if (rc != SEPOL_OK) goto exit;
857 
858 	key = cil_strdup(cil_alias->datum.fqn);
859 	rc = symtab_insert(pdb, SYM_CATS, key, sepol_alias, SCOPE_DECL, 0, NULL);
860 	if (rc != SEPOL_OK) {
861 		free(key);
862 		goto exit;
863 	}
864 	sepol_alias->s.value = sepol_cat->s.value;
865 	sepol_alias->isalias = 1;
866 
867 	return SEPOL_OK;
868 
869 exit:
870 	free(key);
871 	cat_datum_destroy(sepol_alias);
872 	free(sepol_alias);
873 	return rc;
874 }
875 
cil_sensitivityorder_to_policydb(policydb_t * pdb,const struct cil_db * db)876 int cil_sensitivityorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
877 {
878 	int rc = SEPOL_ERR;
879 	uint32_t value = 0;
880 	char *key = NULL;
881 	struct cil_list_item *curr;
882 	struct cil_sens *cil_sens = NULL;
883 	level_datum_t *sepol_level = NULL;
884 	mls_level_t *mls_level = NULL;
885 
886 	cil_list_for_each(curr, db->sensitivityorder) {
887 		cil_sens = curr->data;
888 		sepol_level = cil_malloc(sizeof(*sepol_level));
889 		mls_level = cil_malloc(sizeof(*mls_level));
890 		level_datum_init(sepol_level);
891 		mls_level_init(mls_level);
892 
893 		key = cil_strdup(cil_sens->datum.fqn);
894 		rc = symtab_insert(pdb, SYM_LEVELS, key, sepol_level, SCOPE_DECL, 0, &value);
895 		if (rc != SEPOL_OK) {
896 			goto exit;
897 		}
898 		mls_level->sens = value;
899 		sepol_level->level = mls_level;
900 	}
901 
902 	return SEPOL_OK;
903 
904 exit:
905 	level_datum_destroy(sepol_level);
906 	mls_level_destroy(mls_level);
907 	free(sepol_level);
908 	free(mls_level);
909 	free(key);
910 	return rc;
911 }
912 
cil_sensalias_to_policydb(policydb_t * pdb,struct cil_alias * cil_alias)913 int cil_sensalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias)
914 {
915 	int rc = SEPOL_ERR;
916 	char *key = NULL;
917 	mls_level_t *mls_level = NULL;
918 	level_datum_t *sepol_level = NULL;
919 	level_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_alias));
920 	level_datum_init(sepol_alias);
921 
922 	rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_alias->actual), &sepol_level);
923 	if (rc != SEPOL_OK) goto exit;
924 
925 	key = cil_strdup(cil_alias->datum.fqn);
926 	rc = symtab_insert(pdb, SYM_LEVELS, key, sepol_alias, SCOPE_DECL, 0, NULL);
927 	if (rc != SEPOL_OK) {
928 		goto exit;
929 	}
930 
931 	mls_level = cil_malloc(sizeof(*mls_level));
932 	mls_level_init(mls_level);
933 
934 	rc = mls_level_cpy(mls_level, sepol_level->level);
935 	if (rc != SEPOL_OK) {
936 		goto exit;
937 	}
938 	sepol_alias->level = mls_level;
939 	sepol_alias->defined = 1;
940 	sepol_alias->isalias = 1;
941 
942 	return SEPOL_OK;
943 
944 exit:
945 	level_datum_destroy(sepol_alias);
946 	free(sepol_level);
947 	free(key);
948 	return rc;
949 }
950 
__cil_cond_insert_rule(avtab_t * avtab,avtab_key_t * avtab_key,avtab_datum_t * avtab_datum,cond_node_t * cond_node,enum cil_flavor cond_flavor)951 int __cil_cond_insert_rule(avtab_t *avtab, avtab_key_t *avtab_key, avtab_datum_t *avtab_datum, cond_node_t *cond_node, enum cil_flavor cond_flavor)
952 {
953 	int rc = SEPOL_OK;
954 	avtab_ptr_t avtab_ptr = NULL;
955 	cond_av_list_t *cond_list = NULL;
956 
957 	avtab_ptr = avtab_insert_nonunique(avtab, avtab_key, avtab_datum);
958 	if (!avtab_ptr) {
959 		rc = SEPOL_ERR;
960 		goto exit;
961 	}
962 
963 	// parse_context needs to be non-NULL for conditional rules to be
964 	// written to the binary. it is normally used for finding duplicates,
965 	// but cil checks that earlier, so we don't use it. it just needs to be
966 	// set
967 	avtab_ptr->parse_context = (void*)1;
968 
969 	cond_list = cil_malloc(sizeof(cond_av_list_t));
970 	memset(cond_list, 0, sizeof(cond_av_list_t));
971 
972 	cond_list->node = avtab_ptr;
973 
974 	if (cond_flavor == CIL_CONDTRUE) {
975       cond_list->next = cond_node->true_list;
976       cond_node->true_list = cond_list;
977 	} else {
978       cond_list->next = cond_node->false_list;
979       cond_node->false_list = cond_list;
980 	}
981 
982 exit:
983 	return rc;
984 }
985 
cil_cond_av_list_search(avtab_key_t * key,cond_av_list_t * cond_list)986 avtab_datum_t *cil_cond_av_list_search(avtab_key_t *key, cond_av_list_t *cond_list)
987 {
988 	cond_av_list_t *cur_av;
989 
990 	for (cur_av = cond_list; cur_av != NULL; cur_av = cur_av->next) {
991 		if (cur_av->node->key.source_type == key->source_type &&
992 		    cur_av->node->key.target_type == key->target_type &&
993 		    cur_av->node->key.target_class == key->target_class &&
994 			(cur_av->node->key.specified & key->specified))
995 
996 			return &cur_av->node->datum;
997 
998 	}
999 	return NULL;
1000 }
1001 
__cil_insert_type_rule(policydb_t * pdb,uint32_t kind,uint32_t src,uint32_t tgt,uint32_t obj,uint32_t res,cond_node_t * cond_node,enum cil_flavor cond_flavor)1002 int __cil_insert_type_rule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t res, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1003 {
1004 	int rc = SEPOL_OK;
1005 	avtab_key_t avtab_key;
1006 	avtab_datum_t avtab_datum;
1007 	avtab_ptr_t existing;
1008 
1009 	avtab_key.source_type = src;
1010 	avtab_key.target_type = tgt;
1011 	avtab_key.target_class = obj;
1012 
1013 	switch (kind) {
1014 	case CIL_TYPE_TRANSITION:
1015 		avtab_key.specified = AVTAB_TRANSITION;
1016 		break;
1017 	case CIL_TYPE_CHANGE:
1018 		avtab_key.specified = AVTAB_CHANGE;
1019 		break;
1020 	case CIL_TYPE_MEMBER:
1021 		avtab_key.specified = AVTAB_MEMBER;
1022 		break;
1023 	default:
1024 		rc = SEPOL_ERR;
1025 		goto exit;
1026 	}
1027 
1028 	avtab_datum.data = res;
1029 
1030 	existing = avtab_search_node(&pdb->te_avtab, &avtab_key);
1031 	if (existing) {
1032 		/* Don't add duplicate type rule and warn if they conflict.
1033 		 * A warning should have been previously given if there is a
1034 		 * non-duplicate rule using the same key.
1035 		 */
1036 		if (existing->datum.data != res) {
1037 			cil_log(CIL_ERR, "Conflicting type rules\n");
1038 			rc = SEPOL_ERR;
1039 		}
1040 		goto exit;
1041 	}
1042 
1043 	if (!cond_node) {
1044 		rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum);
1045 	} else {
1046 		existing = avtab_search_node(&pdb->te_cond_avtab, &avtab_key);
1047 		if (existing) {
1048 			cond_av_list_t *this_list;
1049 			cond_av_list_t *other_list;
1050 			avtab_datum_t *search_datum;
1051 
1052 			if (cond_flavor == CIL_CONDTRUE) {
1053 				this_list = cond_node->true_list;
1054 				other_list = cond_node->false_list;
1055 			} else {
1056 				this_list = cond_node->false_list;
1057 				other_list = cond_node->true_list;
1058 			}
1059 
1060 			search_datum = cil_cond_av_list_search(&avtab_key, other_list);
1061 			if (search_datum == NULL) {
1062 				if (existing->datum.data != res) {
1063 					cil_log(CIL_ERR, "Conflicting type rules\n");
1064 					rc = SEPOL_ERR;
1065 					goto exit;
1066 				}
1067 
1068 				search_datum = cil_cond_av_list_search(&avtab_key, this_list);
1069 				if (search_datum) {
1070 					goto exit;
1071 				}
1072 			}
1073 		}
1074 		rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor);
1075 	}
1076 
1077 exit:
1078 	return rc;
1079 }
1080 
__cil_type_rule_to_avtab(policydb_t * pdb,const struct cil_db * db,struct cil_type_rule * cil_rule,cond_node_t * cond_node,enum cil_flavor cond_flavor)1081 int __cil_type_rule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_type_rule *cil_rule, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1082 {
1083 	int rc = SEPOL_ERR;
1084 	uint16_t kind = cil_rule->rule_kind;
1085 	type_datum_t *sepol_src = NULL;
1086 	type_datum_t *sepol_tgt = NULL;
1087 	class_datum_t *sepol_obj = NULL;
1088 	struct cil_list *class_list;
1089 	type_datum_t *sepol_result = NULL;
1090 	ebitmap_t src_bitmap, tgt_bitmap;
1091 	ebitmap_node_t *node1, *node2;
1092 	unsigned int i, j;
1093 	struct cil_list_item *c;
1094 
1095 	rc = __cil_expand_type(cil_rule->src, &src_bitmap);
1096 	if (rc != SEPOL_OK) goto exit;
1097 
1098 	rc = __cil_expand_type(cil_rule->tgt, &tgt_bitmap);
1099 	if (rc != SEPOL_OK) goto exit;
1100 
1101 	class_list = cil_expand_class(cil_rule->obj);
1102 
1103 	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_rule->result), &sepol_result);
1104 	if (rc != SEPOL_OK) goto exit;
1105 
1106 	ebitmap_for_each_bit(&src_bitmap, node1, i) {
1107 		if (!ebitmap_get_bit(&src_bitmap, i)) continue;
1108 
1109 		rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src);
1110 		if (rc != SEPOL_OK) goto exit;
1111 
1112 		ebitmap_for_each_bit(&tgt_bitmap, node2, j) {
1113 			if (!ebitmap_get_bit(&tgt_bitmap, j)) continue;
1114 
1115 			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
1116 			if (rc != SEPOL_OK) goto exit;
1117 
1118 			cil_list_for_each(c, class_list) {
1119 				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
1120 				if (rc != SEPOL_OK) goto exit;
1121 
1122 				rc = __cil_insert_type_rule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, sepol_result->s.value, cond_node, cond_flavor);
1123 				if (rc != SEPOL_OK) goto exit;
1124 			}
1125 		}
1126 	}
1127 
1128 	rc = SEPOL_OK;
1129 
1130 exit:
1131 	ebitmap_destroy(&src_bitmap);
1132 	ebitmap_destroy(&tgt_bitmap);
1133 	cil_list_destroy(&class_list, CIL_FALSE);
1134 	return rc;
1135 }
1136 
cil_type_rule_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_type_rule * cil_rule)1137 int cil_type_rule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_type_rule *cil_rule)
1138 {
1139 	return  __cil_type_rule_to_avtab(pdb, db, cil_rule, NULL, CIL_FALSE);
1140 }
1141 
__cil_typetransition_to_avtab(policydb_t * pdb,const struct cil_db * db,struct cil_nametypetransition * typetrans,cond_node_t * cond_node,enum cil_flavor cond_flavor,hashtab_t filename_trans_table)1142 int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, cond_node_t *cond_node, enum cil_flavor cond_flavor, hashtab_t filename_trans_table)
1143 {
1144 	int rc = SEPOL_ERR;
1145 	type_datum_t *sepol_src = NULL;
1146 	type_datum_t *sepol_tgt = NULL;
1147 	class_datum_t *sepol_obj = NULL;
1148 	struct cil_list *class_list;
1149 	type_datum_t *sepol_result = NULL;
1150 	filename_trans_t *new = NULL;
1151 	ebitmap_t src_bitmap, tgt_bitmap;
1152 	ebitmap_node_t *node1, *node2;
1153 	unsigned int i, j;
1154 	struct cil_list_item *c;
1155 	char *name = DATUM(typetrans->name)->name;
1156 	uint32_t *otype = NULL;
1157 
1158 	if (name == CIL_KEY_STAR) {
1159 		struct cil_type_rule trans;
1160 		trans.rule_kind = CIL_TYPE_TRANSITION;
1161 		trans.src = typetrans->src;
1162 		trans.tgt = typetrans->tgt;
1163 		trans.obj = typetrans->obj;
1164 		trans.result = typetrans->result;
1165 		return __cil_type_rule_to_avtab(pdb, db, &trans, cond_node, cond_flavor);
1166 	}
1167 
1168 	rc = __cil_expand_type(typetrans->src, &src_bitmap);
1169 	if (rc != SEPOL_OK) goto exit;
1170 
1171 	rc = __cil_expand_type(typetrans->tgt, &tgt_bitmap);
1172 	if (rc != SEPOL_OK) goto exit;
1173 
1174 	class_list = cil_expand_class(typetrans->obj);
1175 
1176 	rc = __cil_get_sepol_type_datum(pdb, DATUM(typetrans->result), &sepol_result);
1177 	if (rc != SEPOL_OK) goto exit;
1178 
1179 	ebitmap_for_each_bit(&src_bitmap, node1, i) {
1180 		if (!ebitmap_get_bit(&src_bitmap, i)) continue;
1181 
1182 		rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src);
1183 		if (rc != SEPOL_OK) goto exit;
1184 
1185 		ebitmap_for_each_bit(&tgt_bitmap, node2, j) {
1186 			if (!ebitmap_get_bit(&tgt_bitmap, j)) continue;
1187 
1188 			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
1189 			if (rc != SEPOL_OK) goto exit;
1190 
1191 			cil_list_for_each(c, class_list) {
1192 				int add = CIL_TRUE;
1193 				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
1194 				if (rc != SEPOL_OK) goto exit;
1195 
1196 				new = cil_malloc(sizeof(*new));
1197 				memset(new, 0, sizeof(*new));
1198 				new->stype = sepol_src->s.value;
1199 				new->ttype = sepol_tgt->s.value;
1200 				new->tclass = sepol_obj->s.value;
1201 				new->otype = sepol_result->s.value;
1202 				new->name = cil_strdup(name);
1203 
1204 				rc = hashtab_insert(filename_trans_table, (hashtab_key_t)new, &(new->otype));
1205 				if (rc != SEPOL_OK) {
1206 					if (rc == SEPOL_EEXIST) {
1207 						add = CIL_FALSE;
1208 						otype = hashtab_search(filename_trans_table, (hashtab_key_t)new);
1209 						if (new->otype != *otype) {
1210 							cil_log(CIL_ERR, "Conflicting name type transition rules\n");
1211 						} else {
1212 							rc = SEPOL_OK;
1213 						}
1214 					} else {
1215 						cil_log(CIL_ERR, "Out of memory\n");
1216 					}
1217 				}
1218 
1219 				if (add == CIL_TRUE) {
1220 					new->next = pdb->filename_trans;
1221 					pdb->filename_trans = new;
1222 				} else {
1223 					free(new->name);
1224 					free(new);
1225 					if (rc != SEPOL_OK) {
1226 						goto exit;
1227 					}
1228 				}
1229 			}
1230 		}
1231 	}
1232 
1233 	rc = SEPOL_OK;
1234 
1235 exit:
1236 	ebitmap_destroy(&src_bitmap);
1237 	ebitmap_destroy(&tgt_bitmap);
1238 	cil_list_destroy(&class_list, CIL_FALSE);
1239 	return rc;
1240 }
1241 
cil_typetransition_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_nametypetransition * typetrans,hashtab_t filename_trans_table)1242 int cil_typetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, hashtab_t filename_trans_table)
1243 {
1244 	return  __cil_typetransition_to_avtab(pdb, db, typetrans, NULL, CIL_FALSE, filename_trans_table);
1245 }
1246 
__cil_perms_to_datum(struct cil_list * perms,class_datum_t * sepol_class,uint32_t * datum)1247 int __cil_perms_to_datum(struct cil_list *perms, class_datum_t *sepol_class, uint32_t *datum)
1248 {
1249 	int rc = SEPOL_ERR;
1250 	char *key = NULL;
1251 	struct cil_list_item *curr_perm;
1252 	struct cil_perm *cil_perm;
1253 	uint32_t data = 0;
1254 
1255 	cil_list_for_each(curr_perm, perms) {
1256 		perm_datum_t *sepol_perm;
1257 		cil_perm = curr_perm->data;
1258 		key = cil_perm->datum.fqn;
1259 		sepol_perm = hashtab_search(sepol_class->permissions.table, key);
1260 		if (sepol_perm == NULL) {
1261 			common_datum_t *sepol_common = sepol_class->comdatum;
1262 			sepol_perm = hashtab_search(sepol_common->permissions.table, key);
1263 			if (sepol_perm == NULL) {
1264 				cil_log(CIL_ERR, "Failed to find datum for perm %s\n", key);
1265 				rc = SEPOL_ERR;
1266 				goto exit;
1267 			}
1268 		}
1269 		data |= 1 << (sepol_perm->s.value - 1);
1270 	}
1271 
1272 	*datum = data;
1273 
1274 	return SEPOL_OK;
1275 
1276 exit:
1277 	return rc;
1278 }
1279 
__cil_insert_avrule(policydb_t * pdb,uint32_t kind,uint32_t src,uint32_t tgt,uint32_t obj,uint32_t data,cond_node_t * cond_node,enum cil_flavor cond_flavor)1280 int __cil_insert_avrule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t data, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1281 {
1282 	int rc = SEPOL_OK;
1283 	avtab_key_t avtab_key;
1284 	avtab_datum_t avtab_datum;
1285 	avtab_datum_t *avtab_dup = NULL;
1286 
1287 	avtab_key.source_type = src;
1288 	avtab_key.target_type = tgt;
1289 	avtab_key.target_class = obj;
1290 
1291 	switch (kind) {
1292 	case CIL_AVRULE_ALLOWED:
1293 		avtab_key.specified = AVTAB_ALLOWED;
1294 		break;
1295 	case CIL_AVRULE_AUDITALLOW:
1296 		avtab_key.specified = AVTAB_AUDITALLOW;
1297 		break;
1298 	case CIL_AVRULE_DONTAUDIT:
1299 		avtab_key.specified = AVTAB_AUDITDENY;
1300 		break;
1301 	default:
1302 		rc = SEPOL_ERR;
1303 		goto exit;
1304 		break;
1305 	}
1306 
1307 	if (!cond_node) {
1308 		avtab_dup = avtab_search(&pdb->te_avtab, &avtab_key);
1309 		if (!avtab_dup) {
1310 			avtab_datum.data = data;
1311 			rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum);
1312 		} else {
1313 			if (kind == CIL_AVRULE_DONTAUDIT)
1314 				avtab_dup->data &= data;
1315 			else
1316 				avtab_dup->data |= data;
1317 		}
1318 	} else {
1319 		avtab_datum.data = data;
1320 		rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor);
1321 	}
1322 
1323 exit:
1324 	return rc;
1325 }
1326 
__cil_neverallow_handle(struct cil_list * neverallows,struct cil_symtab_datum * src,struct cil_symtab_datum * tgt,uint32_t class,uint32_t perms)1327 static void __cil_neverallow_handle(struct cil_list *neverallows, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, uint32_t class, uint32_t perms)
1328 {
1329 	struct cil_neverallow *neverallow = neverallows->head->data;
1330 	struct cil_list *neverallow_rules = neverallow->rules;
1331 	struct cil_neverallow_rule *new = NULL;
1332 
1333 	new = cil_malloc(sizeof(*new));
1334 	new->src = src;
1335 	new->tgt = tgt;
1336 	new->class = class;
1337 	new->perms = perms;
1338 
1339 	cil_list_append(neverallow_rules, CIL_LIST_ITEM, new);
1340 }
1341 
__cil_is_type_match(enum cil_flavor f1,struct cil_symtab_datum * t1,enum cil_flavor f2,struct cil_symtab_datum * t2)1342 static int __cil_is_type_match(enum cil_flavor f1, struct cil_symtab_datum *t1, enum cil_flavor f2, struct cil_symtab_datum *t2)
1343 {
1344 	if (t1->fqn == t2->fqn) {
1345 		return CIL_TRUE;
1346 	} else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
1347 		struct cil_typeattribute *a = (struct cil_typeattribute *)t1;
1348 		struct cil_type *t = (struct cil_type *)t2;
1349 		if (ebitmap_get_bit(a->types, t->value)) {
1350 			return CIL_TRUE;
1351 		}
1352 	} else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
1353 		struct cil_typeattribute *a = (struct cil_typeattribute *)t2;
1354 		struct cil_type *t = (struct cil_type *)t1;
1355 		if (ebitmap_get_bit(a->types, t->value)) {
1356 			return CIL_TRUE;
1357 		}
1358 	} else if (f1 == CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
1359 		struct cil_typeattribute *a1 = (struct cil_typeattribute *)t2;
1360 		struct cil_typeattribute *a2 = (struct cil_typeattribute *)t1;
1361 		/* abusing the ebitmap abstraction for speed */
1362 		ebitmap_node_t *n1 = a1->types->node;
1363 		ebitmap_node_t *n2 = a2->types->node;
1364 		while (n1 && n2) {
1365 			if (n1->startbit < n2->startbit) {
1366 				n1 = n1->next;
1367 			} else if (n2->startbit < n1->startbit) {
1368 				n2 = n2->next;
1369 			} else {
1370 				if (n1->map & n2->map) {
1371 					return CIL_TRUE;
1372 				}
1373 				n1 = n1->next;
1374 				n2 = n2->next;
1375 			}
1376 		}
1377 	}
1378 	return CIL_FALSE;
1379 }
1380 
__cil_check_neverallows(struct cil_list * neverallows,struct cil_symtab_datum * src,struct cil_symtab_datum * tgt,uint32_t class,uint32_t perms)1381 static int __cil_check_neverallows(struct cil_list *neverallows, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, uint32_t class, uint32_t perms)
1382 {
1383 	struct cil_list_item *curr = NULL;
1384 	enum cil_flavor al_src_flavor = ((struct cil_tree_node*)src->nodes->head->data)->flavor;
1385 	enum cil_flavor al_tgt_flavor = ((struct cil_tree_node*)tgt->nodes->head->data)->flavor;
1386 	cil_list_for_each(curr, neverallows) {
1387 		struct cil_neverallow *neverallow = curr->data;
1388 		struct cil_tree_node *node = neverallow->node;
1389 		struct cil_list_item *curr_item = NULL;
1390 		cil_list_for_each(curr_item, neverallow->rules) {
1391 			struct cil_neverallow_rule *curr_rule = curr_item->data;
1392 			enum cil_flavor nv_src_flavor = ((struct cil_tree_node*)curr_rule->src->nodes->head->data)->flavor;
1393 			enum cil_flavor nv_tgt_flavor = ((struct cil_tree_node*)curr_rule->tgt->nodes->head->data)->flavor;
1394 			if ((curr_rule->perms & perms) && (class == curr_rule->class)) {
1395 				int src_match = __cil_is_type_match(al_src_flavor, src, nv_src_flavor, curr_rule->src);
1396 				if (src_match) {
1397 					int tgt_match = __cil_is_type_match(al_tgt_flavor, tgt, nv_tgt_flavor, curr_rule->tgt);
1398 					if (tgt_match) {
1399 						cil_log(CIL_ERR, "Neverallow found that matches avrule at line %d of %s\n", node->line, node->path);
1400 						return SEPOL_ERR;
1401 					}
1402 				}
1403 			}
1404 		}
1405 	}
1406 	return SEPOL_OK;
1407 }
1408 
__cil_avrule_expand_helper(policydb_t * pdb,uint16_t kind,struct cil_symtab_datum * src,struct cil_symtab_datum * tgt,struct cil_classperms * cp,struct cil_list * neverallows,cond_node_t * cond_node,enum cil_flavor cond_flavor)1409 int __cil_avrule_expand_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_classperms *cp, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1410 {
1411 	int rc = SEPOL_ERR;
1412 	type_datum_t *sepol_src = NULL;
1413 	type_datum_t *sepol_tgt = NULL;
1414 	class_datum_t *sepol_class = NULL;
1415 	uint32_t data = 0;
1416 
1417 	rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class);
1418 	if (rc != SEPOL_OK) goto exit;
1419 
1420 	rc = __cil_perms_to_datum(cp->perms, sepol_class, &data);
1421 	if (rc != SEPOL_OK) goto exit;
1422 
1423 	if (data == 0) {
1424 		/* No permissions, so don't insert rule. Maybe should return an error? */
1425 		return SEPOL_OK;
1426 	}
1427 
1428 	if (kind == CIL_AVRULE_NEVERALLOW) {
1429 		__cil_neverallow_handle(neverallows, src, tgt, sepol_class->s.value, data);
1430 	} else {
1431 		if (kind == CIL_AVRULE_DONTAUDIT) {
1432 			data = ~data;
1433 		} else if (neverallows != NULL && kind == CIL_AVRULE_ALLOWED) {
1434 			rc = __cil_check_neverallows(neverallows, src, tgt, sepol_class->s.value, data);
1435 			if (rc != SEPOL_OK) {
1436 				goto exit;
1437 			}
1438 		}
1439 
1440 		rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src);
1441 		if (rc != SEPOL_OK) goto exit;
1442 
1443 		rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt);
1444 		if (rc != SEPOL_OK) goto exit;
1445 
1446 		rc = __cil_insert_avrule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_class->s.value, data, cond_node, cond_flavor);
1447 		if (rc != SEPOL_OK) {
1448 			goto exit;
1449 		}
1450 	}
1451 
1452 	return SEPOL_OK;
1453 
1454 exit:
1455 	return rc;
1456 }
1457 
1458 
__cil_avrule_expand(policydb_t * pdb,uint16_t kind,struct cil_symtab_datum * src,struct cil_symtab_datum * tgt,struct cil_list * classperms,struct cil_list * neverallows,cond_node_t * cond_node,enum cil_flavor cond_flavor)1459 int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1460 {
1461 	int rc = SEPOL_ERR;
1462 	struct cil_list_item *curr;
1463 
1464 	cil_list_for_each(curr, classperms) {
1465 		if (curr->flavor == CIL_CLASSPERMS) {
1466 			struct cil_classperms *cp = curr->data;
1467 			if (FLAVOR(cp->class) == CIL_CLASS) {
1468 				rc = __cil_avrule_expand_helper(pdb, kind, src, tgt, cp, neverallows, cond_node, cond_flavor);
1469 				if (rc != SEPOL_OK) {
1470 					goto exit;
1471 				}
1472 			} else { /* MAP */
1473 				struct cil_list_item *i = NULL;
1474 				cil_list_for_each(i, cp->perms) {
1475 					struct cil_perm *cmp = i->data;
1476 					rc = __cil_avrule_expand(pdb, kind, src, tgt, cmp->classperms, neverallows, cond_node, cond_flavor);
1477 					if (rc != SEPOL_OK) {
1478 						goto exit;
1479 					}
1480 				}
1481 			}
1482 		} else { /* SET */
1483 			struct cil_classperms_set *cp_set = curr->data;
1484 			struct cil_classpermission *cp = cp_set->set;
1485 			rc = __cil_avrule_expand(pdb, kind, src, tgt, cp->classperms, neverallows, cond_node, cond_flavor);
1486 			if (rc != SEPOL_OK) {
1487 				goto exit;
1488 			}
1489 		}
1490 	}
1491 
1492 	return SEPOL_OK;
1493 
1494 exit:
1495 	return rc;
1496 }
1497 
__cil_avrule_to_avtab(policydb_t * pdb,const struct cil_db * db,struct cil_avrule * cil_avrule,struct cil_list * neverallows,cond_node_t * cond_node,enum cil_flavor cond_flavor)1498 int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1499 {
1500 	int rc = SEPOL_ERR;
1501 	uint16_t kind = cil_avrule->rule_kind;
1502 	struct cil_symtab_datum *src = NULL;
1503 	struct cil_symtab_datum *tgt = NULL;
1504 	struct cil_list *classperms = cil_avrule->classperms;
1505 
1506 	if (cil_avrule->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) {
1507 		// Do not add dontaudit rules to binary
1508 		rc = SEPOL_OK;
1509 		goto exit;
1510 	}
1511 
1512 	if (cil_avrule->rule_kind == CIL_AVRULE_NEVERALLOW && db->disable_neverallow == CIL_TRUE) {
1513 		// ignore neverallow rules
1514 		rc = SEPOL_OK;
1515 		goto exit;
1516 	}
1517 
1518 	src = cil_avrule->src;
1519 	tgt = cil_avrule->tgt;
1520 
1521 	if (tgt->fqn == CIL_KEY_SELF) {
1522 		ebitmap_t type_bitmap;
1523 		ebitmap_node_t *tnode;
1524 		unsigned int i;
1525 
1526 		rc = __cil_expand_type(src, &type_bitmap);
1527 		if (rc != SEPOL_OK) goto exit;
1528 
1529 		ebitmap_for_each_bit(&type_bitmap, tnode, i) {
1530 			if (!ebitmap_get_bit(&type_bitmap, i)) continue;
1531 
1532 			src = DATUM(db->val_to_type[i]);
1533 			rc = __cil_avrule_expand(pdb, kind, src, src, classperms, neverallows, cond_node, cond_flavor);
1534 			if (rc != SEPOL_OK) {
1535 				ebitmap_destroy(&type_bitmap);
1536 				goto exit;
1537 			}
1538 		}
1539 		ebitmap_destroy(&type_bitmap);
1540 	} else {
1541 		rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, neverallows, cond_node, cond_flavor);
1542 		if (rc != SEPOL_OK) goto exit;
1543 	}
1544 
1545 	return SEPOL_OK;
1546 
1547 exit:
1548 	return rc;
1549 }
1550 
cil_avrule_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_avrule * cil_avrule,struct cil_list * neverallows)1551 int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, struct cil_list *neverallows)
1552 {
1553 	return __cil_avrule_to_avtab(pdb, db, cil_avrule, neverallows, NULL, CIL_FALSE);
1554 }
1555 
__cil_cond_to_policydb_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1556 int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
1557 {
1558 	int rc;
1559 	enum cil_flavor flavor;
1560 	struct cil_args_booleanif *args = extra_args;
1561 	const struct cil_db *db = args->db;
1562 	policydb_t *pdb = args->pdb;
1563 	cond_node_t *cond_node = args->cond_node;
1564 	enum cil_flavor cond_flavor = args->cond_flavor;
1565 	struct cil_type_rule *cil_type_rule;
1566 	struct cil_avrule *cil_avrule;
1567 	struct cil_nametypetransition *cil_typetrans;
1568 	hashtab_t filename_trans_table = args->filename_trans_table;
1569 
1570 	flavor = node->flavor;
1571 	switch (flavor) {
1572 	case CIL_NAMETYPETRANSITION:
1573 		cil_typetrans = (struct cil_nametypetransition*)node->data;
1574 		if (DATUM(cil_typetrans->name)->fqn != CIL_KEY_STAR) {
1575 			cil_log(CIL_ERR, "typetransition with file name not allowed within a booleanif block.\n");
1576 			cil_log(CIL_ERR,"Invalid typetransition statement at line %d of %s\n",
1577 			node->line, node->path);
1578 			goto exit;
1579 		}
1580 		rc = __cil_typetransition_to_avtab(pdb, db, cil_typetrans, cond_node, cond_flavor, filename_trans_table);
1581 		if (rc != SEPOL_OK) {
1582 			cil_log(CIL_ERR, "Failed to insert type transition into avtab at line %d of %s\n", node->line, node->path);
1583 			goto exit;
1584 		}
1585 		break;
1586 	case CIL_TYPE_RULE:
1587 		cil_type_rule = node->data;
1588 		rc = __cil_type_rule_to_avtab(pdb, db, cil_type_rule, cond_node, cond_flavor);
1589 		if (rc != SEPOL_OK) {
1590 			cil_log(CIL_ERR, "Failed to insert typerule into avtab at line %d of %s\n", node->line, node->path);
1591 			goto exit;
1592 		}
1593 		break;
1594 	case CIL_AVRULE:
1595 		cil_avrule = node->data;
1596 		rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, args->neverallows, cond_node, cond_flavor);
1597 		if (rc != SEPOL_OK) {
1598 			cil_log(CIL_ERR, "Failed to insert avrule into avtab at line %d of %s\n", node->line, node->path);
1599 			goto exit;
1600 		}
1601 		break;
1602 	case CIL_CALL:
1603 	case CIL_TUNABLEIF:
1604 		break;
1605 	default:
1606 		cil_log(CIL_ERR, "Invalid statement within booleanif at line %d of %s\n",
1607 			node->line, node->path);
1608 		goto exit;
1609 	}
1610 
1611 	return SEPOL_OK;
1612 
1613 exit:
1614 	return SEPOL_ERR;
1615 }
1616 
1617 static int __cil_cond_expr_to_sepol_expr_helper(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **head, cond_expr_t **tail);
1618 
__cil_cond_item_to_sepol_expr(policydb_t * pdb,struct cil_list_item * item,cond_expr_t ** head,cond_expr_t ** tail)1619 static int __cil_cond_item_to_sepol_expr(policydb_t *pdb, struct cil_list_item *item, cond_expr_t **head, cond_expr_t **tail)
1620 {
1621 	if (item == NULL) {
1622 		goto exit;
1623 	} else if (item->flavor == CIL_DATUM) {
1624 		char *key = DATUM(item->data)->fqn;
1625 		cond_bool_datum_t *sepol_bool = hashtab_search(pdb->p_bools.table, key);
1626 		if (sepol_bool == NULL) {
1627 			cil_log(CIL_INFO, "Failed to find boolean\n");
1628 			goto exit;
1629 		}
1630 		*head = cil_malloc(sizeof(cond_expr_t));
1631 		(*head)->next = NULL;
1632 		(*head)->expr_type = COND_BOOL;
1633 		(*head)->bool = sepol_bool->s.value;
1634 		*tail = *head;
1635 	} else if (item->flavor == CIL_LIST) {
1636 		struct cil_list *l = item->data;
1637 		int rc = __cil_cond_expr_to_sepol_expr_helper(pdb, l, head, tail);
1638 		if (rc != SEPOL_OK) {
1639 			goto exit;
1640 		}
1641 	} else {
1642 		goto exit;
1643 	}
1644 
1645 	return SEPOL_OK;
1646 
1647 exit:
1648 	return SEPOL_ERR;
1649 }
1650 
__cil_cond_expr_to_sepol_expr_helper(policydb_t * pdb,struct cil_list * cil_expr,cond_expr_t ** head,cond_expr_t ** tail)1651 static int __cil_cond_expr_to_sepol_expr_helper(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **head, cond_expr_t **tail)
1652 {
1653 	int rc = SEPOL_ERR;
1654 	struct cil_list_item *item = cil_expr->head;
1655 	enum cil_flavor flavor = cil_expr->flavor;
1656 	cond_expr_t *op, *h1, *h2, *t1, *t2;
1657 
1658 	if (flavor != CIL_BOOL) {
1659 		cil_log(CIL_INFO, "Expected boolean expression\n");
1660 		goto exit;
1661 	}
1662 
1663 	if (item == NULL) {
1664 		goto exit;
1665 	} else if (item->flavor == CIL_OP) {
1666 		enum cil_flavor cil_op = (enum cil_flavor)item->data;
1667 
1668 		op = cil_malloc(sizeof(*op));
1669 		op->bool = 0;
1670 		op->next = NULL;
1671 
1672 		switch (cil_op) {
1673 		case CIL_NOT:
1674 			op->expr_type = COND_NOT;
1675 			break;
1676 		case CIL_OR:
1677 			op->expr_type = COND_OR;
1678 			break;
1679 		case CIL_AND:
1680 			op->expr_type = COND_AND;
1681 			break;
1682 		case CIL_XOR:
1683 			op->expr_type = COND_XOR;
1684 			break;
1685 		case CIL_EQ:
1686 			op->expr_type = COND_EQ;
1687 			break;
1688 		case CIL_NEQ:
1689 			op->expr_type = COND_NEQ;
1690 			break;
1691 		default:
1692 			goto exit;
1693 		}
1694 
1695 		rc = __cil_cond_item_to_sepol_expr(pdb, item->next, &h1, &t1);
1696 		if (rc != SEPOL_OK) {
1697 			cil_log(CIL_INFO, "Failed to get first operand of conditional expression\n");
1698 			free(op);
1699 			goto exit;
1700 		}
1701 
1702 		if (cil_op == CIL_NOT) {
1703 			*head = h1;
1704 			t1->next = op;
1705 			*tail = op;
1706 		} else {
1707 			rc = __cil_cond_item_to_sepol_expr(pdb, item->next->next, &h2, &t2);
1708 			if (rc != SEPOL_OK) {
1709 				cil_log(CIL_INFO, "Failed to get second operand of conditional expression\n");
1710 				free(op);
1711 				cond_expr_destroy(h1);
1712 				goto exit;
1713 			}
1714 
1715 			*head = h1;
1716 			t1->next = h2;
1717 			t2->next = op;
1718 			*tail = op;
1719 		}
1720 	} else {
1721 		rc = __cil_cond_item_to_sepol_expr(pdb, item, &h1, &t1);
1722 		if (rc != SEPOL_OK) {
1723 			cil_log(CIL_INFO, "Failed to get initial item in conditional list\n");
1724 			goto exit;
1725 		}
1726 		*head = h1;
1727 		for (item = item->next; item; item = item->next) {
1728 			rc = __cil_cond_item_to_sepol_expr(pdb, item, &h2, &t2);
1729 			if (rc != SEPOL_OK) {
1730 				cil_log(CIL_INFO, "Failed to get item in conditional list\n");
1731 				cond_expr_destroy(*head);
1732 				goto exit;
1733 			}
1734 			op = cil_malloc(sizeof(*op));
1735 			op->bool = 0;
1736 			op->next = NULL;
1737 			op->expr_type = COND_OR;
1738 			t1->next = h2;
1739 			t2->next = op;
1740 			t1 = op;
1741 		}
1742 		*tail = t1;
1743 	}
1744 
1745 	return SEPOL_OK;
1746 
1747 exit:
1748 	return SEPOL_ERR;
1749 }
1750 
__cil_cond_expr_to_sepol_expr(policydb_t * pdb,struct cil_list * cil_expr,cond_expr_t ** sepol_expr)1751 static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **sepol_expr)
1752 {
1753 	int rc;
1754 	cond_expr_t *head, *tail;
1755 
1756 	rc = __cil_cond_expr_to_sepol_expr_helper(pdb, cil_expr, &head, &tail);
1757 	if (rc != SEPOL_OK) {
1758 		return SEPOL_ERR;
1759 	}
1760 	*sepol_expr = head;
1761 
1762 	return SEPOL_OK;
1763 }
1764 
cil_booleanif_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_tree_node * node,struct cil_list * neverallows,hashtab_t filename_trans_table)1765 int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, struct cil_list *neverallows, hashtab_t filename_trans_table)
1766 {
1767 	int rc = SEPOL_ERR;
1768 	struct cil_args_booleanif bool_args;
1769 	struct cil_booleanif *cil_boolif = (struct cil_booleanif*)node->data;
1770 	struct cil_tree_node *cb_node = node->cl_head;
1771 	struct cil_tree_node *true_node = NULL;
1772 	struct cil_tree_node *false_node = NULL;
1773 	struct cil_tree_node *tmp_node = NULL;
1774 	cond_node_t *tmp_cond = NULL;
1775 	cond_node_t *cond_node = NULL;
1776 	int was_created;
1777 	int swapped = CIL_FALSE;
1778 	cond_av_list_t tmp_cl;
1779 
1780 	tmp_cond = cond_node_create(pdb, NULL);
1781 	if (tmp_cond == NULL) {
1782 		rc = SEPOL_ERR;
1783 		cil_log(CIL_INFO, "Failed to create sepol conditional node at line %d of %s\n",
1784 			node->line, node->path);
1785 		goto exit;
1786 	}
1787 
1788 	rc = __cil_cond_expr_to_sepol_expr(pdb, cil_boolif->datum_expr, &tmp_cond->expr);
1789 	if (rc != SEPOL_OK) {
1790 		cil_log(CIL_INFO, "Failed to convert CIL conditional expression to sepol expression at line %d of %s\n", node->line, node->path);
1791 		goto exit;
1792 	}
1793 
1794 	tmp_cond->true_list = &tmp_cl;
1795 
1796 	rc = cond_normalize_expr(pdb, tmp_cond);
1797 	if (rc != SEPOL_OK) {
1798 		goto exit;
1799 	}
1800 
1801 	if (tmp_cond->false_list != NULL) {
1802 		tmp_cond->true_list = NULL;
1803 		swapped = CIL_TRUE;
1804 	}
1805 
1806 	cond_node = cond_node_find(pdb, tmp_cond, pdb->cond_list, &was_created);
1807 	if (cond_node == NULL) {
1808 		rc = SEPOL_ERR;
1809 		goto exit;
1810 	}
1811 
1812 	if (was_created) {
1813 		cond_node->next = pdb->cond_list;
1814 		pdb->cond_list = cond_node;
1815 	}
1816 
1817 	cond_expr_destroy(tmp_cond->expr);
1818 	free(tmp_cond);
1819 
1820 	for (cb_node = node->cl_head; cb_node != NULL; cb_node = cb_node->next) {
1821 		if (cb_node->flavor == CIL_CONDBLOCK) {
1822 			struct cil_condblock *cb = cb_node->data;
1823 			if (cb->flavor == CIL_CONDTRUE) {
1824 					true_node = cb_node;
1825 			} else if (cb->flavor == CIL_CONDFALSE) {
1826 					false_node = cb_node;
1827 			}
1828 		}
1829 	}
1830 
1831 	if (swapped) {
1832 		tmp_node = true_node;
1833 		true_node = false_node;
1834 		false_node = tmp_node;
1835 	}
1836 
1837 	bool_args.db = db;
1838 	bool_args.pdb = pdb;
1839 	bool_args.cond_node = cond_node;
1840 	bool_args.neverallows = neverallows;
1841 	bool_args.filename_trans_table = filename_trans_table;
1842 
1843 	if (true_node != NULL) {
1844 		bool_args.cond_flavor = CIL_CONDTRUE;
1845 		rc = cil_tree_walk(true_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args);
1846 		if (rc != SEPOL_OK) {
1847 			cil_log(CIL_ERR, "Failure while walking true conditional block at line %d of %s\n", true_node->line, true_node->path);
1848 			goto exit;
1849 		}
1850 	}
1851 
1852 	if (false_node != NULL) {
1853 		bool_args.cond_flavor = CIL_CONDFALSE;
1854 		rc = cil_tree_walk(false_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args);
1855 		if (rc != SEPOL_OK) {
1856 			cil_log(CIL_ERR, "Failure while walking false conditional block at line %d of %s\n", false_node->line, false_node->path);
1857 			goto exit;
1858 		}
1859 	}
1860 
1861 	return SEPOL_OK;
1862 
1863 exit:
1864 	return rc;
1865 }
1866 
cil_roletrans_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_roletransition * roletrans,hashtab_t role_trans_table)1867 int cil_roletrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roletransition *roletrans, hashtab_t role_trans_table)
1868 {
1869 	int rc = SEPOL_ERR;
1870 	role_datum_t *sepol_src = NULL;
1871 	type_datum_t *sepol_tgt = NULL;
1872 	class_datum_t *sepol_obj = NULL;
1873 	struct cil_list *class_list;
1874 	role_datum_t *sepol_result = NULL;
1875 	role_trans_t *new = NULL;
1876 	uint32_t *new_role = NULL;
1877 	ebitmap_t role_bitmap, type_bitmap;
1878 	ebitmap_node_t *rnode, *tnode;
1879 	unsigned int i, j;
1880 	struct cil_list_item *c;
1881 
1882 	rc = __cil_expand_role(DATUM(roletrans->src), &role_bitmap);
1883 	if (rc != SEPOL_OK) goto exit;
1884 
1885 	rc = __cil_expand_type(roletrans->tgt, &type_bitmap);
1886 	if (rc != SEPOL_OK) goto exit;
1887 
1888 	class_list = cil_expand_class(roletrans->obj);
1889 
1890 	rc = __cil_get_sepol_role_datum(pdb, DATUM(roletrans->result), &sepol_result);
1891 	if (rc != SEPOL_OK) goto exit;
1892 
1893 	ebitmap_for_each_bit(&role_bitmap, rnode, i) {
1894 		if (!ebitmap_get_bit(&role_bitmap, i)) continue;
1895 
1896 		rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src);
1897 		if (rc != SEPOL_OK) goto exit;
1898 
1899 		ebitmap_for_each_bit(&type_bitmap, tnode, j) {
1900 			if (!ebitmap_get_bit(&type_bitmap, j)) continue;
1901 
1902 			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
1903 			if (rc != SEPOL_OK) goto exit;
1904 
1905 			cil_list_for_each(c, class_list) {
1906 				int add = CIL_TRUE;
1907 				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
1908 				if (rc != SEPOL_OK) goto exit;
1909 
1910 				new = cil_malloc(sizeof(*new));
1911 				memset(new, 0, sizeof(*new));
1912 				new->role = sepol_src->s.value;
1913 				new->type = sepol_tgt->s.value;
1914 				new->tclass = sepol_obj->s.value;
1915 				new->new_role = sepol_result->s.value;
1916 
1917 				rc = SEPOL_OK;
1918 				rc = hashtab_insert(role_trans_table, (hashtab_key_t)new, &(new->new_role));
1919 				if (rc != SEPOL_OK) {
1920 					if (rc == SEPOL_EEXIST) {
1921 						add = CIL_FALSE;
1922 						new_role = hashtab_search(role_trans_table, (hashtab_key_t)new);
1923 						if (new->new_role != *new_role) {
1924 							cil_log(CIL_ERR, "Conflicting role transition rules\n");
1925 						} else {
1926 							rc = SEPOL_OK;
1927 						}
1928 					} else {
1929 						cil_log(CIL_ERR, "Out of memory\n");
1930 					}
1931 				}
1932 
1933 				if (add == CIL_TRUE) {
1934 					new->next = pdb->role_tr;
1935 					pdb->role_tr = new;
1936 				} else {
1937 					free(new);
1938 					if (rc != SEPOL_OK) {
1939 						goto exit;
1940 					}
1941 				}
1942 			}
1943 		}
1944 	}
1945 
1946 	rc = SEPOL_OK;
1947 
1948 exit:
1949 	ebitmap_destroy(&role_bitmap);
1950 	ebitmap_destroy(&type_bitmap);
1951 	cil_list_destroy(&class_list, CIL_FALSE);
1952 	return rc;
1953 }
1954 
cil_roleallow_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_roleallow * roleallow)1955 int cil_roleallow_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roleallow *roleallow)
1956 {
1957 	int rc = SEPOL_ERR;
1958 	role_datum_t *sepol_src = NULL;
1959 	role_datum_t *sepol_tgt = NULL;
1960 	role_allow_t *sepol_roleallow = NULL;
1961 	ebitmap_t src_bitmap, tgt_bitmap;
1962 	ebitmap_node_t *node1, *node2;
1963 	unsigned int i, j;
1964 
1965 	rc = __cil_expand_role(roleallow->src, &src_bitmap);
1966 	if (rc != SEPOL_OK) goto exit;
1967 
1968 	rc = __cil_expand_role(roleallow->tgt, &tgt_bitmap);
1969 	if (rc != SEPOL_OK) goto exit;
1970 
1971 	ebitmap_for_each_bit(&src_bitmap, node1, i) {
1972 		if (!ebitmap_get_bit(&src_bitmap, i)) continue;
1973 
1974 		rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src);
1975 		if (rc != SEPOL_OK) goto exit;
1976 
1977 		ebitmap_for_each_bit(&tgt_bitmap, node2, j) {
1978 			if (!ebitmap_get_bit(&tgt_bitmap, j)) continue;
1979 
1980 			rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[j]), &sepol_tgt);
1981 			if (rc != SEPOL_OK) goto exit;
1982 
1983 			sepol_roleallow = cil_malloc(sizeof(*sepol_roleallow));
1984 			memset(sepol_roleallow, 0, sizeof(role_allow_t));
1985 			sepol_roleallow->role = sepol_src->s.value;
1986 			sepol_roleallow->new_role = sepol_tgt->s.value;
1987 
1988 			sepol_roleallow->next = pdb->role_allow;
1989 			pdb->role_allow = sepol_roleallow;
1990 		}
1991 	}
1992 
1993 	rc = SEPOL_OK;
1994 
1995 exit:
1996 	ebitmap_destroy(&src_bitmap);
1997 	ebitmap_destroy(&tgt_bitmap);
1998 	return rc;
1999 }
2000 
__cil_constrain_expr_datum_to_sepol_expr(policydb_t * pdb,const struct cil_db * db,struct cil_list_item * item,enum cil_flavor expr_flavor,constraint_expr_t * expr)2001 int __cil_constrain_expr_datum_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, struct cil_list_item *item, enum cil_flavor expr_flavor, constraint_expr_t *expr)
2002 {
2003 	int rc = SEPOL_ERR;
2004 
2005 	if (expr_flavor == CIL_USER) {
2006 		user_datum_t *sepol_user = NULL;
2007 		rc = __cil_get_sepol_user_datum(pdb, item->data, &sepol_user);
2008 		if (rc != SEPOL_OK) goto exit;
2009 
2010 		if (ebitmap_set_bit(&expr->names, sepol_user->s.value - 1, 1)) {
2011 			goto exit;
2012 		}
2013 	} else if (expr_flavor == CIL_ROLE) {
2014 		role_datum_t *sepol_role = NULL;
2015 		ebitmap_t role_bitmap;
2016 		ebitmap_node_t *rnode;
2017 		unsigned int i;
2018 
2019 		rc = __cil_expand_role(item->data, &role_bitmap);
2020 		if (rc != SEPOL_OK) goto exit;
2021 
2022 		ebitmap_for_each_bit(&role_bitmap, rnode, i) {
2023 			if (!ebitmap_get_bit(&role_bitmap, i)) continue;
2024 
2025 			rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role);
2026 			if (rc != SEPOL_OK) {
2027 				ebitmap_destroy(&role_bitmap);
2028 				goto exit;
2029 			}
2030 
2031 			if (ebitmap_set_bit(&expr->names, sepol_role->s.value - 1, 1)) {
2032 				ebitmap_destroy(&role_bitmap);
2033 				goto exit;
2034 			}
2035 		}
2036 		ebitmap_destroy(&role_bitmap);
2037 	} else if (expr_flavor == CIL_TYPE) {
2038 		type_datum_t *sepol_type = NULL;
2039 		ebitmap_t type_bitmap;
2040 		ebitmap_node_t *tnode;
2041 		unsigned int i;
2042 
2043 		if (pdb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) {
2044 			rc = __cil_get_sepol_type_datum(pdb, item->data, &sepol_type);
2045 			if (rc != SEPOL_OK) {
2046 				ebitmap_destroy(&type_bitmap);
2047 				goto exit;
2048 			}
2049 
2050 			if (ebitmap_set_bit(&expr->type_names->types, sepol_type->s.value - 1, 1)) {
2051 				ebitmap_destroy(&type_bitmap);
2052 				goto exit;
2053 			}
2054 		}
2055 
2056 		rc = __cil_expand_type(item->data, &type_bitmap);
2057 		if (rc != SEPOL_OK) goto exit;
2058 
2059 		ebitmap_for_each_bit(&type_bitmap, tnode, i) {
2060 			if (!ebitmap_get_bit(&type_bitmap, i)) continue;
2061 
2062 			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type);
2063 			if (rc != SEPOL_OK) {
2064 				ebitmap_destroy(&type_bitmap);
2065 				goto exit;
2066 			}
2067 
2068 			if (ebitmap_set_bit(&expr->names, sepol_type->s.value - 1, 1)) {
2069 				ebitmap_destroy(&type_bitmap);
2070 				goto exit;
2071 			}
2072 		}
2073 		ebitmap_destroy(&type_bitmap);
2074 	} else {
2075 		goto exit;
2076 	}
2077 
2078 	return SEPOL_OK;
2079 
2080 exit:
2081 	return SEPOL_ERR;
2082 }
2083 
__cil_constrain_expr_leaf_to_sepol_expr(policydb_t * pdb,const struct cil_db * db,struct cil_list_item * op_item,enum cil_flavor expr_flavor,constraint_expr_t * expr)2084 int __cil_constrain_expr_leaf_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, struct cil_list_item *op_item, enum cil_flavor expr_flavor, constraint_expr_t *expr)
2085 {
2086 	int rc = SEPOL_ERR;
2087 	struct cil_list_item *l_item = op_item->next;
2088 	struct cil_list_item *r_item = op_item->next->next;
2089 
2090 	enum cil_flavor l_operand = (enum cil_flavor)l_item->data;
2091 
2092 	switch (l_operand) {
2093 	case CIL_CONS_U1:
2094 		expr->attr = CEXPR_USER;
2095 		break;
2096 	case CIL_CONS_U2:
2097 		expr->attr = CEXPR_USER | CEXPR_TARGET;
2098 		break;
2099 	case CIL_CONS_U3:
2100 		expr->attr = CEXPR_USER | CEXPR_XTARGET;
2101 		break;
2102 	case CIL_CONS_R1:
2103 		expr->attr = CEXPR_ROLE;
2104 		break;
2105 	case CIL_CONS_R2:
2106 		expr->attr = CEXPR_ROLE | CEXPR_TARGET;
2107 		break;
2108 	case CIL_CONS_R3:
2109 		expr->attr = CEXPR_ROLE | CEXPR_XTARGET;
2110 		break;
2111 	case CIL_CONS_T1:
2112 		expr->attr = CEXPR_TYPE;
2113 		break;
2114 	case CIL_CONS_T2:
2115 		expr->attr = CEXPR_TYPE | CEXPR_TARGET;
2116 		break;
2117 	case CIL_CONS_T3:
2118 		expr->attr = CEXPR_TYPE | CEXPR_XTARGET;
2119 		break;
2120 	case CIL_CONS_L1: {
2121 		enum cil_flavor r_operand = (enum cil_flavor)r_item->data;
2122 
2123 		if (r_operand == CIL_CONS_L2) {
2124 			expr->attr = CEXPR_L1L2;
2125 		} else if (r_operand == CIL_CONS_H1) {
2126 			expr->attr = CEXPR_L1H1;
2127 		} else {
2128 			expr->attr = CEXPR_L1H2;
2129 		}
2130 		break;
2131 	}
2132 	case CIL_CONS_L2:
2133 		expr->attr = CEXPR_L2H2;
2134 		break;
2135 	case CIL_CONS_H1: {
2136 		enum cil_flavor r_operand = (enum cil_flavor)r_item->data;
2137 		if (r_operand == CIL_CONS_L2) {
2138 			expr->attr = CEXPR_H1L2;
2139 		} else {
2140 			expr->attr = CEXPR_H1H2;
2141 		}
2142 		break;
2143 	}
2144 	default:
2145 		goto exit;
2146 		break;
2147 	}
2148 
2149 	if (r_item->flavor == CIL_CONS_OPERAND) {
2150 		expr->expr_type = CEXPR_ATTR;
2151 	} else {
2152 		expr->expr_type = CEXPR_NAMES;
2153 		if (r_item->flavor == CIL_DATUM) {
2154 			rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, r_item, expr_flavor, expr);
2155 			if (rc != SEPOL_OK) {
2156 				goto exit;
2157 			}
2158 		} else if (r_item->flavor == CIL_LIST) {
2159 			struct cil_list *r_expr = r_item->data;
2160 			struct cil_list_item *curr;
2161 			cil_list_for_each(curr, r_expr) {
2162 				rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, curr, expr_flavor, expr);
2163 				if (rc != SEPOL_OK) {
2164 					goto exit;
2165 				}
2166 			}
2167 		} else {
2168 			rc = SEPOL_ERR;
2169 			goto exit;
2170 		}
2171 	}
2172 
2173 	return SEPOL_OK;
2174 
2175 exit:
2176 	return rc;
2177 }
2178 
__cil_constrain_expr_to_sepol_expr_helper(policydb_t * pdb,const struct cil_db * db,const struct cil_list * cil_expr,constraint_expr_t ** head,constraint_expr_t ** tail)2179 int __cil_constrain_expr_to_sepol_expr_helper(policydb_t *pdb, const struct cil_db *db, const struct cil_list *cil_expr, constraint_expr_t **head, constraint_expr_t **tail)
2180 {
2181 	int rc = SEPOL_ERR;
2182 	struct cil_list_item *item;
2183 	enum cil_flavor flavor;
2184 	constraint_expr_t *op, *h1, *h2, *t1, *t2;
2185 	int is_leaf = CIL_FALSE;
2186 
2187 	if (cil_expr == NULL) {
2188 		return SEPOL_ERR;
2189 	}
2190 
2191 	item = cil_expr->head;
2192 	flavor = cil_expr->flavor;
2193 
2194 	op = cil_malloc(sizeof(constraint_expr_t));
2195 	rc = constraint_expr_init(op);
2196 	if (rc != SEPOL_OK) {
2197 		goto exit;
2198 	}
2199 
2200 	enum cil_flavor cil_op = (enum cil_flavor)item->data;
2201 	switch (cil_op) {
2202 	case CIL_NOT:
2203 		op->expr_type = CEXPR_NOT;
2204 		break;
2205 	case CIL_AND:
2206 		op->expr_type = CEXPR_AND;
2207 		break;
2208 	case CIL_OR:
2209 		op->expr_type = CEXPR_OR;
2210 		break;
2211 	case CIL_EQ:
2212 		op->op = CEXPR_EQ;
2213 		is_leaf = CIL_TRUE;
2214 		break;
2215 	case CIL_NEQ:
2216 		op->op = CEXPR_NEQ;
2217 		is_leaf = CIL_TRUE;
2218 		break;
2219 	case CIL_CONS_DOM:
2220 		op->op = CEXPR_DOM;
2221 		is_leaf = CIL_TRUE;
2222 		break;
2223 	case CIL_CONS_DOMBY:
2224 		op->op = CEXPR_DOMBY;
2225 		is_leaf = CIL_TRUE;
2226 		break;
2227 	case CIL_CONS_INCOMP:
2228 		op->op = CEXPR_INCOMP;
2229 		is_leaf = CIL_TRUE;
2230 		break;
2231 	default:
2232 		goto exit;
2233 	}
2234 
2235 	if (is_leaf == CIL_TRUE) {
2236 		rc = __cil_constrain_expr_leaf_to_sepol_expr(pdb, db, item, flavor, op);
2237 		if (rc != SEPOL_OK) {
2238 			goto exit;
2239 		}
2240 		*head = op;
2241 		*tail = op;
2242 	} else if (cil_op == CIL_NOT) {
2243 		struct cil_list *l_expr = item->next->data;
2244 		rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1);
2245 		if (rc != SEPOL_OK) {
2246 			goto exit;
2247 		}
2248 		t1->next = op;
2249 		*head = h1;
2250 		*tail = op;
2251 	} else {
2252 		struct cil_list *l_expr = item->next->data;
2253 		struct cil_list *r_expr = item->next->next->data;
2254 		rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1);
2255 		if (rc != SEPOL_OK) {
2256 			goto exit;
2257 		}
2258 		rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, r_expr, &h2, &t2);
2259 		if (rc != SEPOL_OK) {
2260 			constraint_expr_destroy(h1);
2261 			goto exit;
2262 		}
2263 		t1->next = h2;
2264 		t2->next = op;
2265 		*head = h1;
2266 		*tail = op;
2267 	}
2268 
2269 	return SEPOL_OK;
2270 
2271 exit:
2272 	constraint_expr_destroy(op);
2273 	return SEPOL_ERR;
2274 }
2275 
__cil_constrain_expr_to_sepol_expr(policydb_t * pdb,const struct cil_db * db,const struct cil_list * cil_expr,constraint_expr_t ** sepol_expr)2276 int __cil_constrain_expr_to_sepol_expr(policydb_t *pdb, const struct cil_db *db, const struct cil_list *cil_expr, constraint_expr_t **sepol_expr)
2277 {
2278 	int rc;
2279 	constraint_expr_t *head, *tail;
2280 
2281 	rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, cil_expr, &head, &tail);
2282 	if (rc != SEPOL_OK) {
2283 		return SEPOL_ERR;
2284 	}
2285 
2286 	*sepol_expr = head;
2287 
2288 	return SEPOL_OK;
2289 }
2290 
cil_constrain_to_policydb_helper(policydb_t * pdb,const struct cil_db * db,struct cil_symtab_datum * class,struct cil_list * perms,struct cil_list * expr)2291 int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *class, struct cil_list *perms, struct cil_list *expr)
2292 {
2293 	int rc = SEPOL_ERR;
2294 	constraint_node_t *sepol_constrain = NULL;
2295 	constraint_expr_t *sepol_expr = NULL;
2296 	class_datum_t *sepol_class = NULL;
2297 
2298 	sepol_constrain = cil_malloc(sizeof(*sepol_constrain));
2299 	memset(sepol_constrain, 0, sizeof(constraint_node_t));
2300 
2301 	rc = __cil_get_sepol_class_datum(pdb, class, &sepol_class);
2302 	if (rc != SEPOL_OK) goto exit;
2303 
2304 	rc = __cil_perms_to_datum(perms, sepol_class, &sepol_constrain->permissions);
2305 	if (rc != SEPOL_OK) {
2306 		goto exit;
2307 	}
2308 
2309 	rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr);
2310 	if (rc != SEPOL_OK) {
2311 		goto exit;
2312 	}
2313 
2314 	sepol_constrain->expr = sepol_expr;
2315 	sepol_constrain->next = sepol_class->constraints;
2316 	sepol_class->constraints = sepol_constrain;
2317 
2318 	return SEPOL_OK;
2319 
2320 exit:
2321 	free(sepol_constrain);
2322 	return rc;
2323 }
2324 
cil_constrain_expand(policydb_t * pdb,const struct cil_db * db,struct cil_list * classperms,struct cil_list * expr)2325 int cil_constrain_expand(policydb_t *pdb, const struct cil_db *db, struct cil_list *classperms, struct cil_list *expr)
2326 {
2327 	int rc = SEPOL_ERR;
2328 	struct cil_list_item *curr;
2329 
2330 	cil_list_for_each(curr, classperms) {
2331 		if (curr->flavor == CIL_CLASSPERMS) {
2332 			struct cil_classperms *cp = curr->data;
2333 			if (FLAVOR(cp->class) == CIL_CLASS) {
2334 				rc = cil_constrain_to_policydb_helper(pdb, db, DATUM(cp->class), cp->perms, expr);
2335 				if (rc != SEPOL_OK) {
2336 					goto exit;
2337 				}
2338 			} else { /* MAP */
2339 				struct cil_list_item *i = NULL;
2340 				cil_list_for_each(i, cp->perms) {
2341 					struct cil_perm *cmp = i->data;
2342 					rc = cil_constrain_expand(pdb, db, cmp->classperms, expr);
2343 					if (rc != SEPOL_OK) {
2344 						goto exit;
2345 					}
2346 				}
2347 			}
2348 		} else { /* SET */
2349 			struct cil_classperms_set *cp_set = curr->data;
2350 			struct cil_classpermission *cp = cp_set->set;
2351 			rc = cil_constrain_expand(pdb, db, cp->classperms, expr);
2352 			if (rc != SEPOL_OK) {
2353 				goto exit;
2354 			}
2355 		}
2356 	}
2357 
2358 	return SEPOL_OK;
2359 
2360 exit:
2361 	return rc;
2362 }
2363 
cil_constrain_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_constrain * cil_constrain)2364 int cil_constrain_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_constrain *cil_constrain)
2365 {
2366 	int rc = SEPOL_ERR;
2367 	rc = cil_constrain_expand(pdb, db, cil_constrain->classperms, cil_constrain->datum_expr);
2368 	if (rc != SEPOL_OK) {
2369 		goto exit;
2370 	}
2371 
2372 	return SEPOL_OK;
2373 
2374 exit:
2375 	cil_log(CIL_ERR, "Failed to insert constraint into policydb\n");
2376 	return rc;
2377 }
2378 
cil_validatetrans_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_validatetrans * cil_validatetrans)2379 int cil_validatetrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_validatetrans *cil_validatetrans)
2380 {
2381 	int rc = SEPOL_ERR;
2382 	struct cil_list *expr = cil_validatetrans->datum_expr;
2383 	class_datum_t *sepol_class = NULL;
2384 	struct cil_list *class_list;
2385 	constraint_node_t *sepol_validatetrans = NULL;
2386 	constraint_expr_t *sepol_expr = NULL;
2387 	struct cil_list_item *c;
2388 
2389 	class_list = cil_expand_class(cil_validatetrans->class);
2390 
2391 	cil_list_for_each(c, class_list) {
2392 		rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
2393 		if (rc != SEPOL_OK) goto exit;
2394 
2395 		sepol_validatetrans = cil_malloc(sizeof(*sepol_validatetrans));
2396 		memset(sepol_validatetrans, 0, sizeof(constraint_node_t));
2397 
2398 		rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr);
2399 		if (rc != SEPOL_OK) {
2400 			free(sepol_validatetrans);
2401 			goto exit;
2402 		}
2403 		sepol_validatetrans->expr = sepol_expr;
2404 
2405 		sepol_validatetrans->next = sepol_class->validatetrans;
2406 		sepol_class->validatetrans = sepol_validatetrans;
2407 	}
2408 
2409 	rc = SEPOL_OK;
2410 
2411 exit:
2412 	cil_list_destroy(&class_list, CIL_FALSE);
2413 	return rc;
2414 }
2415 
__cil_cats_to_mls_level(policydb_t * pdb,struct cil_cats * cats,mls_level_t * mls_level)2416 int __cil_cats_to_mls_level(policydb_t *pdb, struct cil_cats *cats, mls_level_t *mls_level)
2417 {
2418 	int rc = SEPOL_ERR;
2419 	struct cil_list_item *i;
2420 	cat_datum_t *sepol_cat = NULL;
2421 
2422 	cil_list_for_each(i, cats->datum_expr) {
2423 		struct cil_tree_node *node = DATUM(i->data)->nodes->head->data;
2424 		if (node->flavor == CIL_CATSET) {
2425 			struct cil_list_item *j;
2426 			struct cil_catset *cs = i->data;
2427 			cil_list_for_each(j, cs->cats->datum_expr) {
2428 				rc = __cil_get_sepol_cat_datum(pdb, j->data, &sepol_cat);
2429 				if (rc != SEPOL_OK) goto exit;
2430 
2431 				rc = ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1);
2432 				if (rc != SEPOL_OK) goto exit;
2433 			}
2434 		} else {
2435 			rc = __cil_get_sepol_cat_datum(pdb, i->data, &sepol_cat);
2436 			if (rc != SEPOL_OK) goto exit;
2437 
2438 			rc = ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1);
2439 			if (rc != SEPOL_OK) goto exit;
2440 		}
2441 	}
2442 
2443 	return SEPOL_OK;
2444 
2445 exit:
2446 	return SEPOL_ERR;
2447 }
2448 
cil_sepol_level_define(policydb_t * pdb,struct cil_sens * cil_sens)2449 int cil_sepol_level_define(policydb_t *pdb, struct cil_sens *cil_sens)
2450 {
2451 	int rc = SEPOL_ERR;
2452 	struct cil_list_item *curr;
2453 	level_datum_t *sepol_level = NULL;
2454 	mls_level_t *mls_level = NULL;
2455 
2456 	rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level);
2457 	if (rc != SEPOL_OK) goto exit;
2458 
2459 	mls_level = sepol_level->level;
2460 
2461 	ebitmap_init(&mls_level->cat);
2462 
2463 	if (cil_sens->cats_list) {
2464 		cil_list_for_each(curr, cil_sens->cats_list) {
2465 			struct cil_cats *cats = curr->data;
2466 			rc = __cil_cats_to_mls_level(pdb, cats, mls_level);
2467 			if (rc != SEPOL_OK) {
2468 				cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n");
2469 				goto exit;
2470 			}
2471 		}
2472 	}
2473 
2474 	sepol_level->defined = 1;
2475 
2476 	return SEPOL_OK;
2477 
2478 exit:
2479 	return rc;
2480 }
2481 
cil_level_to_mls_level(policydb_t * pdb,struct cil_level * cil_level,mls_level_t * mls_level)2482 int cil_level_to_mls_level(policydb_t *pdb, struct cil_level *cil_level, mls_level_t *mls_level)
2483 {
2484 	int rc = SEPOL_ERR;
2485 	struct cil_sens *cil_sens = cil_level->sens;
2486 	struct cil_cats *cats = cil_level->cats;
2487 	level_datum_t *sepol_level = NULL;
2488 
2489 	rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level);
2490 	if (rc != SEPOL_OK) goto exit;
2491 
2492 	mls_level->sens = sepol_level->level->sens;
2493 
2494 	ebitmap_init(&mls_level->cat);
2495 
2496 	if (cats != NULL) {
2497 		rc = __cil_cats_to_mls_level(pdb, cats, mls_level);
2498 		if (rc != SEPOL_OK) {
2499 			cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n");
2500 			goto exit;
2501 		}
2502 	}
2503 
2504 	rc = SEPOL_OK;
2505 exit:
2506 	return rc;
2507 }
2508 
__cil_levelrange_to_mls_range(policydb_t * pdb,struct cil_levelrange * cil_lvlrange,mls_range_t * mls_range)2509 int __cil_levelrange_to_mls_range(policydb_t *pdb, struct cil_levelrange *cil_lvlrange, mls_range_t *mls_range)
2510 {
2511 	int rc = SEPOL_ERR;
2512 	struct cil_level *low = cil_lvlrange->low;
2513 	struct cil_level *high = cil_lvlrange->high;
2514 	mls_level_t *mls_level = NULL;
2515 
2516 	mls_level = &mls_range->level[0];
2517 
2518 	rc = cil_level_to_mls_level(pdb, low, mls_level);
2519 	if (rc != SEPOL_OK) {
2520 		goto exit;
2521 	}
2522 
2523 	mls_level = &mls_range->level[1];
2524 
2525 	rc = cil_level_to_mls_level(pdb, high, mls_level);
2526 	if (rc != SEPOL_OK) {
2527 		goto exit;
2528 	}
2529 
2530 	return SEPOL_OK;
2531 
2532 exit:
2533 	return rc;
2534 }
2535 
cil_userlevel_userrange_to_policydb(policydb_t * pdb,struct cil_user * cil_user)2536 int cil_userlevel_userrange_to_policydb(policydb_t *pdb, struct cil_user *cil_user)
2537 {
2538 	int rc = SEPOL_ERR;
2539 	struct cil_level *cil_level = cil_user->dftlevel;
2540 	struct cil_levelrange *cil_levelrange = cil_user->range;
2541 	user_datum_t *sepol_user = NULL;
2542 
2543 	rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user);
2544 	if (rc != SEPOL_OK) goto exit;
2545 
2546 	rc = cil_level_to_mls_level(pdb, cil_level, &sepol_user->exp_dfltlevel);
2547 	if (rc != SEPOL_OK) {
2548 		goto exit;
2549 	}
2550 
2551 	rc = __cil_levelrange_to_mls_range(pdb, cil_levelrange, &sepol_user->exp_range);
2552 	if (rc != SEPOL_OK) {
2553 		goto exit;
2554 	}
2555 
2556 	return SEPOL_OK;
2557 
2558 exit:
2559 	return rc;
2560 }
2561 
__cil_context_to_sepol_context(policydb_t * pdb,struct cil_context * cil_context,context_struct_t * sepol_context)2562 int __cil_context_to_sepol_context(policydb_t *pdb, struct cil_context *cil_context, context_struct_t *sepol_context)
2563 {
2564 	int rc = SEPOL_ERR;
2565 	struct cil_levelrange *cil_lvlrange = cil_context->range;
2566 	user_datum_t *sepol_user = NULL;
2567 	role_datum_t *sepol_role = NULL;
2568 	type_datum_t *sepol_type = NULL;
2569 
2570 	rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_context->user), &sepol_user);
2571 	if (rc != SEPOL_OK) goto exit;
2572 
2573 	rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_context->role), &sepol_role);
2574 	if (rc != SEPOL_OK) goto exit;
2575 
2576 	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_context->type), &sepol_type);
2577 	if (rc != SEPOL_OK) goto exit;
2578 
2579 	sepol_context->user = sepol_user->s.value;
2580 	sepol_context->role = sepol_role->s.value;
2581 	sepol_context->type = sepol_type->s.value;
2582 
2583 	if (pdb->mls == CIL_TRUE) {
2584 		mls_context_init(sepol_context);
2585 
2586 		rc = __cil_levelrange_to_mls_range(pdb, cil_lvlrange, &sepol_context->range);
2587 		if (rc != SEPOL_OK) {
2588 			cil_log(CIL_ERR,"Problem with MLS\n");
2589 			mls_context_destroy(sepol_context);
2590 			goto exit;
2591 		}
2592 	}
2593 
2594 	return SEPOL_OK;
2595 
2596 exit:
2597 	return rc;
2598 }
2599 
cil_sidorder_to_policydb(policydb_t * pdb,const struct cil_db * db)2600 int cil_sidorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
2601 {
2602 	int rc = SEPOL_ERR;
2603 	struct cil_list_item *curr;
2604 	unsigned count = 0;
2605 	ocontext_t *tail = NULL;
2606 
2607 	if (db->sidorder == NULL || db->sidorder->head == NULL) {
2608 		cil_log(CIL_WARN, "No sidorder statement in policy\n");
2609 		return SEPOL_OK;
2610 	}
2611 
2612 	cil_list_for_each(curr, db->sidorder) {
2613 		struct cil_sid *cil_sid = (struct cil_sid*)curr->data;
2614 		struct cil_context *cil_context = cil_sid->context;
2615 
2616 		if (cil_context != NULL) {
2617 			ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_ISID], &tail);
2618 			count++;
2619 			new_ocon->sid[0] = count;
2620 			new_ocon->u.name = cil_strdup(cil_sid->datum.fqn);
2621 			rc = __cil_context_to_sepol_context(pdb, cil_context, &new_ocon->context[0]);
2622 			if (rc != SEPOL_OK) {
2623 				cil_log(CIL_ERR,"Problem with context for SID %s\n",cil_sid->datum.fqn);
2624 				goto exit;
2625 			}
2626 		}
2627 	}
2628 
2629 	return SEPOL_OK;
2630 
2631 exit:
2632 	return rc;
2633 }
2634 
cil_rangetransition_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_rangetransition * rangetrans,hashtab_t range_trans_table)2635 int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans, hashtab_t range_trans_table)
2636 {
2637 	int rc = SEPOL_ERR;
2638 	type_datum_t *sepol_src = NULL;
2639 	type_datum_t *sepol_tgt = NULL;
2640 	class_datum_t *sepol_class = NULL;
2641 	struct cil_list *class_list;
2642 	range_trans_t *new;
2643 	ebitmap_t src_bitmap, tgt_bitmap;
2644 	ebitmap_node_t *node1, *node2;
2645 	unsigned int i, j;
2646 	struct cil_list_item *c;
2647 	struct mls_range *o_range = NULL;
2648 
2649 	rc = __cil_expand_type(rangetrans->src, &src_bitmap);
2650 	if (rc != SEPOL_OK) goto exit;
2651 
2652 	rc = __cil_expand_type(rangetrans->exec, &tgt_bitmap);
2653 	if (rc != SEPOL_OK) goto exit;
2654 
2655 	class_list = cil_expand_class(rangetrans->obj);
2656 
2657 	ebitmap_for_each_bit(&src_bitmap, node1, i) {
2658 		if (!ebitmap_get_bit(&src_bitmap, i)) continue;
2659 
2660 		rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src);
2661 		if (rc != SEPOL_OK) goto exit;
2662 
2663 		ebitmap_for_each_bit(&tgt_bitmap, node2, j) {
2664 			if (!ebitmap_get_bit(&tgt_bitmap, j)) continue;
2665 
2666 			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
2667 			if (rc != SEPOL_OK) goto exit;
2668 
2669 			cil_list_for_each(c, class_list) {
2670 				int add = CIL_TRUE;
2671 				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
2672 				if (rc != SEPOL_OK) goto exit;
2673 
2674 				new = cil_malloc(sizeof(*new));
2675 				memset(new, 0, sizeof(range_trans_t));
2676 				new->source_type = sepol_src->s.value;
2677 				new->target_type = sepol_tgt->s.value;
2678 				new->target_class = sepol_class->s.value;
2679 				rc = __cil_levelrange_to_mls_range(pdb, rangetrans->range, &new->target_range);
2680 				if (rc != SEPOL_OK) {
2681 					free(new);
2682 					goto exit;
2683 				}
2684 
2685 				rc = SEPOL_OK;
2686 				rc = hashtab_insert(range_trans_table, (hashtab_key_t)new, &(new->target_range));
2687 				if (rc != SEPOL_OK) {
2688 					if (rc == SEPOL_EEXIST) {
2689 						add = CIL_FALSE;
2690 						o_range = hashtab_search(range_trans_table, (hashtab_key_t)new);
2691 						if (!mls_range_eq(&new->target_range, o_range)) {
2692 							cil_log(CIL_ERR, "Conflicting Range transition rules\n");
2693 						} else {
2694 							rc = SEPOL_OK;
2695 						}
2696 					} else {
2697 						cil_log(CIL_ERR, "Out of memory\n");
2698 					}
2699 				}
2700 
2701 				if (add == CIL_TRUE) {
2702 					new->next = pdb->range_tr;
2703 					pdb->range_tr = new;
2704 				} else {
2705 					mls_range_destroy(&new->target_range);
2706 					free(new);
2707 					if (rc != SEPOL_OK) {
2708 						goto exit;
2709 					}
2710 				}
2711 			}
2712 		}
2713 	}
2714 
2715 	rc = SEPOL_OK;
2716 
2717 exit:
2718 	ebitmap_destroy(&src_bitmap);
2719 	ebitmap_destroy(&tgt_bitmap);
2720 	cil_list_destroy(&class_list, CIL_FALSE);
2721 	return rc;
2722 }
2723 
cil_portcon_to_policydb(policydb_t * pdb,struct cil_sort * portcons)2724 int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons)
2725 {
2726 	int rc = SEPOL_ERR;
2727 	uint32_t i = 0;
2728 	ocontext_t *tail = NULL;
2729 
2730 	for (i = 0; i < portcons->count; i++) {
2731 		struct cil_portcon *cil_portcon = portcons->array[i];
2732 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_PORT], &tail);
2733 
2734 		switch (cil_portcon->proto) {
2735 		case CIL_PROTOCOL_UDP:
2736 			new_ocon->u.port.protocol = IPPROTO_UDP;
2737 			break;
2738 		case CIL_PROTOCOL_TCP:
2739 			new_ocon->u.port.protocol = IPPROTO_TCP;
2740 			break;
2741 		default:
2742 			/* should not get here */
2743 			rc = SEPOL_ERR;
2744 			goto exit;
2745 		}
2746 
2747 		new_ocon->u.port.low_port = cil_portcon->port_low;
2748 		new_ocon->u.port.high_port = cil_portcon->port_high;
2749 
2750 		rc = __cil_context_to_sepol_context(pdb, cil_portcon->context, &new_ocon->context[0]);
2751 		if (rc != SEPOL_OK) {
2752 			goto exit;
2753 		}
2754 	}
2755 
2756 	return SEPOL_OK;
2757 
2758 exit:
2759 	return rc;
2760 }
2761 
cil_netifcon_to_policydb(policydb_t * pdb,struct cil_sort * netifcons)2762 int cil_netifcon_to_policydb(policydb_t *pdb, struct cil_sort *netifcons)
2763 {
2764 	int rc = SEPOL_ERR;
2765 	uint32_t i = 0;
2766 	ocontext_t *tail = NULL;
2767 
2768 	for (i = 0; i < netifcons->count; i++) {
2769 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NETIF], &tail);
2770 		struct cil_netifcon *cil_netifcon = netifcons->array[i];
2771 
2772 		new_ocon->u.name = cil_strdup(cil_netifcon->interface_str);
2773 
2774 		rc = __cil_context_to_sepol_context(pdb, cil_netifcon->if_context, &new_ocon->context[0]);
2775 		if (rc != SEPOL_OK) {
2776 			goto exit;
2777 		}
2778 
2779 		rc = __cil_context_to_sepol_context(pdb, cil_netifcon->packet_context, &new_ocon->context[1]);
2780 		if (rc != SEPOL_OK) {
2781 			context_destroy(&new_ocon->context[0]);
2782 			goto exit;
2783 		}
2784 	}
2785 
2786 	return SEPOL_OK;
2787 
2788 exit:
2789 	return rc;
2790 }
2791 
cil_nodecon_to_policydb(policydb_t * pdb,struct cil_sort * nodecons)2792 int cil_nodecon_to_policydb(policydb_t *pdb, struct cil_sort *nodecons)
2793 {
2794 	int rc = SEPOL_ERR;
2795 	uint32_t i = 0;
2796 	ocontext_t *tail = NULL;
2797 	ocontext_t *tail6 = NULL;
2798 
2799 	for (i = 0; i < nodecons->count; i++) {
2800 		ocontext_t *new_ocon = NULL;
2801 		struct cil_nodecon *cil_nodecon = nodecons->array[i];
2802 
2803 		if (cil_nodecon->addr->family == AF_INET) {
2804 			new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE], &tail);
2805 			new_ocon->u.node.addr = cil_nodecon->addr->ip.v4.s_addr;
2806 			new_ocon->u.node.mask = cil_nodecon->mask->ip.v4.s_addr;
2807 		} else if (cil_nodecon->addr->family == AF_INET6) {
2808 			new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE6], &tail6);
2809 			memcpy(new_ocon->u.node6.addr, &cil_nodecon->addr->ip.v6.s6_addr[0], 16);
2810 			memcpy(new_ocon->u.node6.mask, &cil_nodecon->mask->ip.v6.s6_addr[0], 16);
2811 		} else {
2812 			/* should not get here */
2813 			rc = SEPOL_ERR;
2814 			goto exit;
2815 		}
2816 
2817 		rc = __cil_context_to_sepol_context(pdb, cil_nodecon->context, &new_ocon->context[0]);
2818 		if (rc != SEPOL_OK) {
2819 			goto exit;
2820 		}
2821 	}
2822 
2823 	return SEPOL_OK;
2824 
2825 exit:
2826 	return rc;
2827 }
2828 
cil_fsuse_to_policydb(policydb_t * pdb,struct cil_sort * fsuses)2829 int cil_fsuse_to_policydb(policydb_t *pdb, struct cil_sort *fsuses)
2830 {
2831 	int rc = SEPOL_ERR;
2832 	uint32_t i = 0;
2833 	ocontext_t *tail = NULL;
2834 
2835 	for (i = 0; i < fsuses->count; i++) {
2836 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_FSUSE], &tail);
2837 		struct cil_fsuse *cil_fsuse = fsuses->array[i];
2838 
2839 		new_ocon->u.name = cil_strdup(cil_fsuse->fs_str);
2840 		new_ocon->v.behavior = cil_fsuse->type;
2841 
2842 		rc = __cil_context_to_sepol_context(pdb, cil_fsuse->context, &new_ocon->context[0]);
2843 		if (rc != SEPOL_OK) {
2844 			goto exit;
2845 		}
2846 	}
2847 
2848 	return SEPOL_OK;
2849 
2850 exit:
2851 	return rc;
2852 }
2853 
cil_genfscon_to_policydb(policydb_t * pdb,struct cil_sort * genfscons)2854 int cil_genfscon_to_policydb(policydb_t *pdb, struct cil_sort *genfscons)
2855 {
2856 	int rc = SEPOL_ERR;
2857 	uint32_t i = 0;
2858 	genfs_t *genfs_tail = NULL;
2859 	ocontext_t *ocon_tail = NULL;
2860 
2861 	for (i = 0; i < genfscons->count; i++) {
2862 		struct cil_genfscon *cil_genfscon = genfscons->array[i];
2863 		ocontext_t *new_ocon = cil_malloc(sizeof(ocontext_t));
2864 		memset(new_ocon, 0, sizeof(ocontext_t));
2865 
2866 		if (genfs_tail && strcmp(genfs_tail->fstype, cil_genfscon->fs_str) == 0) {
2867 			ocon_tail->next = new_ocon;
2868 		} else {
2869 			genfs_t *new_genfs = cil_malloc(sizeof(genfs_t));
2870 			memset(new_genfs, 0, sizeof(genfs_t));
2871 			new_genfs->fstype = cil_strdup(cil_genfscon->fs_str);
2872 			new_genfs->head = new_ocon;
2873 
2874 			if (genfs_tail) {
2875 				genfs_tail->next = new_genfs;
2876 			} else {
2877 				pdb->genfs = new_genfs;
2878 			}
2879 			genfs_tail = new_genfs;
2880 		}
2881 
2882 		ocon_tail = new_ocon;
2883 
2884 		new_ocon->u.name = cil_strdup(cil_genfscon->path_str);
2885 
2886 		rc = __cil_context_to_sepol_context(pdb, cil_genfscon->context, &new_ocon->context[0]);
2887 		if (rc != SEPOL_OK) {
2888 			goto exit;
2889 		}
2890 	}
2891 
2892 	return SEPOL_OK;
2893 
2894 exit:
2895 	return rc;
2896 }
2897 
cil_pirqcon_to_policydb(policydb_t * pdb,struct cil_sort * pirqcons)2898 int cil_pirqcon_to_policydb(policydb_t *pdb, struct cil_sort *pirqcons)
2899 {
2900 	int rc = SEPOL_ERR;
2901 	uint32_t i = 0;
2902 	ocontext_t *tail = NULL;
2903 
2904 	for (i = 0; i < pirqcons->count; i++) {
2905 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PIRQ], &tail);
2906 		struct cil_pirqcon *cil_pirqcon = pirqcons->array[i];
2907 
2908 		new_ocon->u.pirq = cil_pirqcon->pirq;
2909 
2910 		rc = __cil_context_to_sepol_context(pdb, cil_pirqcon->context, &new_ocon->context[0]);
2911 		if (rc != SEPOL_OK) {
2912 			goto exit;
2913 		}
2914 	}
2915 
2916 	return SEPOL_OK;
2917 
2918 exit:
2919 	return rc;
2920 }
2921 
cil_iomemcon_to_policydb(policydb_t * pdb,struct cil_sort * iomemcons)2922 int cil_iomemcon_to_policydb(policydb_t *pdb, struct cil_sort *iomemcons)
2923 {
2924 	int rc = SEPOL_ERR;
2925 	uint32_t i = 0;
2926 	ocontext_t *tail = NULL;
2927 
2928 	for (i = 0; i < iomemcons->count; i++) {
2929 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOMEM], &tail);
2930 		struct cil_iomemcon *cil_iomemcon = iomemcons->array[i];
2931 
2932 		new_ocon->u.iomem.low_iomem = cil_iomemcon->iomem_low;
2933 		new_ocon->u.iomem.high_iomem = cil_iomemcon->iomem_high;
2934 
2935 		rc = __cil_context_to_sepol_context(pdb, cil_iomemcon->context, &new_ocon->context[0]);
2936 		if (rc != SEPOL_OK) {
2937 			goto exit;
2938 		}
2939 	}
2940 
2941 	return SEPOL_OK;
2942 
2943 exit:
2944 	return rc;
2945 }
2946 
cil_ioportcon_to_policydb(policydb_t * pdb,struct cil_sort * ioportcons)2947 int cil_ioportcon_to_policydb(policydb_t *pdb, struct cil_sort *ioportcons)
2948 {
2949 	int rc = SEPOL_ERR;
2950 	uint32_t i = 0;
2951 	ocontext_t *tail = NULL;
2952 
2953 	for (i = 0; i < ioportcons->count; i++) {
2954 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOPORT], &tail);
2955 		struct cil_ioportcon *cil_ioportcon = ioportcons->array[i];
2956 
2957 		new_ocon->u.ioport.low_ioport = cil_ioportcon->ioport_low;
2958 		new_ocon->u.ioport.high_ioport = cil_ioportcon->ioport_high;
2959 
2960 		rc = __cil_context_to_sepol_context(pdb, cil_ioportcon->context, &new_ocon->context[0]);
2961 		if (rc != SEPOL_OK) {
2962 			goto exit;
2963 		}
2964 	}
2965 
2966 	return SEPOL_OK;
2967 
2968 exit:
2969 	return rc;
2970 }
2971 
cil_pcidevicecon_to_policydb(policydb_t * pdb,struct cil_sort * pcidevicecons)2972 int cil_pcidevicecon_to_policydb(policydb_t *pdb, struct cil_sort *pcidevicecons)
2973 {
2974 	int rc = SEPOL_ERR;
2975 	uint32_t i = 0;
2976 	ocontext_t *tail = NULL;
2977 
2978 	for (i = 0; i < pcidevicecons->count; i++) {
2979 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PCIDEVICE], &tail);
2980 		struct cil_pcidevicecon *cil_pcidevicecon = pcidevicecons->array[i];
2981 
2982 		new_ocon->u.device = cil_pcidevicecon->dev;
2983 
2984 		rc = __cil_context_to_sepol_context(pdb, cil_pcidevicecon->context, &new_ocon->context[0]);
2985 		if (rc != SEPOL_OK) {
2986 			goto exit;
2987 		}
2988 	}
2989 
2990 	return SEPOL_OK;
2991 
2992 exit:
2993 	return rc;
2994 }
2995 
cil_devicetreecon_to_policydb(policydb_t * pdb,struct cil_sort * devicetreecons)2996 int cil_devicetreecon_to_policydb(policydb_t *pdb, struct cil_sort *devicetreecons)
2997 {
2998 	int rc = SEPOL_ERR;
2999 	uint32_t i = 0;
3000 	ocontext_t *tail = NULL;
3001 
3002 	for (i = 0; i < devicetreecons->count; i++) {
3003 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_DEVICETREE], &tail);
3004 		struct cil_devicetreecon *cil_devicetreecon = devicetreecons->array[i];
3005 
3006 		new_ocon->u.name = cil_strdup(cil_devicetreecon->path);
3007 
3008 		rc = __cil_context_to_sepol_context(pdb, cil_devicetreecon->context, &new_ocon->context[0]);
3009 		if (rc != SEPOL_OK) {
3010 			goto exit;
3011 		}
3012 	}
3013 
3014 	return SEPOL_OK;
3015 
3016 exit:
3017 	return rc;
3018 }
3019 
cil_default_to_policydb(policydb_t * pdb,struct cil_default * def)3020 int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def)
3021 {
3022 	struct cil_list_item *curr;
3023 	class_datum_t *sepol_class;
3024 	struct cil_list *class_list;
3025 
3026 	cil_list_for_each(curr, def->class_datums) {
3027 		struct cil_list_item *c;
3028 
3029 		class_list = cil_expand_class(curr->data);
3030 
3031 		cil_list_for_each(c, class_list) {
3032 			int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
3033 			if (rc != SEPOL_OK) goto exit;
3034 
3035 			switch (def->flavor) {
3036 			case CIL_DEFAULTUSER:
3037 				if (!sepol_class->default_user) {
3038 					sepol_class->default_user = def->object;
3039 				} else if (sepol_class->default_user != (char)def->object) {
3040 					cil_log(CIL_ERR,"User default labeling for class %s already specified\n",DATUM(c->data)->fqn);
3041 					goto exit;
3042 				}
3043 				break;
3044 			case CIL_DEFAULTROLE:
3045 				if (!sepol_class->default_role) {
3046 					sepol_class->default_role = def->object;
3047 				} else if (sepol_class->default_role != (char)def->object) {
3048 					cil_log(CIL_ERR,"Role default labeling for class %s already specified\n",DATUM(c->data)->fqn);
3049 					goto exit;
3050 				}
3051 				break;
3052 			case CIL_DEFAULTTYPE:
3053 				if (!sepol_class->default_type) {
3054 					sepol_class->default_type = def->object;
3055 				} else if (sepol_class->default_type != (char)def->object) {
3056 					cil_log(CIL_ERR,"Type default labeling for class %s already specified\n",DATUM(c->data)->fqn);
3057 					goto exit;
3058 				}
3059 				break;
3060 			default:
3061 				goto exit;
3062 			}
3063 		}
3064 
3065 		cil_list_destroy(&class_list, CIL_FALSE);
3066 	}
3067 
3068 	return SEPOL_OK;
3069 
3070 exit:
3071 	cil_list_destroy(&class_list, CIL_FALSE);
3072 	return SEPOL_ERR;
3073 }
3074 
cil_defaultrange_to_policydb(policydb_t * pdb,struct cil_defaultrange * def)3075 int cil_defaultrange_to_policydb(policydb_t *pdb, struct cil_defaultrange *def)
3076 {
3077 	struct cil_list_item *curr;
3078 	class_datum_t *sepol_class;
3079 	struct cil_list *class_list;
3080 
3081 	cil_list_for_each(curr, def->class_datums) {
3082 		struct cil_list_item *c;
3083 
3084 		class_list = cil_expand_class(curr->data);
3085 
3086 		cil_list_for_each(c, class_list) {
3087 			int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
3088 			if (rc != SEPOL_OK) goto exit;
3089 
3090 			if (!sepol_class->default_range) {
3091 				sepol_class->default_range = def->object_range;
3092 			} else if (sepol_class->default_range != (char)def->object_range) {
3093 				cil_log(CIL_ERR,"Range default labeling for class %s already specified\n", DATUM(curr->data)->fqn);
3094 				goto exit;
3095 			}
3096 		}
3097 
3098 		cil_list_destroy(&class_list, CIL_FALSE);
3099 	}
3100 
3101 	return SEPOL_OK;
3102 
3103 exit:
3104 	cil_list_destroy(&class_list, CIL_FALSE);
3105 	return SEPOL_ERR;
3106 }
3107 
__cil_node_to_policydb(struct cil_tree_node * node,void * extra_args)3108 int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
3109 {
3110 	int rc = SEPOL_OK;
3111 	int pass;
3112 	struct cil_args_binary *args = extra_args;
3113 	const struct cil_db *db;
3114 	policydb_t *pdb;
3115 	hashtab_t filename_trans_table;
3116 	hashtab_t range_trans_table;
3117 	hashtab_t role_trans_table;
3118 	db = args->db;
3119 	pdb = args->pdb;
3120 	pass = args->pass;
3121 	filename_trans_table = args->filename_trans_table;
3122 	range_trans_table = args->range_trans_table;
3123 	role_trans_table = args->role_trans_table;
3124 
3125 	if (node->flavor >= CIL_MIN_DECLARATIVE) {
3126 		if (node != DATUM(node->data)->nodes->head->data) {
3127 			goto exit;
3128 		}
3129 	}
3130 
3131 	switch (pass) {
3132 	case 1:
3133 		switch (node->flavor) {
3134 		case CIL_ROLE:
3135 			rc = cil_role_to_policydb(pdb, node->data);
3136 			break;
3137 		case CIL_TYPE:
3138 			rc = cil_type_to_policydb(pdb, node->data);
3139 			break;
3140 		case CIL_TYPEATTRIBUTE:
3141 			rc = cil_typeattribute_to_policydb(pdb, node->data);
3142 			break;
3143 		case CIL_POLICYCAP:
3144 			rc = cil_policycap_to_policydb(pdb, node->data);
3145 			break;
3146 		case CIL_USER:
3147 			rc = cil_user_to_policydb(pdb, node->data);
3148 			break;
3149 		case CIL_BOOL:
3150 			rc = cil_bool_to_policydb(pdb, node->data);
3151 			break;
3152 		case CIL_CATALIAS:
3153 			if (pdb->mls == CIL_TRUE) {
3154 				rc = cil_catalias_to_policydb(pdb, node->data);
3155 			}
3156 			break;
3157 		case CIL_SENS:
3158 			if (pdb->mls == CIL_TRUE) {
3159 				rc = cil_sepol_level_define(pdb, node->data);
3160 			}
3161 			break;
3162 		default:
3163 			break;
3164 		}
3165 		break;
3166 	case 2:
3167 		switch (node->flavor) {
3168 		case CIL_TYPE:
3169 			rc = cil_type_bounds_to_policydb(pdb, node->data);
3170 			break;
3171 		case CIL_TYPEALIAS:
3172 			rc = cil_typealias_to_policydb(pdb, node->data);
3173 			break;
3174 		case CIL_TYPEPERMISSIVE:
3175 			rc = cil_typepermissive_to_policydb(pdb, node->data);
3176 			break;
3177 		case CIL_TYPEATTRIBUTE:
3178 			rc = cil_typeattribute_to_bitmap(pdb, db, node->data);
3179 			break;
3180 		case CIL_SENSALIAS:
3181 			if (pdb->mls == CIL_TRUE) {
3182 				rc = cil_sensalias_to_policydb(pdb, node->data);
3183 			}
3184 			break;
3185 		case CIL_ROLE:
3186 			rc = cil_role_bounds_to_policydb(pdb, node->data);
3187 			if (rc != SEPOL_OK) goto exit;
3188 			rc = cil_roletype_to_policydb(pdb, db, node->data);
3189 			break;
3190 		case CIL_USER:
3191 			rc = cil_user_bounds_to_policydb(pdb, node->data);
3192 			if (rc != SEPOL_OK) goto exit;
3193 			if (pdb->mls == CIL_TRUE) {
3194 				rc = cil_userlevel_userrange_to_policydb(pdb, node->data);
3195 			}
3196 			break;
3197 		case CIL_USERROLE:
3198 			rc = cil_userrole_to_policydb(pdb, db, node->data);
3199 			break;
3200 		case CIL_TYPE_RULE:
3201 			rc = cil_type_rule_to_policydb(pdb, db, node->data);
3202 			break;
3203 		case CIL_AVRULE: {
3204 			struct cil_avrule *rule = node->data;
3205 			struct cil_list *neverallows = args->neverallows;
3206 			if (rule->rule_kind == CIL_AVRULE_NEVERALLOW) {
3207 				struct cil_neverallow *new_rule = NULL;
3208 
3209 				new_rule = cil_malloc(sizeof(*new_rule));
3210 				cil_list_init(&new_rule->rules, CIL_LIST_ITEM);
3211 				new_rule->node = node;
3212 
3213 				cil_list_prepend(neverallows, CIL_LIST_ITEM, new_rule);
3214 
3215 				rc = cil_avrule_to_policydb(pdb, db, node->data, neverallows);
3216 			}
3217 			break;
3218 		}
3219 		case CIL_ROLETRANSITION:
3220 			rc = cil_roletrans_to_policydb(pdb, db, node->data, role_trans_table);
3221 			break;
3222 		case CIL_ROLEATTRIBUTESET:
3223 		  /*rc = cil_roleattributeset_to_policydb(pdb, node->data);*/
3224 			break;
3225 		case CIL_NAMETYPETRANSITION:
3226 			rc = cil_typetransition_to_policydb(pdb, db, node->data, filename_trans_table);
3227 			break;
3228 		case CIL_CONSTRAIN:
3229 			rc = cil_constrain_to_policydb(pdb, db, node->data);
3230 			break;
3231 		case CIL_MLSCONSTRAIN:
3232 			if (pdb->mls == CIL_TRUE) {
3233 				rc = cil_constrain_to_policydb(pdb, db, node->data);
3234 			}
3235 			break;
3236 		case CIL_VALIDATETRANS:
3237 			rc = cil_validatetrans_to_policydb(pdb, db, node->data);
3238 			break;
3239 		case CIL_MLSVALIDATETRANS:
3240 			if (pdb->mls == CIL_TRUE) {
3241 				rc = cil_validatetrans_to_policydb(pdb, db, node->data);
3242 			}
3243 			break;
3244 		case CIL_RANGETRANSITION:
3245 			if (pdb->mls == CIL_TRUE) {
3246 				rc = cil_rangetransition_to_policydb(pdb, db, node->data, range_trans_table);
3247 			}
3248 			break;
3249 		case CIL_DEFAULTUSER:
3250 		case CIL_DEFAULTROLE:
3251 		case CIL_DEFAULTTYPE:
3252 			rc = cil_default_to_policydb(pdb, node->data);
3253 			break;
3254 		case CIL_DEFAULTRANGE:
3255 			rc = cil_defaultrange_to_policydb(pdb, node->data);
3256 			break;
3257 		default:
3258 			break;
3259 		}
3260 		break;
3261 	case 3:
3262 		switch (node->flavor) {
3263 		case CIL_BOOLEANIF:
3264 			rc = cil_booleanif_to_policydb(pdb, db, node, args->neverallows, filename_trans_table);
3265 			break;
3266 		case CIL_AVRULE: {
3267 				struct cil_avrule *rule = node->data;
3268 				if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) {
3269 					rc = cil_avrule_to_policydb(pdb, db, node->data, args->neverallows);
3270 				}
3271 			}
3272 			break;
3273 		case CIL_ROLEALLOW:
3274 			rc = cil_roleallow_to_policydb(pdb, db, node->data);
3275 			break;
3276 		default:
3277 			break;
3278 		}
3279 	default:
3280 		break;
3281 	}
3282 
3283 exit:
3284 	if (rc != SEPOL_OK) {
3285 		cil_log(CIL_ERR, "Binary policy creation failed at line %d of %s\n", node->line, node->path);
3286 	}
3287 	return rc;
3288 }
3289 
__cil_binary_create_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)3290 int __cil_binary_create_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
3291 {
3292 	int rc = SEPOL_ERR;
3293 
3294 	if (node->flavor == CIL_BLOCK) {
3295 		struct cil_block *blk = node->data;
3296 		if (blk->is_abstract == CIL_TRUE) {
3297 			*finished = CIL_TREE_SKIP_HEAD;
3298 			rc = SEPOL_OK;
3299 			goto exit;
3300 		}
3301 	} else if (node->flavor == CIL_MACRO) {
3302 		*finished = CIL_TREE_SKIP_HEAD;
3303 		rc = SEPOL_OK;
3304 		goto exit;
3305 	} else if (node->flavor == CIL_BOOLEANIF) {
3306 		*finished = CIL_TREE_SKIP_HEAD;
3307 	}
3308 
3309 	rc = __cil_node_to_policydb(node, extra_args);
3310 	if (rc != SEPOL_OK) {
3311 		goto exit;
3312 	}
3313 
3314 exit:
3315 	return rc;
3316 }
3317 
__cil_contexts_to_policydb(policydb_t * pdb,const struct cil_db * db)3318 int __cil_contexts_to_policydb(policydb_t *pdb, const struct cil_db *db)
3319 {
3320 	int rc = SEPOL_ERR;
3321 
3322 	rc = cil_portcon_to_policydb(pdb, db->portcon);
3323 	if (rc != SEPOL_OK) {
3324 		goto exit;
3325 	}
3326 
3327 	rc = cil_netifcon_to_policydb(pdb, db->netifcon);
3328 	if (rc != SEPOL_OK) {
3329 		goto exit;
3330 	}
3331 
3332 	rc = cil_nodecon_to_policydb(pdb, db->nodecon);
3333 	if (rc != SEPOL_OK) {
3334 		goto exit;
3335 	}
3336 
3337 	rc = cil_fsuse_to_policydb(pdb, db->fsuse);
3338 	if (rc != SEPOL_OK) {
3339 		goto exit;
3340 	}
3341 
3342 	rc = cil_genfscon_to_policydb(pdb, db->genfscon);
3343 	if (rc != SEPOL_OK) {
3344 		goto exit;
3345 	}
3346 
3347 	if (db->target_platform == SEPOL_TARGET_XEN) {
3348 		rc = cil_pirqcon_to_policydb(pdb, db->pirqcon);
3349 		if (rc != SEPOL_OK) {
3350 			goto exit;
3351 		}
3352 
3353 		rc = cil_iomemcon_to_policydb(pdb, db->iomemcon);
3354 		if (rc != SEPOL_OK) {
3355 			goto exit;
3356 		}
3357 
3358 		rc = cil_ioportcon_to_policydb(pdb, db->ioportcon);
3359 		if (rc != SEPOL_OK) {
3360 			goto exit;
3361 		}
3362 
3363 		rc = cil_pcidevicecon_to_policydb(pdb, db->pcidevicecon);
3364 		if (rc != SEPOL_OK) {
3365 			goto exit;
3366 		}
3367 
3368 		rc = cil_devicetreecon_to_policydb(pdb, db->devicetreecon);
3369 		if (rc != SEPOL_OK) {
3370 			goto exit;
3371 		}
3372 	}
3373 	return SEPOL_OK;
3374 exit:
3375 	return rc;
3376 }
3377 
__cil_common_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3378 int __cil_common_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3379 {
3380 	policydb_t *pdb = data;
3381 	common_datum_t *common = (common_datum_t *)datum;
3382 
3383 	if (common->s.value < 1 || common->s.value > pdb->p_commons.nprim) {
3384 		return -EINVAL;
3385 	}
3386 	pdb->p_common_val_to_name[common->s.value - 1] = (char *)key;
3387 
3388 	return 0;
3389 }
3390 
__cil_class_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3391 int __cil_class_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3392 {
3393 	policydb_t *pdb = data;
3394 	class_datum_t *class = (class_datum_t *)datum;
3395 
3396 	if (class->s.value < 1 || class->s.value > pdb->p_classes.nprim) {
3397 		return -EINVAL;
3398 	}
3399 	pdb->p_class_val_to_name[class->s.value - 1] = (char *)key;
3400 	pdb->class_val_to_struct[class->s.value - 1] = class;
3401 
3402 	return 0;
3403 }
3404 
__cil_role_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3405 int __cil_role_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3406 {
3407 	policydb_t *pdb = data;
3408 	role_datum_t *role = (role_datum_t *)datum;
3409 
3410 	if (role->s.value < 1 || role->s.value > pdb->p_roles.nprim) {
3411 		return -EINVAL;
3412 	}
3413 	pdb->p_role_val_to_name[role->s.value - 1] = (char *)key;
3414 	pdb->role_val_to_struct[role->s.value - 1] = role;
3415 
3416 	return 0;
3417 }
3418 
__cil_type_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3419 int __cil_type_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3420 {
3421 	policydb_t *pdb = data;
3422 	type_datum_t *type = (type_datum_t *)datum;
3423 
3424 	if (type->s.value < 1 || type->s.value > pdb->p_types.nprim) {
3425 		return -EINVAL;
3426 	}
3427 	pdb->p_type_val_to_name[type->s.value - 1] = (char *)key;
3428 	pdb->type_val_to_struct[type->s.value - 1] = type;
3429 
3430 	return 0;
3431 }
3432 
__cil_user_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3433 int __cil_user_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3434 {
3435 	policydb_t *pdb = data;
3436 	user_datum_t *user = (user_datum_t *)datum;
3437 
3438 	if (user->s.value < 1 || user->s.value > pdb->p_users.nprim) {
3439 		return -EINVAL;
3440 	}
3441 	pdb->p_user_val_to_name[user->s.value - 1] = (char *)key;
3442 	pdb->user_val_to_struct[user->s.value - 1] = user;
3443 
3444 	return 0;
3445 }
3446 
__cil_bool_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3447 int __cil_bool_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3448 {
3449 	policydb_t *pdb = data;
3450 	cond_bool_datum_t *bool = (cond_bool_datum_t *)datum;
3451 
3452 	if (bool->s.value < 1 || bool->s.value > pdb->p_bools.nprim) {
3453 		return -EINVAL;
3454 	}
3455 	pdb->p_bool_val_to_name[bool->s.value - 1] = (char *)key;
3456 	pdb->bool_val_to_struct[bool->s.value - 1] = bool;
3457 
3458 	return 0;
3459 }
3460 
__cil_level_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3461 int __cil_level_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3462 {
3463 	policydb_t *pdb = data;
3464 	level_datum_t *level = (level_datum_t *)datum;
3465 
3466 	if (level->level->sens < 1 || level->level->sens > pdb->p_levels.nprim) {
3467 		return -EINVAL;
3468 	}
3469 	pdb->p_sens_val_to_name[level->level->sens - 1] = (char *)key;
3470 
3471 	return 0;
3472 }
3473 
__cil_cat_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3474 int __cil_cat_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3475 {
3476 	policydb_t *pdb = data;
3477 	cat_datum_t *cat = (cat_datum_t *)datum;
3478 
3479 	if (cat->s.value < 1 || cat->s.value > pdb->p_cats.nprim) {
3480 		return -EINVAL;
3481 	}
3482 	pdb->p_cat_val_to_name[cat->s.value - 1] = (char *)key;
3483 
3484 	return 0;
3485 }
3486 
__cil_policydb_val_arrays_create(policydb_t * policydb)3487 int __cil_policydb_val_arrays_create(policydb_t *policydb)
3488 {
3489 	int rc = SEPOL_ERR;
3490 
3491 	policydb->p_common_val_to_name = cil_malloc(sizeof(char *) * policydb->p_commons.nprim);
3492 	rc = hashtab_map(policydb->p_commons.table, &__cil_common_val_array_insert, policydb);
3493 	if (rc != SEPOL_OK) {
3494 		goto exit;
3495 	}
3496 
3497 	policydb->p_class_val_to_name = cil_malloc(sizeof(char *) * policydb->p_classes.nprim);
3498 	policydb->class_val_to_struct = cil_malloc(sizeof(class_datum_t *) * policydb->p_classes.nprim);
3499 	rc = hashtab_map(policydb->p_classes.table, &__cil_class_val_array_insert, policydb);
3500 	if (rc != SEPOL_OK) {
3501 		goto exit;
3502 	}
3503 
3504 	policydb->p_role_val_to_name = cil_malloc(sizeof(char *) * policydb->p_roles.nprim);
3505 	policydb->role_val_to_struct = cil_malloc(sizeof(role_datum_t *) * policydb->p_roles.nprim);
3506 	rc = hashtab_map(policydb->p_roles.table, &__cil_role_val_array_insert, policydb);
3507 	if (rc != SEPOL_OK) {
3508 		goto exit;
3509 	}
3510 
3511 	policydb->p_type_val_to_name = cil_malloc(sizeof(char *) * policydb->p_types.nprim);
3512 	policydb->type_val_to_struct = cil_malloc(sizeof(type_datum_t *) * policydb->p_types.nprim);
3513 	rc = hashtab_map(policydb->p_types.table, &__cil_type_val_array_insert, policydb);
3514 	if (rc != SEPOL_OK) {
3515 		goto exit;
3516 	}
3517 
3518 	policydb->p_user_val_to_name = cil_malloc(sizeof(char *) * policydb->p_users.nprim);
3519 	policydb->user_val_to_struct = cil_malloc(sizeof(user_datum_t *) * policydb->p_users.nprim);
3520 	rc = hashtab_map(policydb->p_users.table, &__cil_user_val_array_insert, policydb);
3521 	if (rc != SEPOL_OK) {
3522 		goto exit;
3523 	}
3524 
3525 	policydb->p_bool_val_to_name = cil_malloc(sizeof(char *) * policydb->p_bools.nprim);
3526 	policydb->bool_val_to_struct = cil_malloc(sizeof(cond_bool_datum_t *) * policydb->p_bools.nprim);
3527 	rc = hashtab_map(policydb->p_bools.table, &__cil_bool_val_array_insert, policydb);
3528 	if (rc != SEPOL_OK) {
3529 		goto exit;
3530 	}
3531 
3532 	policydb->p_sens_val_to_name = cil_malloc(sizeof(char *) * policydb->p_levels.nprim);
3533 	rc = hashtab_map(policydb->p_levels.table, &__cil_level_val_array_insert, policydb);
3534 	if (rc != SEPOL_OK) {
3535 		goto exit;
3536 	}
3537 
3538 	policydb->p_cat_val_to_name = cil_malloc(sizeof(char *) * policydb->p_cats.nprim);
3539 	rc = hashtab_map(policydb->p_cats.table, &__cil_cat_val_array_insert, policydb);
3540 	if (rc != SEPOL_OK) {
3541 		goto exit;
3542 	}
3543 
3544 exit:
3545 	return rc;
3546 }
3547 
__cil_set_conditional_state_and_flags(policydb_t * pdb)3548 static void __cil_set_conditional_state_and_flags(policydb_t *pdb)
3549 {
3550 	cond_node_t *cur;
3551 
3552 	for (cur = pdb->cond_list; cur != NULL; cur = cur->next) {
3553 		int new_state;
3554 		cond_av_list_t *c;
3555 
3556 		new_state = cond_evaluate_expr(pdb, cur->expr);
3557 
3558 		cur->cur_state = new_state;
3559 
3560 		if (new_state == -1) {
3561 			cil_log(CIL_WARN, "Expression result was undefined - disabling all rules\n");
3562 		}
3563 
3564 		for (c = cur->true_list; c != NULL; c = c->next) {
3565 			if (new_state <= 0) {
3566 				c->node->key.specified &= ~AVTAB_ENABLED;
3567 			} else {
3568 				c->node->key.specified |= AVTAB_ENABLED;
3569 			}
3570 		}
3571 
3572 		for (c = cur->false_list; c != NULL; c = c->next) {
3573 			if (new_state) { /* -1 or 1 */
3574 				c->node->key.specified &= ~AVTAB_ENABLED;
3575 			} else {
3576 				c->node->key.specified |= AVTAB_ENABLED;
3577 			}
3578 		}
3579 	}
3580 }
3581 
__cil_policydb_create(const struct cil_db * db,struct sepol_policydb ** spdb)3582 int __cil_policydb_create(const struct cil_db *db, struct sepol_policydb **spdb)
3583 {
3584 	int rc;
3585 	struct policydb *pdb = NULL;
3586 
3587 	rc = sepol_policydb_create(spdb);
3588 	if (rc < 0) {
3589 		cil_log(CIL_ERR, "Failed to create policy db\n");
3590 		// spdb could be a dangling pointer at this point, so reset it so
3591 		// callers of this function don't need to worry about freeing garbage
3592 		*spdb = NULL;
3593 		goto exit;
3594 	}
3595 
3596 	pdb = &(*spdb)->p;
3597 
3598 	pdb->policy_type = POLICY_KERN;
3599 	pdb->target_platform = db->target_platform;
3600 	pdb->policyvers = db->policy_version;
3601 	pdb->handle_unknown = db->handle_unknown;
3602 	pdb->mls = db->mls;
3603 
3604 	return SEPOL_OK;
3605 
3606 exit:
3607 	return rc;
3608 }
3609 
3610 
__cil_policydb_init(policydb_t * pdb,const struct cil_db * db)3611 int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db)
3612 {
3613 	int rc = SEPOL_ERR;
3614 
3615 	// these flags should get set in __cil_policydb_create. However, for
3616 	// backwards compatability, it is possible that __cil_policydb_create is
3617 	// never called. So, they must also be set here.
3618 	pdb->handle_unknown = db->handle_unknown;
3619 	pdb->mls = db->mls;
3620 
3621 	rc = cil_classorder_to_policydb(pdb, db);
3622 	if (rc != SEPOL_OK) {
3623 		goto exit;
3624 	}
3625 
3626 	if (pdb->mls == CIL_TRUE) {
3627 		rc = cil_catorder_to_policydb(pdb, db);
3628 		if (rc != SEPOL_OK) {
3629 			goto exit;
3630 		}
3631 
3632 		rc = cil_sensitivityorder_to_policydb(pdb, db);
3633 		if (rc != SEPOL_OK) {
3634 			goto exit;
3635 		}
3636 	}
3637 
3638 	rc = avtab_alloc(&pdb->te_avtab, MAX_AVTAB_SIZE);
3639 	if (rc != SEPOL_OK) {
3640 		goto exit;
3641 	}
3642 
3643 	rc = avtab_alloc(&pdb->te_cond_avtab, MAX_AVTAB_SIZE);
3644 	if (rc != SEPOL_OK) {
3645 		goto exit;
3646 	}
3647 
3648 	return SEPOL_OK;
3649 
3650 exit:
3651 
3652 	return rc;
3653 }
3654 
filename_trans_hash(hashtab_t h,hashtab_key_t key)3655 static unsigned int filename_trans_hash(hashtab_t h, hashtab_key_t key)
3656 {
3657 	filename_trans_t *k = (filename_trans_t *)key;
3658 	return ((k->tclass + (k->ttype << 2) +
3659 				(k->stype << 9)) & (h->size - 1));
3660 }
3661 
filename_trans_compare(hashtab_t h,hashtab_key_t key1,hashtab_key_t key2)3662 static int filename_trans_compare(hashtab_t h
3663              __attribute__ ((unused)), hashtab_key_t key1,
3664 			              hashtab_key_t key2)
3665 {
3666 	filename_trans_t *a = (filename_trans_t *)key1;
3667 	filename_trans_t *b = (filename_trans_t *)key2;
3668 
3669 	return a->stype != b->stype || a->ttype != b->ttype || a->tclass != b->tclass || strcmp(a->name, b->name);
3670 }
3671 
range_trans_hash(hashtab_t h,hashtab_key_t key)3672 static unsigned int range_trans_hash(hashtab_t h, hashtab_key_t key)
3673 {
3674 	range_trans_t *k = (range_trans_t *)key;
3675 	return ((k->target_class + (k->target_type << 2) +
3676 				(k->source_type << 5)) & (h->size - 1));
3677 }
3678 
range_trans_compare(hashtab_t h,hashtab_key_t key1,hashtab_key_t key2)3679 static int range_trans_compare(hashtab_t h
3680              __attribute__ ((unused)), hashtab_key_t key1,
3681 			              hashtab_key_t key2)
3682 {
3683 	range_trans_t *a = (range_trans_t *)key1;
3684 	range_trans_t *b = (range_trans_t *)key2;
3685 
3686 	return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class;
3687 }
3688 
role_trans_hash(hashtab_t h,hashtab_key_t key)3689 static unsigned int role_trans_hash(hashtab_t h, hashtab_key_t key)
3690 {
3691 	role_trans_t *k = (role_trans_t *)key;
3692 	return ((k->role + (k->type << 2) +
3693 				(k->tclass << 5)) & (h->size - 1));
3694 }
3695 
role_trans_compare(hashtab_t h,hashtab_key_t key1,hashtab_key_t key2)3696 static int role_trans_compare(hashtab_t h
3697              __attribute__ ((unused)), hashtab_key_t key1,
3698 			              hashtab_key_t key2)
3699 {
3700 	role_trans_t *a = (role_trans_t *)key1;
3701 	role_trans_t *b = (role_trans_t *)key2;
3702 
3703 	return a->role != b->role || a->type != b->type || a->tclass != b->tclass;
3704 }
3705 
cil_binary_create(const struct cil_db * db,sepol_policydb_t ** policydb)3706 int cil_binary_create(const struct cil_db *db, sepol_policydb_t **policydb)
3707 {
3708 	int rc = SEPOL_ERR;
3709 	struct sepol_policydb *pdb = NULL;
3710 
3711 	rc = __cil_policydb_create(db, &pdb);
3712 	if (rc != SEPOL_OK) {
3713 		goto exit;
3714 	}
3715 
3716 	rc = cil_binary_create_allocated_pdb(db, pdb);
3717 	if (rc != SEPOL_OK) {
3718 		goto exit;
3719 	}
3720 
3721 	*policydb = pdb;
3722 
3723 	return SEPOL_OK;
3724 
3725 exit:
3726 	sepol_policydb_free(pdb);
3727 
3728 	return rc;
3729 }
3730 
3731 // assumes policydb is already allocated and initialized properly with things
3732 // like policy type set to kernel and version set appropriately
cil_binary_create_allocated_pdb(const struct cil_db * db,sepol_policydb_t * policydb)3733 int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *policydb)
3734 {
3735 	int rc = SEPOL_ERR;
3736 	int i;
3737 	struct cil_args_binary extra_args;
3738 	policydb_t *pdb = &policydb->p;
3739 	struct cil_list *neverallows = NULL;
3740 	hashtab_t filename_trans_table = NULL;
3741 	hashtab_t range_trans_table = NULL;
3742 	hashtab_t role_trans_table = NULL;
3743 
3744 	if (db == NULL || policydb == NULL) {
3745 		if (db == NULL) {
3746 			cil_log(CIL_ERR,"db == NULL\n");
3747 		} else if (policydb == NULL) {
3748 			cil_log(CIL_ERR,"policydb == NULL\n");
3749 		}
3750 		return SEPOL_ERR;
3751 	}
3752 
3753 	rc = __cil_policydb_init(pdb, db);
3754 	if (rc != SEPOL_OK) {
3755 		cil_log(CIL_ERR,"Problem in policydb_init\n");
3756 		goto exit;
3757 	}
3758 
3759 	filename_trans_table = hashtab_create(filename_trans_hash, filename_trans_compare, FILENAME_TRANS_TABLE_SIZE);
3760 	if (!filename_trans_table) {
3761 		cil_log(CIL_INFO, "Failure to create hashtab for filename_trans\n");
3762 		goto exit;
3763 	}
3764 
3765 	range_trans_table = hashtab_create(range_trans_hash, range_trans_compare, RANGE_TRANS_TABLE_SIZE);
3766 	if (!range_trans_table) {
3767 		cil_log(CIL_INFO, "Failure to create hashtab for range_trans\n");
3768 		goto exit;
3769 	}
3770 
3771 	role_trans_table = hashtab_create(role_trans_hash, role_trans_compare, ROLE_TRANS_TABLE_SIZE);
3772 	if (!role_trans_table) {
3773 		cil_log(CIL_INFO, "Failure to create hashtab for role_trans\n");
3774 		goto exit;
3775 	}
3776 
3777 	cil_list_init(&neverallows, CIL_LIST_ITEM);
3778 
3779 	extra_args.db = db;
3780 	extra_args.pdb = pdb;
3781 	extra_args.neverallows = neverallows;
3782 	extra_args.filename_trans_table = filename_trans_table;
3783 	extra_args.range_trans_table = range_trans_table;
3784 	extra_args.role_trans_table = role_trans_table;
3785 	for (i = 1; i <= 3; i++) {
3786 		extra_args.pass = i;
3787 
3788 		rc = cil_tree_walk(db->ast->root, __cil_binary_create_helper, NULL, NULL, &extra_args);
3789 		if (rc != SEPOL_OK) {
3790 			cil_log(CIL_INFO, "Failure while walking cil database\n");
3791 			goto exit;
3792 		}
3793 
3794 		if (i == 1) {
3795 			rc = __cil_policydb_val_arrays_create(pdb);
3796 			if (rc != SEPOL_OK) {
3797 				cil_log(CIL_INFO, "Failure creating val_to_{struct,name} arrays\n");
3798 				goto exit;
3799 			}
3800 		}
3801 	}
3802 
3803 	rc = cil_sidorder_to_policydb(pdb, db);
3804 	if (rc != SEPOL_OK) {
3805 		goto exit;
3806 	}
3807 
3808 	rc = __cil_contexts_to_policydb(pdb, db);
3809 	if (rc != SEPOL_OK) {
3810 		cil_log(CIL_INFO, "Failure while inserting cil contexts into sepol policydb\n");
3811 		goto exit;
3812 	}
3813 
3814 	if (pdb->type_attr_map == NULL) {
3815 		rc = __cil_typeattr_bitmap_init(pdb);
3816 		if (rc != SEPOL_OK) {
3817 			cil_log(CIL_INFO, "Failure while initializing typeattribute bitmap\n");
3818 			goto exit;
3819 		}
3820 	}
3821 
3822 	cond_optimize_lists(pdb->cond_list);
3823 	__cil_set_conditional_state_and_flags(pdb);
3824 
3825 	rc = SEPOL_OK;
3826 
3827 exit:
3828 	hashtab_destroy(filename_trans_table);
3829 	hashtab_destroy(range_trans_table);
3830 	hashtab_destroy(role_trans_table);
3831 	cil_neverallows_list_destroy(neverallows);
3832 
3833 	return rc;
3834 }
3835