• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef IPPROTO_DCCP
35 #define IPPROTO_DCCP 33
36 #endif
37 #ifndef IPPROTO_SCTP
38 #define IPPROTO_SCTP 132
39 #endif
40 
41 #include <sepol/policydb/policydb.h>
42 #include <sepol/policydb/polcaps.h>
43 #include <sepol/policydb/conditional.h>
44 #include <sepol/policydb/constraint.h>
45 #include <sepol/policydb/expand.h>
46 #include <sepol/policydb/hierarchy.h>
47 
48 #include "cil_internal.h"
49 #include "cil_flavor.h"
50 #include "cil_log.h"
51 #include "cil_mem.h"
52 #include "cil_tree.h"
53 #include "cil_binary.h"
54 #include "cil_symtab.h"
55 #include "cil_find.h"
56 #include "cil_build_ast.h"
57 
58 #define ROLE_TRANS_TABLE_SIZE (1 << 10)
59 #define AVRULEX_TABLE_SIZE (1 <<  10)
60 #define PERMS_PER_CLASS 32
61 
62 struct cil_args_binary {
63 	const struct cil_db *db;
64 	policydb_t *pdb;
65 	struct cil_list *neverallows;
66 	int pass;
67 	hashtab_t role_trans_table;
68 	hashtab_t avrulex_ioctl_table;
69 	void **type_value_to_cil;
70 };
71 
72 struct cil_args_booleanif {
73 	const struct cil_db *db;
74 	policydb_t *pdb;
75 	cond_node_t *cond_node;
76 	enum cil_flavor cond_flavor;
77 };
78 
__cil_get_sepol_user_datum(policydb_t * pdb,struct cil_symtab_datum * datum,user_datum_t ** sepol_user)79 static int __cil_get_sepol_user_datum(policydb_t *pdb, struct cil_symtab_datum *datum, user_datum_t **sepol_user)
80 {
81 	*sepol_user = hashtab_search(pdb->p_users.table, datum->fqn);
82 	if (*sepol_user == NULL) {
83 		cil_log(CIL_INFO, "Failed to find user %s in sepol hashtab\n", datum->fqn);
84 		return SEPOL_ERR;
85 	}
86 
87 	return SEPOL_OK;
88 }
89 
__cil_get_sepol_role_datum(policydb_t * pdb,struct cil_symtab_datum * datum,role_datum_t ** sepol_role)90 static int __cil_get_sepol_role_datum(policydb_t *pdb, struct cil_symtab_datum *datum, role_datum_t **sepol_role)
91 {
92 	*sepol_role = hashtab_search(pdb->p_roles.table, datum->fqn);
93 	if (*sepol_role == NULL) {
94 		cil_log(CIL_INFO, "Failed to find role %s in sepol hashtab\n", datum->fqn);
95 		return SEPOL_ERR;
96 	}
97 
98 	return SEPOL_OK;
99 }
100 
__cil_get_sepol_type_datum(policydb_t * pdb,struct cil_symtab_datum * datum,type_datum_t ** sepol_type)101 static int __cil_get_sepol_type_datum(policydb_t *pdb, struct cil_symtab_datum *datum, type_datum_t **sepol_type)
102 {
103 	*sepol_type = hashtab_search(pdb->p_types.table, datum->fqn);
104 	if (*sepol_type == NULL) {
105 		cil_log(CIL_INFO, "Failed to find type %s in sepol hashtab\n", datum->fqn);
106 		return SEPOL_ERR;
107 	}
108 
109 	return SEPOL_OK;
110 }
111 
__cil_get_sepol_class_datum(policydb_t * pdb,struct cil_symtab_datum * datum,class_datum_t ** sepol_class)112 static int __cil_get_sepol_class_datum(policydb_t *pdb, struct cil_symtab_datum *datum, class_datum_t **sepol_class)
113 {
114 	*sepol_class = hashtab_search(pdb->p_classes.table, datum->fqn);
115 	if (*sepol_class == NULL) {
116 		cil_log(CIL_INFO, "Failed to find class %s in sepol hashtab\n", datum->fqn);
117 		return SEPOL_ERR;
118 	}
119 
120 	return SEPOL_OK;
121 }
122 
__cil_get_sepol_cat_datum(policydb_t * pdb,struct cil_symtab_datum * datum,cat_datum_t ** sepol_cat)123 static int __cil_get_sepol_cat_datum(policydb_t *pdb, struct cil_symtab_datum *datum, cat_datum_t **sepol_cat)
124 {
125 	*sepol_cat = hashtab_search(pdb->p_cats.table, datum->fqn);
126 	if (*sepol_cat == NULL) {
127 		cil_log(CIL_INFO, "Failed to find category %s in sepol hashtab\n", datum->fqn);
128 		return SEPOL_ERR;
129 	}
130 
131 	return SEPOL_OK;
132 }
133 
__cil_get_sepol_level_datum(policydb_t * pdb,struct cil_symtab_datum * datum,level_datum_t ** sepol_level)134 static int __cil_get_sepol_level_datum(policydb_t *pdb, struct cil_symtab_datum *datum, level_datum_t **sepol_level)
135 {
136 	*sepol_level = hashtab_search(pdb->p_levels.table, datum->fqn);
137 	if (*sepol_level == NULL) {
138 		cil_log(CIL_INFO, "Failed to find level %s in sepol hashtab\n", datum->fqn);
139 		return SEPOL_ERR;
140 	}
141 
142 	return SEPOL_OK;
143 }
144 
__cil_expand_user(struct cil_symtab_datum * datum,ebitmap_t * new)145 static int __cil_expand_user(struct cil_symtab_datum *datum, ebitmap_t *new)
146 {
147 	struct cil_tree_node *node = NODE(datum);
148 	struct cil_user *user = NULL;
149 	struct cil_userattribute *attr = NULL;
150 
151 	if (node->flavor == CIL_USERATTRIBUTE) {
152 		attr = (struct cil_userattribute *)datum;
153 		if (ebitmap_cpy(new, attr->users)) {
154 			cil_log(CIL_ERR, "Failed to copy user bits\n");
155 			goto exit;
156 		}
157 	} else {
158 		user = (struct cil_user *)datum;
159 		ebitmap_init(new);
160 		if (ebitmap_set_bit(new, user->value, 1)) {
161 			cil_log(CIL_ERR, "Failed to set user bit\n");
162 			ebitmap_destroy(new);
163 			goto exit;
164 		}
165 	}
166 
167 	return SEPOL_OK;
168 
169 exit:
170 	return SEPOL_ERR;
171 }
172 
__cil_expand_role(struct cil_symtab_datum * datum,ebitmap_t * new)173 static int __cil_expand_role(struct cil_symtab_datum *datum, ebitmap_t *new)
174 {
175 	struct cil_tree_node *node = NODE(datum);
176 
177 	if (node->flavor == CIL_ROLEATTRIBUTE) {
178 		struct cil_roleattribute *attr = (struct cil_roleattribute *)datum;
179 		if (ebitmap_cpy(new, attr->roles)) {
180 			cil_log(CIL_ERR, "Failed to copy role bits\n");
181 			goto exit;
182 		}
183 	} else {
184 		struct cil_role *role = (struct cil_role *)datum;
185 		ebitmap_init(new);
186 		if (ebitmap_set_bit(new, role->value, 1)) {
187 			cil_log(CIL_ERR, "Failed to set role bit\n");
188 			ebitmap_destroy(new);
189 			goto exit;
190 		}
191 	}
192 
193 	return SEPOL_OK;
194 
195 exit:
196 	return SEPOL_ERR;
197 }
198 
__cil_expand_type(struct cil_symtab_datum * datum,ebitmap_t * new)199 static int __cil_expand_type(struct cil_symtab_datum *datum, ebitmap_t *new)
200 {
201 	struct cil_tree_node *node = NODE(datum);
202 
203 	if (node->flavor == CIL_TYPEATTRIBUTE) {
204 		struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
205 		if (ebitmap_cpy(new, attr->types)) {
206 			cil_log(CIL_ERR, "Failed to copy type bits\n");
207 			goto exit;
208 		}
209 	} else {
210 		struct cil_type *type = (struct cil_type *)datum;
211 		ebitmap_init(new);
212 		if (ebitmap_set_bit(new, type->value, 1)) {
213 			cil_log(CIL_ERR, "Failed to set type bit\n");
214 			ebitmap_destroy(new);
215 			goto exit;
216 		}
217 	}
218 
219 	return SEPOL_OK;
220 
221 exit:
222 	return SEPOL_ERR;
223 }
224 
cil_add_ocontext(ocontext_t ** head,ocontext_t ** tail)225 static ocontext_t *cil_add_ocontext(ocontext_t **head, ocontext_t **tail)
226 {
227 	ocontext_t *new = cil_malloc(sizeof(ocontext_t));
228 	memset(new, 0, sizeof(ocontext_t));
229 	if (*tail) {
230 		(*tail)->next = new;
231 	} else {
232 		*head = new;
233 	}
234 	*tail = new;
235 
236 	return new;
237 }
238 
cil_common_to_policydb(policydb_t * pdb,struct cil_class * cil_common,common_datum_t ** common_out)239 int cil_common_to_policydb(policydb_t *pdb, struct cil_class *cil_common, common_datum_t **common_out)
240 {
241 	int rc = SEPOL_ERR;
242 	uint32_t value = 0;
243 	char *key = NULL;
244 	struct cil_tree_node *node = cil_common->datum.nodes->head->data;
245 	struct cil_tree_node *cil_perm = node->cl_head;
246 	common_datum_t *sepol_common = cil_malloc(sizeof(*sepol_common));
247 	memset(sepol_common, 0, sizeof(common_datum_t));
248 
249 	key = cil_strdup(cil_common->datum.fqn);
250 	rc = symtab_insert(pdb, SYM_COMMONS, key, sepol_common, SCOPE_DECL, 0, &value);
251 	if (rc != SEPOL_OK) {
252 		free(sepol_common);
253 		goto exit;
254 	}
255 	sepol_common->s.value = value;
256 
257 	rc = symtab_init(&sepol_common->permissions, PERM_SYMTAB_SIZE);
258 	if (rc != SEPOL_OK) {
259 		goto exit;
260 	}
261 
262 	while (cil_perm != NULL) {
263 		struct cil_perm *curr = cil_perm->data;
264 		perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm));
265 		memset(sepol_perm, 0, sizeof(perm_datum_t));
266 
267 		key = cil_strdup(curr->datum.fqn);
268 		rc = hashtab_insert(sepol_common->permissions.table, key, sepol_perm);
269 		if (rc != SEPOL_OK) {
270 			free(sepol_perm);
271 			goto exit;
272 		}
273 		sepol_perm->s.value = sepol_common->permissions.nprim + 1;
274 		sepol_common->permissions.nprim++;
275 		cil_perm = cil_perm->next;
276 	}
277 
278 	*common_out = sepol_common;
279 
280 	return SEPOL_OK;
281 
282 exit:
283 	free(key);
284 	return rc;
285 }
286 
cil_classorder_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_class * class_value_to_cil[],struct cil_perm ** perm_value_to_cil[])287 int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
288 {
289 	int rc = SEPOL_ERR;
290 	struct cil_list_item *curr_class;
291 
292 	cil_list_for_each(curr_class, db->classorder) {
293 		struct cil_class *cil_class = curr_class->data;
294 		uint32_t value = 0;
295 		char *key = NULL;
296 		int class_index;
297 		struct cil_tree_node *curr;
298 		common_datum_t *sepol_common = NULL;
299 		class_datum_t *sepol_class = cil_malloc(sizeof(*sepol_class));
300 		memset(sepol_class, 0, sizeof(class_datum_t));
301 
302 		key = cil_strdup(cil_class->datum.fqn);
303 		rc = symtab_insert(pdb, SYM_CLASSES, key, sepol_class, SCOPE_DECL, 0, &value);
304 		if (rc != SEPOL_OK) {
305 			free(sepol_class);
306 			free(key);
307 			goto exit;
308 		}
309 		sepol_class->s.value = value;
310 		class_index = value;
311 		class_value_to_cil[class_index] = cil_class;
312 
313 		rc = symtab_init(&sepol_class->permissions, PERM_SYMTAB_SIZE);
314 		if (rc != SEPOL_OK) {
315 			goto exit;
316 		}
317 
318 		if (cil_class->common != NULL) {
319 			int i;
320 			struct cil_class *cil_common = cil_class->common;
321 
322 			key = cil_class->common->datum.fqn;
323 			sepol_common = hashtab_search(pdb->p_commons.table, key);
324 			if (sepol_common == NULL) {
325 				rc = cil_common_to_policydb(pdb, cil_common, &sepol_common);
326 				if (rc != SEPOL_OK) {
327 					goto exit;
328 				}
329 			}
330 			sepol_class->comdatum = sepol_common;
331 			sepol_class->comkey = cil_strdup(key);
332 			sepol_class->permissions.nprim += sepol_common->permissions.nprim;
333 
334 			for (curr = NODE(cil_class->common)->cl_head, i = 1; curr; curr = curr->next, i++) {
335 				struct cil_perm *cil_perm = curr->data;
336 				perm_value_to_cil[class_index][i] = cil_perm;
337 			}
338 		}
339 
340 		for (curr = NODE(cil_class)->cl_head; curr; curr = curr->next) {
341 			struct cil_perm *cil_perm = curr->data;
342 			perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm));
343 			memset(sepol_perm, 0, sizeof(perm_datum_t));
344 
345 			key = cil_strdup(cil_perm->datum.fqn);
346 			rc = hashtab_insert(sepol_class->permissions.table, key, sepol_perm);
347 			if (rc != SEPOL_OK) {
348 				free(sepol_perm);
349 				free(key);
350 				goto exit;
351 			}
352 			sepol_perm->s.value = sepol_class->permissions.nprim + 1;
353 			sepol_class->permissions.nprim++;
354 			perm_value_to_cil[class_index][sepol_perm->s.value] = cil_perm;
355 		}
356 	}
357 
358 	return SEPOL_OK;
359 
360 exit:
361 	return rc;
362 }
363 
cil_role_to_policydb(policydb_t * pdb,struct cil_role * cil_role)364 int cil_role_to_policydb(policydb_t *pdb, struct cil_role *cil_role)
365 {
366 	int rc = SEPOL_ERR;
367 	uint32_t value = 0;
368 	char *key = NULL;
369 	role_datum_t *sepol_role = cil_malloc(sizeof(*sepol_role));
370 	role_datum_init(sepol_role);
371 
372 	if (cil_role->datum.fqn == CIL_KEY_OBJECT_R) {
373 		/* special case
374 		 * object_r defaults to 1 in libsepol symtab */
375 		rc = SEPOL_OK;
376 		goto exit;
377 	}
378 
379 	key = cil_strdup(cil_role->datum.fqn);
380 	rc = symtab_insert(pdb, SYM_ROLES, (hashtab_key_t)key, sepol_role, SCOPE_DECL, 0, &value);
381 	if (rc != SEPOL_OK) {
382 		goto exit;
383 	}
384 	if (ebitmap_set_bit(&sepol_role->dominates, value - 1, 1)) {
385 		cil_log(CIL_INFO, "Failed to set dominates bit for role\n");
386 		rc = SEPOL_ERR;
387 		goto exit;
388 	}
389 	sepol_role->s.value = value;
390 	return SEPOL_OK;
391 
392 exit:
393 	free(key);
394 	role_datum_destroy(sepol_role);
395 	free(sepol_role);
396 	return rc;
397 }
398 
cil_role_bounds_to_policydb(policydb_t * pdb,struct cil_role * cil_role)399 int cil_role_bounds_to_policydb(policydb_t *pdb, struct cil_role *cil_role)
400 {
401 	int rc = SEPOL_ERR;
402 	role_datum_t *sepol_role = NULL;
403 	role_datum_t *sepol_parent = NULL;
404 
405 	if (cil_role->bounds) {
406 		rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_role), &sepol_role);
407 		if (rc != SEPOL_OK) goto exit;
408 
409 		rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_role->bounds), &sepol_parent);
410 		if (rc != SEPOL_OK) goto exit;
411 
412 		sepol_role->bounds = sepol_parent->s.value;
413 	}
414 
415 	return SEPOL_OK;
416 
417 exit:
418 	cil_log(CIL_ERR, "Failed to insert role bounds for role %s\n", cil_role->datum.fqn);
419 	return SEPOL_ERR;
420 }
421 
cil_roletype_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_role * role)422 int cil_roletype_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_role *role)
423 {
424 	int rc = SEPOL_ERR;
425 
426 	if (role->types) {
427 		role_datum_t *sepol_role = NULL;
428 		type_datum_t *sepol_type = NULL;
429 		ebitmap_node_t *tnode;
430 		unsigned int i;
431 
432 		rc = __cil_get_sepol_role_datum(pdb, DATUM(role), &sepol_role);
433 		if (rc != SEPOL_OK) goto exit;
434 
435 		ebitmap_for_each_positive_bit(role->types, tnode, i) {
436 			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type);
437 			if (rc != SEPOL_OK) goto exit;
438 
439 			if (ebitmap_set_bit(&sepol_role->types.types, sepol_type->s.value - 1, 1)) {
440 				cil_log(CIL_INFO, "Failed to set type bit for role\n");
441 				rc = SEPOL_ERR;
442 				goto exit;
443 			}
444 		}
445 	}
446 
447 	return SEPOL_OK;
448 
449 exit:
450 	return rc;
451 }
452 
cil_type_to_policydb(policydb_t * pdb,struct cil_type * cil_type,void * type_value_to_cil[])453 int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type, void *type_value_to_cil[])
454 {
455 	int rc = SEPOL_ERR;
456 	uint32_t value = 0;
457 	char *key = NULL;
458 	type_datum_t *sepol_type = cil_malloc(sizeof(*sepol_type));
459 	type_datum_init(sepol_type);
460 
461 	sepol_type->flavor = TYPE_TYPE;
462 
463 	key = cil_strdup(cil_type->datum.fqn);
464 	rc = symtab_insert(pdb, SYM_TYPES, key, sepol_type, SCOPE_DECL, 0, &value);
465 	if (rc != SEPOL_OK) {
466 		goto exit;
467 	}
468 	sepol_type->s.value = value;
469 	sepol_type->primary = 1;
470 
471 	type_value_to_cil[value] = cil_type;
472 
473 	return SEPOL_OK;
474 
475 exit:
476 	free(key);
477 	type_datum_destroy(sepol_type);
478 	free(sepol_type);
479 	return rc;
480 }
481 
cil_type_bounds_to_policydb(policydb_t * pdb,struct cil_type * cil_type)482 int cil_type_bounds_to_policydb(policydb_t *pdb, struct cil_type *cil_type)
483 {
484 	int rc = SEPOL_ERR;
485 	type_datum_t *sepol_type = NULL;
486 	type_datum_t *sepol_parent = NULL;
487 
488 	if (cil_type->bounds) {
489 		rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_type), &sepol_type);
490 		if (rc != SEPOL_OK) goto exit;
491 
492 		rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_type->bounds), &sepol_parent);
493 		if (rc != SEPOL_OK) goto exit;
494 
495 		sepol_type->bounds = sepol_parent->s.value;
496 	}
497 
498 	return SEPOL_OK;
499 
500 exit:
501 	cil_log(CIL_ERR, "Failed to insert type bounds for type %s\n", cil_type->datum.fqn);
502 	return SEPOL_ERR;
503 }
504 
cil_typealias_to_policydb(policydb_t * pdb,struct cil_alias * cil_alias)505 int cil_typealias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias)
506 {
507 	int rc = SEPOL_ERR;
508 	char *key = NULL;
509 	type_datum_t *sepol_type = NULL;
510 	type_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_alias));
511 	type_datum_init(sepol_alias);
512 
513 	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_alias->actual), &sepol_type);
514 	if (rc != SEPOL_OK) goto exit;
515 
516 	sepol_alias->flavor = TYPE_TYPE;
517 
518 	key = cil_strdup(cil_alias->datum.fqn);
519 	rc = symtab_insert(pdb, SYM_TYPES, key, sepol_alias, SCOPE_DECL, 0, NULL);
520 	if (rc != SEPOL_OK) {
521 		goto exit;
522 	}
523 	sepol_alias->s.value = sepol_type->s.value;
524 	sepol_alias->primary = 0;
525 
526 	return SEPOL_OK;
527 
528 exit:
529 	free(key);
530 	type_datum_destroy(sepol_alias);
531 	free(sepol_alias);
532 	return rc;
533 }
534 
cil_typepermissive_to_policydb(policydb_t * pdb,struct cil_typepermissive * cil_typeperm)535 int cil_typepermissive_to_policydb(policydb_t *pdb, struct cil_typepermissive *cil_typeperm)
536 {
537 	int rc = SEPOL_ERR;
538 	type_datum_t *sepol_type = NULL;
539 
540 	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_typeperm->type), &sepol_type);
541 	if (rc != SEPOL_OK) goto exit;
542 
543 	if (ebitmap_set_bit(&pdb->permissive_map, sepol_type->s.value, 1)) {
544 		goto exit;
545 	}
546 
547 	return SEPOL_OK;
548 
549 exit:
550 	type_datum_destroy(sepol_type);
551 	free(sepol_type);
552 	return rc;
553 
554 }
555 
cil_typeattribute_to_policydb(policydb_t * pdb,struct cil_typeattribute * cil_attr,void * type_value_to_cil[])556 int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr, void *type_value_to_cil[])
557 {
558 	int rc = SEPOL_ERR;
559 	uint32_t value = 0;
560 	char *key = NULL;
561 	type_datum_t *sepol_attr = NULL;
562 
563 	if (!cil_attr->keep) {
564 		return SEPOL_OK;
565 	}
566 
567 	sepol_attr = cil_malloc(sizeof(*sepol_attr));
568 	type_datum_init(sepol_attr);
569 
570 	sepol_attr->flavor = TYPE_ATTRIB;
571 
572 	key = cil_strdup(cil_attr->datum.fqn);
573 	rc = symtab_insert(pdb, SYM_TYPES, key, sepol_attr, SCOPE_DECL, 0, &value);
574 	if (rc != SEPOL_OK) {
575 		goto exit;
576 	}
577 	sepol_attr->s.value = value;
578 	sepol_attr->primary = 1;
579 
580 	type_value_to_cil[value] = cil_attr;
581 
582 	return SEPOL_OK;
583 
584 exit:
585 	type_datum_destroy(sepol_attr);
586 	free(sepol_attr);
587 	return rc;
588 }
589 
__cil_typeattr_bitmap_init(policydb_t * pdb)590 int __cil_typeattr_bitmap_init(policydb_t *pdb)
591 {
592 	int rc = SEPOL_ERR;
593 	uint32_t i;
594 
595 	pdb->type_attr_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t));
596 	pdb->attr_type_map = cil_malloc(pdb->p_types.nprim * sizeof(ebitmap_t));
597 
598 	for (i = 0; i < pdb->p_types.nprim; i++) {
599 		ebitmap_init(&pdb->type_attr_map[i]);
600 		ebitmap_init(&pdb->attr_type_map[i]);
601 		if (ebitmap_set_bit(&pdb->type_attr_map[i], i, 1)) {
602 			rc = SEPOL_ERR;
603 			goto exit;
604 		}
605 		if (pdb->type_val_to_struct[i] && pdb->type_val_to_struct[i]->flavor != TYPE_ATTRIB) {
606 			if (ebitmap_set_bit(&pdb->attr_type_map[i], i, 1)) {
607 				rc = SEPOL_ERR;
608 				goto exit;
609 			}
610 		}
611 
612 	}
613 
614 	return SEPOL_OK;
615 
616 exit:
617 	return rc;
618 }
619 
cil_typeattribute_to_bitmap(policydb_t * pdb,const struct cil_db * db,struct cil_typeattribute * cil_attr)620 int cil_typeattribute_to_bitmap(policydb_t *pdb, const struct cil_db *db, struct cil_typeattribute *cil_attr)
621 {
622 	int rc = SEPOL_ERR;
623 	uint32_t value = 0;
624 	type_datum_t *sepol_type = NULL;
625 	ebitmap_node_t *tnode;
626 	unsigned int i;
627 
628 	if (!cil_attr->keep) {
629 		return SEPOL_OK;
630 	}
631 
632 	if (pdb->type_attr_map == NULL) {
633 		rc = __cil_typeattr_bitmap_init(pdb);
634 		if (rc != SEPOL_OK) {
635 			goto exit;
636 		}
637 	}
638 
639 	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_attr), &sepol_type);
640 	if (rc != SEPOL_OK) goto exit;
641 
642 	value = sepol_type->s.value;
643 
644 	ebitmap_for_each_positive_bit(cil_attr->types, tnode, i) {
645 		rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type);
646 		if (rc != SEPOL_OK) goto exit;
647 
648 		ebitmap_set_bit(&pdb->type_attr_map[sepol_type->s.value - 1], value - 1, 1);
649 		ebitmap_set_bit(&pdb->attr_type_map[value - 1], sepol_type->s.value - 1, 1);
650 	}
651 
652 	rc = SEPOL_OK;
653 exit:
654 	return rc;
655 }
656 
cil_policycap_to_policydb(policydb_t * pdb,struct cil_policycap * cil_polcap)657 int cil_policycap_to_policydb(policydb_t *pdb, struct cil_policycap *cil_polcap)
658 {
659 	int rc = SEPOL_ERR;
660 	int capnum;
661 
662 	capnum = sepol_polcap_getnum(cil_polcap->datum.fqn);
663 	if (capnum == -1) {
664 		goto exit;
665 	}
666 
667 	if (ebitmap_set_bit(&pdb->policycaps, capnum, 1)) {
668 		goto exit;
669 	}
670 
671 	return SEPOL_OK;
672 
673 exit:
674 	return rc;
675 }
676 
cil_user_to_policydb(policydb_t * pdb,struct cil_user * cil_user)677 int cil_user_to_policydb(policydb_t *pdb, struct cil_user *cil_user)
678 {
679 	int rc = SEPOL_ERR;
680 	uint32_t value = 0;
681 	char *key = NULL;
682 	user_datum_t *sepol_user = cil_malloc(sizeof(*sepol_user));
683 	user_datum_init(sepol_user);
684 
685 	key = cil_strdup(cil_user->datum.fqn);
686 	rc = symtab_insert(pdb, SYM_USERS, key, sepol_user, SCOPE_DECL, 0, &value);
687 	if (rc != SEPOL_OK) {
688 		goto exit;
689 	}
690 	sepol_user->s.value = value;
691 
692 	return SEPOL_OK;
693 
694 exit:
695 	free(key);
696 	user_datum_destroy(sepol_user);
697 	free(sepol_user);
698 	return rc;
699 }
700 
cil_user_bounds_to_policydb(policydb_t * pdb,struct cil_user * cil_user)701 int cil_user_bounds_to_policydb(policydb_t *pdb, struct cil_user *cil_user)
702 {
703 	int rc = SEPOL_ERR;
704 	user_datum_t *sepol_user = NULL;
705 	user_datum_t *sepol_parent = NULL;
706 
707 	if (cil_user->bounds) {
708 		rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user);
709 		if (rc != SEPOL_OK) goto exit;
710 
711 		rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user->bounds), &sepol_parent);
712 		if (rc != SEPOL_OK) goto exit;
713 
714 		sepol_user->bounds = sepol_parent->s.value;
715 	}
716 
717 	return SEPOL_OK;
718 
719 exit:
720 	cil_log(CIL_ERR, "Failed to insert user bounds for user %s\n", cil_user->datum.fqn);
721 	return SEPOL_ERR;
722 }
723 
cil_userrole_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_user * user)724 int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_user *user)
725 {
726 	int rc = SEPOL_ERR;
727 	user_datum_t *sepol_user = NULL;
728 	role_datum_t *sepol_role = NULL;
729 	ebitmap_node_t *rnode = NULL;
730 	unsigned int i;
731 
732 	if (user->roles) {
733 		rc = __cil_get_sepol_user_datum(pdb, DATUM(user), &sepol_user);
734 		if (rc != SEPOL_OK) {
735 			goto exit;
736 		}
737 
738 		ebitmap_for_each_positive_bit(user->roles, rnode, i) {
739 			rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role);
740 			if (rc != SEPOL_OK) {
741 				goto exit;
742 			}
743 
744 			if (sepol_role->s.value == 1) {
745 				// role is object_r, ignore it since it is implicitly associated
746 				// with all users
747 				continue;
748 			}
749 
750 			if (ebitmap_set_bit(&sepol_user->roles.roles, sepol_role->s.value - 1, 1)) {
751 				cil_log(CIL_INFO, "Failed to set role bit for user\n");
752 				rc = SEPOL_ERR;
753 				goto exit;
754 			}
755 		}
756 	}
757 
758 	rc = SEPOL_OK;
759 
760 exit:
761 	return rc;
762 }
763 
cil_bool_to_policydb(policydb_t * pdb,struct cil_bool * cil_bool)764 int cil_bool_to_policydb(policydb_t *pdb, struct cil_bool *cil_bool)
765 {
766 	int rc = SEPOL_ERR;
767 	uint32_t value = 0;
768 	char *key = NULL;
769 	cond_bool_datum_t *sepol_bool = cil_malloc(sizeof(*sepol_bool));
770 	memset(sepol_bool, 0, sizeof(cond_bool_datum_t));
771 
772 	key = cil_strdup(cil_bool->datum.fqn);
773 	rc = symtab_insert(pdb, SYM_BOOLS, key, sepol_bool, SCOPE_DECL, 0, &value);
774 	if (rc != SEPOL_OK) {
775 		goto exit;
776 	}
777 	sepol_bool->s.value = value;
778 	sepol_bool->state = cil_bool->value;
779 
780 	return SEPOL_OK;
781 
782 exit:
783 	free(key);
784 	free(sepol_bool);
785 	return rc;
786 }
787 
cil_catorder_to_policydb(policydb_t * pdb,const struct cil_db * db)788 int cil_catorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
789 {
790 	int rc = SEPOL_ERR;
791 	uint32_t value = 0;
792 	char *key = NULL;
793 	struct cil_list_item *curr_cat;
794 	struct cil_cat *cil_cat = NULL;
795 	cat_datum_t *sepol_cat = NULL;
796 
797 	cil_list_for_each(curr_cat, db->catorder) {
798 		cil_cat = curr_cat->data;
799 		sepol_cat = cil_malloc(sizeof(*sepol_cat));
800 		cat_datum_init(sepol_cat);
801 
802 		key = cil_strdup(cil_cat->datum.fqn);
803 		rc = symtab_insert(pdb, SYM_CATS, key, sepol_cat, SCOPE_DECL, 0, &value);
804 		if (rc != SEPOL_OK) {
805 			goto exit;
806 		}
807 		sepol_cat->s.value = value;
808 	}
809 
810 	return SEPOL_OK;
811 
812 exit:
813 	free(key);
814 	cat_datum_destroy(sepol_cat);
815 	free(sepol_cat);
816 	return rc;
817 }
818 
cil_catalias_to_policydb(policydb_t * pdb,struct cil_alias * cil_alias)819 int cil_catalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias)
820 {
821 	int rc = SEPOL_ERR;
822 	char *key = NULL;
823 	cat_datum_t *sepol_cat;
824 	cat_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_cat));
825 	cat_datum_init(sepol_alias);
826 
827 	rc = __cil_get_sepol_cat_datum(pdb, DATUM(cil_alias->actual), &sepol_cat);
828 	if (rc != SEPOL_OK) goto exit;
829 
830 	key = cil_strdup(cil_alias->datum.fqn);
831 	rc = symtab_insert(pdb, SYM_CATS, key, sepol_alias, SCOPE_DECL, 0, NULL);
832 	if (rc != SEPOL_OK) {
833 		goto exit;
834 	}
835 	sepol_alias->s.value = sepol_cat->s.value;
836 	sepol_alias->isalias = 1;
837 
838 	return SEPOL_OK;
839 
840 exit:
841 	free(key);
842 	cat_datum_destroy(sepol_alias);
843 	free(sepol_alias);
844 	return rc;
845 }
846 
cil_sensitivityorder_to_policydb(policydb_t * pdb,const struct cil_db * db)847 int cil_sensitivityorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
848 {
849 	int rc = SEPOL_ERR;
850 	uint32_t value = 0;
851 	char *key = NULL;
852 	struct cil_list_item *curr;
853 	struct cil_sens *cil_sens = NULL;
854 	level_datum_t *sepol_level = NULL;
855 	mls_level_t *mls_level = NULL;
856 
857 	cil_list_for_each(curr, db->sensitivityorder) {
858 		cil_sens = curr->data;
859 		sepol_level = cil_malloc(sizeof(*sepol_level));
860 		mls_level = cil_malloc(sizeof(*mls_level));
861 		level_datum_init(sepol_level);
862 		mls_level_init(mls_level);
863 
864 		key = cil_strdup(cil_sens->datum.fqn);
865 		rc = symtab_insert(pdb, SYM_LEVELS, key, sepol_level, SCOPE_DECL, 0, &value);
866 		if (rc != SEPOL_OK) {
867 			goto exit;
868 		}
869 		mls_level->sens = value;
870 		sepol_level->level = mls_level;
871 	}
872 
873 	return SEPOL_OK;
874 
875 exit:
876 	level_datum_destroy(sepol_level);
877 	mls_level_destroy(mls_level);
878 	free(sepol_level);
879 	free(mls_level);
880 	free(key);
881 	return rc;
882 }
883 
cil_sensalias_to_policydb(policydb_t * pdb,struct cil_alias * cil_alias)884 int cil_sensalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias)
885 {
886 	int rc = SEPOL_ERR;
887 	char *key = NULL;
888 	mls_level_t *mls_level = NULL;
889 	level_datum_t *sepol_level = NULL;
890 	level_datum_t *sepol_alias = cil_malloc(sizeof(*sepol_alias));
891 	level_datum_init(sepol_alias);
892 
893 	rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_alias->actual), &sepol_level);
894 	if (rc != SEPOL_OK) goto exit;
895 
896 	key = cil_strdup(cil_alias->datum.fqn);
897 	rc = symtab_insert(pdb, SYM_LEVELS, key, sepol_alias, SCOPE_DECL, 0, NULL);
898 	if (rc != SEPOL_OK) {
899 		goto exit;
900 	}
901 
902 	mls_level = cil_malloc(sizeof(*mls_level));
903 	mls_level_init(mls_level);
904 
905 	rc = mls_level_cpy(mls_level, sepol_level->level);
906 	if (rc != SEPOL_OK) {
907 		goto exit;
908 	}
909 	sepol_alias->level = mls_level;
910 	sepol_alias->defined = 1;
911 	sepol_alias->isalias = 1;
912 
913 	return SEPOL_OK;
914 
915 exit:
916 	level_datum_destroy(sepol_alias);
917 	free(sepol_alias);
918 	free(key);
919 	return rc;
920 }
921 
__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)922 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)
923 {
924 	int rc = SEPOL_OK;
925 	avtab_ptr_t avtab_ptr = NULL;
926 	cond_av_list_t *cond_list = NULL;
927 
928 	avtab_ptr = avtab_insert_nonunique(avtab, avtab_key, avtab_datum);
929 	if (!avtab_ptr) {
930 		rc = SEPOL_ERR;
931 		goto exit;
932 	}
933 
934 	// parse_context needs to be non-NULL for conditional rules to be
935 	// written to the binary. it is normally used for finding duplicates,
936 	// but cil checks that earlier, so we don't use it. it just needs to be
937 	// set
938 	avtab_ptr->parse_context = (void*)1;
939 
940 	cond_list = cil_malloc(sizeof(cond_av_list_t));
941 	memset(cond_list, 0, sizeof(cond_av_list_t));
942 
943 	cond_list->node = avtab_ptr;
944 
945 	if (cond_flavor == CIL_CONDTRUE) {
946       cond_list->next = cond_node->true_list;
947       cond_node->true_list = cond_list;
948 	} else {
949       cond_list->next = cond_node->false_list;
950       cond_node->false_list = cond_list;
951 	}
952 
953 exit:
954 	return rc;
955 }
956 
cil_cond_av_list_search(avtab_key_t * key,cond_av_list_t * cond_list)957 avtab_datum_t *cil_cond_av_list_search(avtab_key_t *key, cond_av_list_t *cond_list)
958 {
959 	cond_av_list_t *cur_av;
960 
961 	for (cur_av = cond_list; cur_av != NULL; cur_av = cur_av->next) {
962 		if (cur_av->node->key.source_type == key->source_type &&
963 		    cur_av->node->key.target_type == key->target_type &&
964 		    cur_av->node->key.target_class == key->target_class &&
965 			(cur_av->node->key.specified & key->specified))
966 
967 			return &cur_av->node->datum;
968 
969 	}
970 	return NULL;
971 }
972 
__cil_insert_type_rule(policydb_t * pdb,uint32_t kind,uint32_t src,uint32_t tgt,uint32_t obj,uint32_t res,struct cil_type_rule * cil_rule,cond_node_t * cond_node,enum cil_flavor cond_flavor)973 int __cil_insert_type_rule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t res, struct cil_type_rule *cil_rule, cond_node_t *cond_node, enum cil_flavor cond_flavor)
974 {
975 	int rc = SEPOL_OK;
976 	avtab_key_t avtab_key;
977 	avtab_datum_t avtab_datum;
978 	avtab_ptr_t existing;
979 
980 	avtab_key.source_type = src;
981 	avtab_key.target_type = tgt;
982 	avtab_key.target_class = obj;
983 
984 	switch (kind) {
985 	case CIL_TYPE_TRANSITION:
986 		avtab_key.specified = AVTAB_TRANSITION;
987 		break;
988 	case CIL_TYPE_CHANGE:
989 		avtab_key.specified = AVTAB_CHANGE;
990 		break;
991 	case CIL_TYPE_MEMBER:
992 		avtab_key.specified = AVTAB_MEMBER;
993 		break;
994 	default:
995 		rc = SEPOL_ERR;
996 		goto exit;
997 	}
998 
999 	avtab_datum.data = res;
1000 
1001 	existing = avtab_search_node(&pdb->te_avtab, &avtab_key);
1002 	if (existing) {
1003 		/* Don't add duplicate type rule and warn if they conflict.
1004 		 * A warning should have been previously given if there is a
1005 		 * non-duplicate rule using the same key.
1006 		 */
1007 		if (existing->datum.data != res) {
1008 			cil_log(CIL_ERR, "Conflicting type rules (scontext=%s tcontext=%s tclass=%s result=%s), existing=%s\n",
1009 				pdb->p_type_val_to_name[src - 1],
1010 				pdb->p_type_val_to_name[tgt - 1],
1011 				pdb->p_class_val_to_name[obj - 1],
1012 				pdb->p_type_val_to_name[res - 1],
1013 				pdb->p_type_val_to_name[existing->datum.data - 1]);
1014 			cil_log(CIL_ERR, "Expanded from type rule (scontext=%s tcontext=%s tclass=%s result=%s)\n",
1015 				cil_rule->src_str, cil_rule->tgt_str, cil_rule->obj_str, cil_rule->result_str);
1016 			rc = SEPOL_ERR;
1017 		}
1018 		goto exit;
1019 	}
1020 
1021 	if (!cond_node) {
1022 		rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum);
1023 	} else {
1024 		existing = avtab_search_node(&pdb->te_cond_avtab, &avtab_key);
1025 		if (existing) {
1026 			cond_av_list_t *this_list;
1027 			cond_av_list_t *other_list;
1028 			avtab_datum_t *search_datum;
1029 
1030 			if (cond_flavor == CIL_CONDTRUE) {
1031 				this_list = cond_node->true_list;
1032 				other_list = cond_node->false_list;
1033 			} else {
1034 				this_list = cond_node->false_list;
1035 				other_list = cond_node->true_list;
1036 			}
1037 
1038 			search_datum = cil_cond_av_list_search(&avtab_key, other_list);
1039 			if (search_datum == NULL) {
1040 				if (existing->datum.data != res) {
1041 					cil_log(CIL_ERR, "Conflicting type rules (scontext=%s tcontext=%s tclass=%s result=%s), existing=%s\n",
1042 						pdb->p_type_val_to_name[src - 1],
1043 						pdb->p_type_val_to_name[tgt - 1],
1044 						pdb->p_class_val_to_name[obj - 1],
1045 						pdb->p_type_val_to_name[res - 1],
1046 						pdb->p_type_val_to_name[existing->datum.data - 1]);
1047 					cil_log(CIL_ERR, "Expanded from type rule (scontext=%s tcontext=%s tclass=%s result=%s)\n",
1048 						cil_rule->src_str, cil_rule->tgt_str, cil_rule->obj_str, cil_rule->result_str);
1049 					rc = SEPOL_ERR;
1050 					goto exit;
1051 				}
1052 
1053 				search_datum = cil_cond_av_list_search(&avtab_key, this_list);
1054 				if (search_datum) {
1055 					goto exit;
1056 				}
1057 			}
1058 		}
1059 		rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor);
1060 	}
1061 
1062 exit:
1063 	return rc;
1064 }
1065 
__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)1066 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)
1067 {
1068 	int rc = SEPOL_ERR;
1069 	uint16_t kind = cil_rule->rule_kind;
1070 	type_datum_t *sepol_src = NULL;
1071 	type_datum_t *sepol_tgt = NULL;
1072 	class_datum_t *sepol_obj = NULL;
1073 	struct cil_list *class_list = NULL;
1074 	type_datum_t *sepol_result = NULL;
1075 	ebitmap_t src_bitmap, tgt_bitmap;
1076 	ebitmap_node_t *node1, *node2;
1077 	unsigned int i, j;
1078 	struct cil_list_item *c;
1079 
1080 	rc = __cil_expand_type(cil_rule->src, &src_bitmap);
1081 	if (rc != SEPOL_OK) goto exit;
1082 
1083 	rc = __cil_expand_type(cil_rule->tgt, &tgt_bitmap);
1084 	if (rc != SEPOL_OK) goto exit;
1085 
1086 	class_list = cil_expand_class(cil_rule->obj);
1087 
1088 	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_rule->result), &sepol_result);
1089 	if (rc != SEPOL_OK) goto exit;
1090 
1091 	ebitmap_for_each_positive_bit(&src_bitmap, node1, i) {
1092 		rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src);
1093 		if (rc != SEPOL_OK) goto exit;
1094 
1095 		ebitmap_for_each_positive_bit(&tgt_bitmap, node2, j) {
1096 			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
1097 			if (rc != SEPOL_OK) goto exit;
1098 
1099 			cil_list_for_each(c, class_list) {
1100 				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
1101 				if (rc != SEPOL_OK) goto exit;
1102 
1103 				rc = __cil_insert_type_rule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, sepol_result->s.value, cil_rule, cond_node, cond_flavor);
1104 				if (rc != SEPOL_OK) goto exit;
1105 			}
1106 		}
1107 	}
1108 
1109 	rc = SEPOL_OK;
1110 
1111 exit:
1112 	ebitmap_destroy(&src_bitmap);
1113 	ebitmap_destroy(&tgt_bitmap);
1114 	cil_list_destroy(&class_list, CIL_FALSE);
1115 	return rc;
1116 }
1117 
cil_type_rule_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_type_rule * cil_rule)1118 int cil_type_rule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_type_rule *cil_rule)
1119 {
1120 	return  __cil_type_rule_to_avtab(pdb, db, cil_rule, NULL, CIL_FALSE);
1121 }
1122 
__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)1123 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)
1124 {
1125 	int rc = SEPOL_ERR;
1126 	type_datum_t *sepol_src = NULL;
1127 	type_datum_t *sepol_tgt = NULL;
1128 	class_datum_t *sepol_obj = NULL;
1129 	struct cil_list *class_list = NULL;
1130 	type_datum_t *sepol_result = NULL;
1131 	ebitmap_t src_bitmap, tgt_bitmap;
1132 	ebitmap_node_t *node1, *node2;
1133 	unsigned int i, j;
1134 	uint32_t otype;
1135 	struct cil_list_item *c;
1136 	char *name = DATUM(typetrans->name)->name;
1137 
1138 	if (name == CIL_KEY_STAR) {
1139 		struct cil_type_rule trans;
1140 		trans.rule_kind = CIL_TYPE_TRANSITION;
1141 		trans.src = typetrans->src;
1142 		trans.tgt = typetrans->tgt;
1143 		trans.obj = typetrans->obj;
1144 		trans.result = typetrans->result;
1145 		trans.src_str = typetrans->src_str;
1146 		trans.tgt_str = typetrans->tgt_str;
1147 		trans.obj_str = typetrans->obj_str;
1148 		trans.result_str = typetrans->result_str;
1149 		return __cil_type_rule_to_avtab(pdb, db, &trans, cond_node, cond_flavor);
1150 	}
1151 
1152 	rc = __cil_expand_type(typetrans->src, &src_bitmap);
1153 	if (rc != SEPOL_OK) goto exit;
1154 
1155 	rc = __cil_expand_type(typetrans->tgt, &tgt_bitmap);
1156 	if (rc != SEPOL_OK) goto exit;
1157 
1158 	class_list = cil_expand_class(typetrans->obj);
1159 
1160 	rc = __cil_get_sepol_type_datum(pdb, DATUM(typetrans->result), &sepol_result);
1161 	if (rc != SEPOL_OK) goto exit;
1162 
1163 	ebitmap_for_each_positive_bit(&src_bitmap, node1, i) {
1164 		rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src);
1165 		if (rc != SEPOL_OK) goto exit;
1166 
1167 		ebitmap_for_each_positive_bit(&tgt_bitmap, node2, j) {
1168 			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
1169 			if (rc != SEPOL_OK) goto exit;
1170 
1171 			cil_list_for_each(c, class_list) {
1172 				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
1173 				if (rc != SEPOL_OK) goto exit;
1174 
1175 				rc = policydb_filetrans_insert(
1176 					pdb, sepol_src->s.value, sepol_tgt->s.value,
1177 					sepol_obj->s.value, name, NULL,
1178 					sepol_result->s.value, &otype
1179 				);
1180 				if (rc != SEPOL_OK) {
1181 					if (rc == SEPOL_EEXIST) {
1182 						if (sepol_result->s.value!= otype) {
1183 							cil_log(CIL_ERR, "Conflicting name type transition rules\n");
1184 						} else {
1185 							rc = SEPOL_OK;
1186 						}
1187 					} else {
1188 						cil_log(CIL_ERR, "Out of memory\n");
1189 					}
1190 					if (rc != SEPOL_OK) {
1191 						goto exit;
1192 					}
1193 				}
1194 			}
1195 		}
1196 	}
1197 
1198 	rc = SEPOL_OK;
1199 
1200 exit:
1201 	ebitmap_destroy(&src_bitmap);
1202 	ebitmap_destroy(&tgt_bitmap);
1203 	cil_list_destroy(&class_list, CIL_FALSE);
1204 	return rc;
1205 }
1206 
cil_typetransition_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_nametypetransition * typetrans)1207 int cil_typetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans)
1208 {
1209 	return  __cil_typetransition_to_avtab(pdb, db, typetrans, NULL, CIL_FALSE);
1210 }
1211 
__perm_str_to_datum(char * perm_str,class_datum_t * sepol_class,uint32_t * datum)1212 int __perm_str_to_datum(char *perm_str, class_datum_t *sepol_class, uint32_t *datum)
1213 {
1214 	int rc;
1215 	perm_datum_t *sepol_perm;
1216 	common_datum_t *sepol_common;
1217 
1218 	sepol_perm = hashtab_search(sepol_class->permissions.table, perm_str);
1219 	if (sepol_perm == NULL) {
1220 		sepol_common = sepol_class->comdatum;
1221 		sepol_perm = hashtab_search(sepol_common->permissions.table, perm_str);
1222 		if (sepol_perm == NULL) {
1223 			cil_log(CIL_ERR, "Failed to find datum for perm %s\n", perm_str);
1224 			rc = SEPOL_ERR;
1225 			goto exit;
1226 		}
1227 	}
1228 	*datum |= UINT32_C(1) << (sepol_perm->s.value - 1);
1229 
1230 	return SEPOL_OK;
1231 
1232 exit:
1233 	return rc;
1234 }
1235 
__cil_perms_to_datum(struct cil_list * perms,class_datum_t * sepol_class,uint32_t * datum)1236 int __cil_perms_to_datum(struct cil_list *perms, class_datum_t *sepol_class, uint32_t *datum)
1237 {
1238 	int rc = SEPOL_ERR;
1239 	char *key = NULL;
1240 	struct cil_list_item *curr_perm;
1241 	struct cil_perm *cil_perm;
1242 	uint32_t data = 0;
1243 
1244 	cil_list_for_each(curr_perm, perms) {
1245 		cil_perm = curr_perm->data;
1246 		key = cil_perm->datum.fqn;
1247 
1248 		rc = __perm_str_to_datum(key, sepol_class, &data);
1249 		if (rc != SEPOL_OK) {
1250 			goto exit;
1251 		}
1252 	}
1253 
1254 	*datum = data;
1255 
1256 	return SEPOL_OK;
1257 
1258 exit:
1259 	return rc;
1260 }
1261 
__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)1262 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)
1263 {
1264 	int rc = SEPOL_OK;
1265 	avtab_key_t avtab_key;
1266 	avtab_datum_t avtab_datum;
1267 	avtab_datum_t *avtab_dup = NULL;
1268 
1269 	avtab_key.source_type = src;
1270 	avtab_key.target_type = tgt;
1271 	avtab_key.target_class = obj;
1272 
1273 	switch (kind) {
1274 	case CIL_AVRULE_ALLOWED:
1275 		avtab_key.specified = AVTAB_ALLOWED;
1276 		break;
1277 	case CIL_AVRULE_AUDITALLOW:
1278 		avtab_key.specified = AVTAB_AUDITALLOW;
1279 		break;
1280 	case CIL_AVRULE_DONTAUDIT:
1281 		avtab_key.specified = AVTAB_AUDITDENY;
1282 		break;
1283 	default:
1284 		rc = SEPOL_ERR;
1285 		goto exit;
1286 		break;
1287 	}
1288 
1289 	if (!cond_node) {
1290 		avtab_dup = avtab_search(&pdb->te_avtab, &avtab_key);
1291 		if (!avtab_dup) {
1292 			avtab_datum.data = data;
1293 			rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum);
1294 		} else {
1295 			if (kind == CIL_AVRULE_DONTAUDIT)
1296 				avtab_dup->data &= data;
1297 			else
1298 				avtab_dup->data |= data;
1299 		}
1300 	} else {
1301 		avtab_datum.data = data;
1302 		rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor);
1303 	}
1304 
1305 exit:
1306 	return rc;
1307 }
1308 
__cil_avrule_expand_helper(policydb_t * pdb,uint16_t kind,struct cil_symtab_datum * src,struct cil_symtab_datum * tgt,struct cil_classperms * cp,cond_node_t * cond_node,enum cil_flavor cond_flavor)1309 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, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1310 {
1311 	int rc = SEPOL_ERR;
1312 	type_datum_t *sepol_src = NULL;
1313 	type_datum_t *sepol_tgt = NULL;
1314 	class_datum_t *sepol_class = NULL;
1315 	uint32_t data = 0;
1316 
1317 	rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class);
1318 	if (rc != SEPOL_OK) goto exit;
1319 
1320 	rc = __cil_perms_to_datum(cp->perms, sepol_class, &data);
1321 	if (rc != SEPOL_OK) goto exit;
1322 
1323 	if (data == 0) {
1324 		/* No permissions, so don't insert rule. Maybe should return an error? */
1325 		return SEPOL_OK;
1326 	}
1327 
1328 	if (kind == CIL_AVRULE_DONTAUDIT) {
1329 		data = ~data;
1330 	}
1331 
1332 	rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src);
1333 	if (rc != SEPOL_OK) goto exit;
1334 
1335 	rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt);
1336 	if (rc != SEPOL_OK) goto exit;
1337 
1338 	rc = __cil_insert_avrule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_class->s.value, data, cond_node, cond_flavor);
1339 	if (rc != SEPOL_OK) {
1340 		goto exit;
1341 	}
1342 
1343 	return SEPOL_OK;
1344 
1345 exit:
1346 	return rc;
1347 }
1348 
1349 
__cil_avrule_expand(policydb_t * pdb,uint16_t kind,struct cil_symtab_datum * src,struct cil_symtab_datum * tgt,struct cil_list * classperms,cond_node_t * cond_node,enum cil_flavor cond_flavor)1350 int __cil_avrule_expand(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1351 {
1352 	int rc = SEPOL_ERR;
1353 	struct cil_list_item *curr;
1354 
1355 	cil_list_for_each(curr, classperms) {
1356 		if (curr->flavor == CIL_CLASSPERMS) {
1357 			struct cil_classperms *cp = curr->data;
1358 			if (FLAVOR(cp->class) == CIL_CLASS) {
1359 				rc = __cil_avrule_expand_helper(pdb, kind, src, tgt, cp, cond_node, cond_flavor);
1360 				if (rc != SEPOL_OK) {
1361 					goto exit;
1362 				}
1363 			} else { /* MAP */
1364 				struct cil_list_item *i = NULL;
1365 				cil_list_for_each(i, cp->perms) {
1366 					struct cil_perm *cmp = i->data;
1367 					rc = __cil_avrule_expand(pdb, kind, src, tgt, cmp->classperms, cond_node, cond_flavor);
1368 					if (rc != SEPOL_OK) {
1369 						goto exit;
1370 					}
1371 				}
1372 			}
1373 		} else { /* SET */
1374 			struct cil_classperms_set *cp_set = curr->data;
1375 			struct cil_classpermission *cp = cp_set->set;
1376 			rc = __cil_avrule_expand(pdb, kind, src, tgt, cp->classperms, cond_node, cond_flavor);
1377 			if (rc != SEPOL_OK) {
1378 				goto exit;
1379 			}
1380 		}
1381 	}
1382 
1383 	return SEPOL_OK;
1384 
1385 exit:
1386 	return rc;
1387 }
1388 
__cil_should_expand_attribute(const struct cil_db * db,struct cil_symtab_datum * datum)1389 static int __cil_should_expand_attribute( const struct cil_db *db, struct cil_symtab_datum *datum)
1390 {
1391 	struct cil_tree_node *node;
1392 	struct cil_typeattribute *attr;
1393 
1394 	node = NODE(datum);
1395 
1396 	if (node->flavor != CIL_TYPEATTRIBUTE) {
1397 		return CIL_FALSE;
1398 	}
1399 
1400 	attr = (struct cil_typeattribute *)datum;
1401 
1402 	return !attr->keep || (ebitmap_cardinality(attr->types) < db->attrs_expand_size);
1403 }
1404 
__cil_avrule_to_avtab(policydb_t * pdb,const struct cil_db * db,struct cil_avrule * cil_avrule,cond_node_t * cond_node,enum cil_flavor cond_flavor)1405 int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, cond_node_t *cond_node, enum cil_flavor cond_flavor)
1406 {
1407 	int rc = SEPOL_ERR;
1408 	uint16_t kind = cil_avrule->rule_kind;
1409 	struct cil_symtab_datum *src = NULL;
1410 	struct cil_symtab_datum *tgt = NULL;
1411 	struct cil_list *classperms = cil_avrule->perms.classperms;
1412 	ebitmap_t src_bitmap, tgt_bitmap;
1413 	ebitmap_node_t *snode, *tnode;
1414 	unsigned int s,t;
1415 
1416 	if (cil_avrule->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) {
1417 		// Do not add dontaudit rules to binary
1418 		rc = SEPOL_OK;
1419 		goto exit;
1420 	}
1421 
1422 	src = cil_avrule->src;
1423 	tgt = cil_avrule->tgt;
1424 
1425 	if (tgt->fqn == CIL_KEY_SELF) {
1426 		rc = __cil_expand_type(src, &src_bitmap);
1427 		if (rc != SEPOL_OK) {
1428 			goto exit;
1429 		}
1430 
1431 		ebitmap_for_each_positive_bit(&src_bitmap, snode, s) {
1432 			src = DATUM(db->val_to_type[s]);
1433 			rc = __cil_avrule_expand(pdb, kind, src, src, classperms, cond_node, cond_flavor);
1434 			if (rc != SEPOL_OK) {
1435 				ebitmap_destroy(&src_bitmap);
1436 				goto exit;
1437 			}
1438 		}
1439 		ebitmap_destroy(&src_bitmap);
1440 	} else {
1441 		int expand_src = __cil_should_expand_attribute(db, src);
1442 		int expand_tgt = __cil_should_expand_attribute(db, tgt);
1443 		if (!expand_src && !expand_tgt) {
1444 			rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor);
1445 			if (rc != SEPOL_OK) {
1446 				goto exit;
1447 			}
1448 		} else if (expand_src && expand_tgt) {
1449 			rc = __cil_expand_type(src, &src_bitmap);
1450 			if (rc != SEPOL_OK) {
1451 				goto exit;
1452 			}
1453 
1454 			rc = __cil_expand_type(tgt, &tgt_bitmap);
1455 			if (rc != SEPOL_OK) {
1456 				ebitmap_destroy(&src_bitmap);
1457 				goto exit;
1458 			}
1459 
1460 			ebitmap_for_each_positive_bit(&src_bitmap, snode, s) {
1461 				src = DATUM(db->val_to_type[s]);
1462 				ebitmap_for_each_positive_bit(&tgt_bitmap, tnode, t) {
1463 					tgt = DATUM(db->val_to_type[t]);
1464 
1465 					rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor);
1466 					if (rc != SEPOL_OK) {
1467 						ebitmap_destroy(&src_bitmap);
1468 						ebitmap_destroy(&tgt_bitmap);
1469 						goto exit;
1470 					}
1471 				}
1472 			}
1473 			ebitmap_destroy(&src_bitmap);
1474 			ebitmap_destroy(&tgt_bitmap);
1475 		} else if (expand_src) {
1476 			rc = __cil_expand_type(src, &src_bitmap);
1477 			if (rc != SEPOL_OK) {
1478 				goto exit;
1479 			}
1480 
1481 			ebitmap_for_each_positive_bit(&src_bitmap, snode, s) {
1482 				src = DATUM(db->val_to_type[s]);
1483 
1484 				rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor);
1485 				if (rc != SEPOL_OK) {
1486 					ebitmap_destroy(&src_bitmap);
1487 					goto exit;
1488 				}
1489 			}
1490 			ebitmap_destroy(&src_bitmap);
1491 		} else { /* expand_tgt */
1492 			rc = __cil_expand_type(tgt, &tgt_bitmap);
1493 			if (rc != SEPOL_OK) {
1494 				goto exit;
1495 			}
1496 
1497 			ebitmap_for_each_positive_bit(&tgt_bitmap, tnode, t) {
1498 				tgt = DATUM(db->val_to_type[t]);
1499 
1500 				rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor);
1501 				if (rc != SEPOL_OK) {
1502 					ebitmap_destroy(&tgt_bitmap);
1503 					goto exit;
1504 				}
1505 			}
1506 			ebitmap_destroy(&tgt_bitmap);
1507 		}
1508 	}
1509 
1510 	return SEPOL_OK;
1511 
1512 exit:
1513 	return rc;
1514 }
1515 
cil_avrule_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_avrule * cil_avrule)1516 int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule)
1517 {
1518 	return __cil_avrule_to_avtab(pdb, db, cil_avrule, NULL, CIL_FALSE);
1519 }
1520 
1521 // Copied from checkpolicy/policy_define.c
1522 
1523 /* index of the u32 containing the permission */
1524 #define XPERM_IDX(x) (x >> 5)
1525 /* set bits 0 through x-1 within the u32 */
1526 #define XPERM_SETBITS(x) ((UINT32_C(1) << (x & 0x1f)) - 1)
1527 /* low value for this u32 */
1528 #define XPERM_LOW(x) (x << 5)
1529 /* high value for this u32 */
1530 #define XPERM_HIGH(x) (((x + 1) << 5) - 1)
__avrule_xperm_setrangebits(uint16_t low,uint16_t high,struct avtab_extended_perms * xperms)1531 void __avrule_xperm_setrangebits(uint16_t low, uint16_t high, struct avtab_extended_perms *xperms)
1532 {
1533 	unsigned int i;
1534 	uint16_t h = high + 1;
1535 	/* for each u32 that this low-high range touches, set driver permissions */
1536 	for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) {
1537 		/* set all bits in u32 */
1538 		if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
1539 			xperms->perms[i] |= ~0U;
1540 		/* set low bits */
1541 		else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i)))
1542 			xperms->perms[i] |= XPERM_SETBITS(h);
1543 		/* set high bits */
1544 		else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
1545 			xperms->perms[i] |= ~0U - XPERM_SETBITS(low);
1546 		/* set middle bits */
1547 		else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i)))
1548 			xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low);
1549 	}
1550 }
1551 
1552 
1553 #define IOC_DRIV(x) (x >> 8)
1554 #define IOC_FUNC(x) (x & 0xff)
1555 
__cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t * xperms,struct cil_list ** xperms_list)1556 int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil_list **xperms_list)
1557 {
1558 	ebitmap_node_t *node;
1559 	unsigned int i;
1560 	uint16_t low = 0, high = 0;
1561 	struct avtab_extended_perms *partial = NULL;
1562 	struct avtab_extended_perms *complete = NULL;
1563 	int start_new_range;
1564 
1565 	cil_list_init(xperms_list, CIL_NONE);
1566 
1567 	start_new_range = 1;
1568 
1569 	ebitmap_for_each_positive_bit(xperms, node, i) {
1570 		if (start_new_range) {
1571 			low = i;
1572 			start_new_range = 0;
1573 		}
1574 
1575 		// continue if the current bit isn't the end of the driver function or the next bit is set
1576 		if (IOC_FUNC(i) != 0xff && ebitmap_get_bit(xperms, i + 1)) {
1577 			continue;
1578 		}
1579 
1580 		// if we got here, i is the end of this range (either because the func
1581 		// is 0xff or the next bit isn't set). The next time around we are
1582 		// going to need a start a new range
1583 		high = i;
1584 		start_new_range = 1;
1585 
1586 		if (IOC_FUNC(low) == 0x00 && IOC_FUNC(high) == 0xff) {
1587 			if (!complete) {
1588 				complete = cil_calloc(1, sizeof(*complete));
1589 				complete->driver = 0x0;
1590 				complete->specified = AVTAB_XPERMS_IOCTLDRIVER;
1591 			}
1592 
1593 			__avrule_xperm_setrangebits(IOC_DRIV(low), IOC_DRIV(low), complete);
1594 		} else {
1595 			if (partial && partial->driver != IOC_DRIV(low)) {
1596 				cil_list_append(*xperms_list, CIL_NONE, partial);
1597 				partial = NULL;
1598 			}
1599 
1600 			if (!partial) {
1601 				partial = cil_calloc(1, sizeof(*partial));
1602 				partial->driver = IOC_DRIV(low);
1603 				partial->specified = AVTAB_XPERMS_IOCTLFUNCTION;
1604 			}
1605 
1606 			__avrule_xperm_setrangebits(IOC_FUNC(low), IOC_FUNC(high), partial);
1607 		}
1608 	}
1609 
1610 	if (partial) {
1611 		cil_list_append(*xperms_list, CIL_NONE, partial);
1612 	}
1613 
1614 	if (complete) {
1615 		cil_list_append(*xperms_list, CIL_NONE, complete);
1616 	}
1617 
1618 	return SEPOL_OK;
1619 }
1620 
__cil_avrulex_ioctl_to_policydb(hashtab_key_t k,hashtab_datum_t datum,void * args)1621 int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args)
1622 {
1623 	int rc = SEPOL_OK;
1624 	struct policydb *pdb;
1625 	avtab_key_t *avtab_key;
1626 	avtab_datum_t avtab_datum;
1627 	struct cil_list *xperms_list = NULL;
1628 	struct cil_list_item *item;
1629 	class_datum_t *sepol_obj;
1630 	uint32_t data = 0;
1631 
1632 	avtab_key = (avtab_key_t *)k;
1633 	pdb = args;
1634 
1635 	sepol_obj = pdb->class_val_to_struct[avtab_key->target_class - 1];
1636 
1637 	// setting the data for an extended avtab isn't really necessary because
1638 	// it is ignored by the kernel. However, neverallow checking requires that
1639 	// the data value be set, so set it for that to work.
1640 	rc = __perm_str_to_datum(CIL_KEY_IOCTL, sepol_obj, &data);
1641 	if (rc != SEPOL_OK) {
1642 		goto exit;
1643 	}
1644 	avtab_datum.data = data;
1645 
1646 	rc = __cil_permx_bitmap_to_sepol_xperms_list(datum, &xperms_list);
1647 	if (rc != SEPOL_OK) {
1648 		goto exit;
1649 	}
1650 
1651 	cil_list_for_each(item, xperms_list) {
1652 		avtab_datum.xperms = item->data;
1653 		rc = avtab_insert(&pdb->te_avtab, avtab_key, &avtab_datum);
1654 		if (rc != SEPOL_OK) {
1655 			goto exit;
1656 		}
1657 	}
1658 
1659 	rc = SEPOL_OK;
1660 
1661 exit:
1662 	if (xperms_list != NULL) {
1663 		cil_list_for_each(item, xperms_list) {
1664 			free(item->data);
1665 		}
1666 		cil_list_destroy(&xperms_list, CIL_FALSE);
1667 	}
1668 	return rc;
1669 }
1670 
__cil_avrulex_ioctl_to_hashtable(hashtab_t h,uint16_t kind,uint32_t src,uint32_t tgt,uint32_t obj,ebitmap_t * xperms)1671 int __cil_avrulex_ioctl_to_hashtable(hashtab_t h, uint16_t kind, uint32_t src, uint32_t tgt, uint32_t obj, ebitmap_t *xperms)
1672 {
1673 	uint16_t specified;
1674 	avtab_key_t *avtab_key;
1675 	ebitmap_t *hashtab_xperms;
1676 	int rc = SEPOL_ERR;
1677 
1678 	switch (kind) {
1679 	case CIL_AVRULE_ALLOWED:
1680 		specified = AVTAB_XPERMS_ALLOWED;
1681 		break;
1682 	case CIL_AVRULE_AUDITALLOW:
1683 		specified = AVTAB_XPERMS_AUDITALLOW;
1684 		break;
1685 	case CIL_AVRULE_DONTAUDIT:
1686 		specified = AVTAB_XPERMS_DONTAUDIT;
1687 		break;
1688 	default:
1689 		rc = SEPOL_ERR;
1690 		goto exit;
1691 	}
1692 
1693 	avtab_key = cil_malloc(sizeof(*avtab_key));
1694 	avtab_key->source_type = src;
1695 	avtab_key->target_type = tgt;
1696 	avtab_key->target_class = obj;
1697 	avtab_key->specified = specified;
1698 
1699 	hashtab_xperms = (ebitmap_t *)hashtab_search(h, (hashtab_key_t)avtab_key);
1700 	if (!hashtab_xperms) {
1701 		hashtab_xperms = cil_malloc(sizeof(*hashtab_xperms));
1702 		rc = ebitmap_cpy(hashtab_xperms, xperms);
1703 		if (rc != SEPOL_OK) {
1704 			free(hashtab_xperms);
1705 			free(avtab_key);
1706 			goto exit;
1707 		}
1708 		rc = hashtab_insert(h, (hashtab_key_t)avtab_key, hashtab_xperms);
1709 		if (rc != SEPOL_OK) {
1710 			free(hashtab_xperms);
1711 			free(avtab_key);
1712 			goto exit;
1713 		}
1714 	} else {
1715 		free(avtab_key);
1716 		rc = ebitmap_union(hashtab_xperms, xperms);
1717 		if (rc != SEPOL_OK) {
1718 			goto exit;
1719 		}
1720 	}
1721 
1722 	return SEPOL_OK;
1723 
1724 exit:
1725 	return rc;
1726 }
1727 
__cil_avrulex_to_hashtable_helper(policydb_t * pdb,uint16_t kind,struct cil_symtab_datum * src,struct cil_symtab_datum * tgt,struct cil_permissionx * permx,struct cil_args_binary * args)1728 int __cil_avrulex_to_hashtable_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_permissionx *permx, struct cil_args_binary *args)
1729 {
1730 	int rc = SEPOL_ERR;
1731 	type_datum_t *sepol_src = NULL;
1732 	type_datum_t *sepol_tgt = NULL;
1733 	class_datum_t *sepol_obj = NULL;
1734 	struct cil_list *class_list = NULL;
1735 	struct cil_list_item *c;
1736 
1737 	rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src);
1738 	if (rc != SEPOL_OK) goto exit;
1739 
1740 	rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt);
1741 	if (rc != SEPOL_OK) goto exit;
1742 
1743 	class_list = cil_expand_class(permx->obj);
1744 
1745 	cil_list_for_each(c, class_list) {
1746 		rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
1747 		if (rc != SEPOL_OK) goto exit;
1748 
1749 		switch (permx->kind) {
1750 		case  CIL_PERMX_KIND_IOCTL:
1751 			rc = __cil_avrulex_ioctl_to_hashtable(args->avrulex_ioctl_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms);
1752 			if (rc != SEPOL_OK) goto exit;
1753 			break;
1754 		default:
1755 			rc = SEPOL_ERR;
1756 			goto exit;
1757 		}
1758 	}
1759 
1760 	rc = SEPOL_OK;
1761 
1762 exit:
1763 	cil_list_destroy(&class_list, CIL_FALSE);
1764 
1765 	return rc;
1766 }
1767 
cil_avrulex_to_hashtable(policydb_t * pdb,const struct cil_db * db,struct cil_avrule * cil_avrulex,struct cil_args_binary * args)1768 int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrulex, struct cil_args_binary *args)
1769 {
1770 	int rc = SEPOL_ERR;
1771 	uint16_t kind;
1772 	struct cil_symtab_datum *src = NULL;
1773 	struct cil_symtab_datum *tgt = NULL;
1774 	ebitmap_t src_bitmap, tgt_bitmap;
1775 	ebitmap_node_t *snode, *tnode;
1776 	unsigned int s,t;
1777 
1778 	if (cil_avrulex->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) {
1779 		// Do not add dontaudit rules to binary
1780 		rc = SEPOL_OK;
1781 		goto exit;
1782 	}
1783 
1784 	kind = cil_avrulex->rule_kind;
1785 	src = cil_avrulex->src;
1786 	tgt = cil_avrulex->tgt;
1787 
1788 	if (tgt->fqn == CIL_KEY_SELF) {
1789 		rc = __cil_expand_type(src, &src_bitmap);
1790 		if (rc != SEPOL_OK) goto exit;
1791 
1792 		ebitmap_for_each_positive_bit(&src_bitmap, snode, s) {
1793 			src = DATUM(db->val_to_type[s]);
1794 			rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, src, cil_avrulex->perms.x.permx, args);
1795 			if (rc != SEPOL_OK) {
1796 				goto exit;
1797 			}
1798 		}
1799 		ebitmap_destroy(&src_bitmap);
1800 	} else {
1801 		int expand_src = __cil_should_expand_attribute(db, src);
1802 		int expand_tgt = __cil_should_expand_attribute(db, tgt);
1803 
1804 		if (!expand_src && !expand_tgt) {
1805 			rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args);
1806 			if (rc != SEPOL_OK) {
1807 				goto exit;
1808 			}
1809 		} else if (expand_src && expand_tgt) {
1810 			rc = __cil_expand_type(src, &src_bitmap);
1811 			if (rc != SEPOL_OK) {
1812 				goto exit;
1813 			}
1814 
1815 			rc = __cil_expand_type(tgt, &tgt_bitmap);
1816 			if (rc != SEPOL_OK) {
1817 				ebitmap_destroy(&src_bitmap);
1818 				goto exit;
1819 			}
1820 
1821 			ebitmap_for_each_positive_bit(&src_bitmap, snode, s) {
1822 				src = DATUM(db->val_to_type[s]);
1823 				ebitmap_for_each_positive_bit(&tgt_bitmap, tnode, t) {
1824 					tgt = DATUM(db->val_to_type[t]);
1825 
1826 					rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args);
1827 					if (rc != SEPOL_OK) {
1828 						ebitmap_destroy(&src_bitmap);
1829 						ebitmap_destroy(&tgt_bitmap);
1830 						goto exit;
1831 					}
1832 				}
1833 			}
1834 			ebitmap_destroy(&src_bitmap);
1835 			ebitmap_destroy(&tgt_bitmap);
1836 		} else if (expand_src) {
1837 			rc = __cil_expand_type(src, &src_bitmap);
1838 			if (rc != SEPOL_OK) {
1839 				goto exit;
1840 			}
1841 
1842 			ebitmap_for_each_positive_bit(&src_bitmap, snode, s) {
1843 				src = DATUM(db->val_to_type[s]);
1844 
1845 				rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args);
1846 				if (rc != SEPOL_OK) {
1847 					ebitmap_destroy(&src_bitmap);
1848 					goto exit;
1849 				}
1850 			}
1851 			ebitmap_destroy(&src_bitmap);
1852 		} else { /* expand_tgt */
1853 			rc = __cil_expand_type(tgt, &tgt_bitmap);
1854 			if (rc != SEPOL_OK) {
1855 				goto exit;
1856 			}
1857 
1858 			ebitmap_for_each_positive_bit(&tgt_bitmap, tnode, t) {
1859 				tgt = DATUM(db->val_to_type[t]);
1860 
1861 				rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args);
1862 				if (rc != SEPOL_OK) {
1863 					ebitmap_destroy(&tgt_bitmap);
1864 					goto exit;
1865 				}
1866 			}
1867 			ebitmap_destroy(&tgt_bitmap);
1868 		}
1869 	}
1870 
1871 	return SEPOL_OK;
1872 
1873 exit:
1874 	return rc;
1875 }
1876 
__cil_avrulex_ioctl_destroy(hashtab_key_t k,hashtab_datum_t datum,void * args)1877 static int __cil_avrulex_ioctl_destroy(hashtab_key_t k, hashtab_datum_t datum, __attribute__((unused)) void *args)
1878 {
1879 	free(k);
1880 	ebitmap_destroy(datum);
1881 	free(datum);
1882 
1883 	return SEPOL_OK;
1884 }
1885 
__cil_cond_to_policydb_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1886 int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
1887 {
1888 	int rc;
1889 	enum cil_flavor flavor;
1890 	struct cil_args_booleanif *args = extra_args;
1891 	const struct cil_db *db = args->db;
1892 	policydb_t *pdb = args->pdb;
1893 	cond_node_t *cond_node = args->cond_node;
1894 	enum cil_flavor cond_flavor = args->cond_flavor;
1895 	struct cil_type_rule *cil_type_rule;
1896 	struct cil_avrule *cil_avrule;
1897 	struct cil_nametypetransition *cil_typetrans;
1898 
1899 	flavor = node->flavor;
1900 	switch (flavor) {
1901 	case CIL_NAMETYPETRANSITION:
1902 		cil_typetrans = (struct cil_nametypetransition*)node->data;
1903 		if (DATUM(cil_typetrans->name)->fqn != CIL_KEY_STAR) {
1904 			cil_log(CIL_ERR, "typetransition with file name not allowed within a booleanif block.\n");
1905 			cil_tree_log(node, CIL_ERR,"Invalid typetransition statement");
1906 			goto exit;
1907 		}
1908 		rc = __cil_typetransition_to_avtab(pdb, db, cil_typetrans, cond_node, cond_flavor);
1909 		if (rc != SEPOL_OK) {
1910 			cil_tree_log(node, CIL_ERR, "Failed to insert type transition into avtab");
1911 			goto exit;
1912 		}
1913 		break;
1914 	case CIL_TYPE_RULE:
1915 		cil_type_rule = node->data;
1916 		rc = __cil_type_rule_to_avtab(pdb, db, cil_type_rule, cond_node, cond_flavor);
1917 		if (rc != SEPOL_OK) {
1918 			cil_tree_log(node, CIL_ERR, "Failed to insert typerule into avtab");
1919 			goto exit;
1920 		}
1921 		break;
1922 	case CIL_AVRULE:
1923 		cil_avrule = node->data;
1924 		rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, cond_node, cond_flavor);
1925 		if (rc != SEPOL_OK) {
1926 			cil_tree_log(node, CIL_ERR, "Failed to insert avrule into avtab");
1927 			goto exit;
1928 		}
1929 		break;
1930 	case CIL_CALL:
1931 	case CIL_TUNABLEIF:
1932 		break;
1933 	default:
1934 		cil_tree_log(node, CIL_ERR, "Invalid statement within booleanif");
1935 		goto exit;
1936 	}
1937 
1938 	return SEPOL_OK;
1939 
1940 exit:
1941 	return SEPOL_ERR;
1942 }
1943 
1944 static void __cil_expr_to_string(struct cil_list *expr, enum cil_flavor flavor, char **out);
1945 
__cil_expr_to_string_helper(struct cil_list_item * curr,enum cil_flavor flavor,char ** out)1946 static void __cil_expr_to_string_helper(struct cil_list_item *curr, enum cil_flavor flavor, char **out)
1947 {
1948 	char *c;
1949 
1950 	if (curr->flavor == CIL_DATUM) {
1951 		*out = cil_strdup(DATUM(curr->data)->fqn);
1952 	} else if (curr->flavor == CIL_LIST) {
1953 		__cil_expr_to_string(curr->data, flavor, &c);
1954 		cil_asprintf(out, "(%s)", c);
1955 		free(c);
1956 	} else if (flavor == CIL_PERMISSIONX) {
1957 		// permissionx expressions aren't resolved into anything, so curr->flavor
1958 		// is just a CIL_STRING, not a CIL_DATUM, so just check on flavor for those
1959 		*out = cil_strdup(curr->data);
1960 	}
1961 }
1962 
__cil_expr_to_string(struct cil_list * expr,enum cil_flavor flavor,char ** out)1963 static void __cil_expr_to_string(struct cil_list *expr, enum cil_flavor flavor, char **out)
1964 {
1965 	struct cil_list_item *curr;
1966 	char *s1 = NULL;
1967 	char *s2 = NULL;
1968 	enum cil_flavor op;
1969 
1970 	if (expr == NULL || expr->head == NULL) {
1971 		*out = cil_strdup("");
1972 		return;
1973 	}
1974 
1975 	curr = expr->head;
1976 
1977 	if (curr->flavor == CIL_OP) {
1978 		op = (enum cil_flavor)(uintptr_t)curr->data;
1979 
1980 		if (op == CIL_ALL) {
1981 			*out = cil_strdup(CIL_KEY_ALL);
1982 		} else if (op == CIL_RANGE) {
1983 			__cil_expr_to_string_helper(curr->next, flavor, &s1);
1984 			__cil_expr_to_string_helper(curr->next->next, flavor, &s2);
1985 			cil_asprintf(out, "%s %s %s", CIL_KEY_RANGE, s1, s2);
1986 			free(s1);
1987 			free(s2);
1988 		} else {
1989 			__cil_expr_to_string_helper(curr->next, flavor, &s1);
1990 
1991 			if (op == CIL_NOT) {
1992 				cil_asprintf(out, "%s %s", CIL_KEY_NOT, s1);
1993 				free(s1);
1994 			} else {
1995 				const char *opstr = "";
1996 
1997 				__cil_expr_to_string_helper(curr->next->next, flavor, &s2);
1998 
1999 				if (op == CIL_OR) {
2000 					opstr = CIL_KEY_OR;
2001 				} else if (op == CIL_AND) {
2002 					opstr = CIL_KEY_AND;
2003 				} else if (op == CIL_XOR) {
2004 					opstr = CIL_KEY_XOR;
2005 				}
2006 
2007 				cil_asprintf(out, "%s %s %s", opstr, s1, s2);
2008 				free(s1);
2009 				free(s2);
2010 			}
2011 		}
2012 	} else {
2013 		char *c1 = NULL;
2014 		char *c2 = NULL;
2015 		__cil_expr_to_string_helper(curr, flavor, &c1);
2016 		for (curr = curr->next; curr; curr = curr->next) {
2017 			s1 = NULL;
2018 			__cil_expr_to_string_helper(curr, flavor, &s1);
2019 			cil_asprintf(&c2, "%s %s", c1, s1);
2020 			free(c1);
2021 			free(s1);
2022 			c1 = c2;
2023 		}
2024 		*out = c1;
2025 	}
2026 }
2027 
2028 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);
2029 
__cil_cond_item_to_sepol_expr(policydb_t * pdb,struct cil_list_item * item,cond_expr_t ** head,cond_expr_t ** tail)2030 static int __cil_cond_item_to_sepol_expr(policydb_t *pdb, struct cil_list_item *item, cond_expr_t **head, cond_expr_t **tail)
2031 {
2032 	if (item == NULL) {
2033 		goto exit;
2034 	} else if (item->flavor == CIL_DATUM) {
2035 		char *key = DATUM(item->data)->fqn;
2036 		cond_bool_datum_t *sepol_bool = hashtab_search(pdb->p_bools.table, key);
2037 		if (sepol_bool == NULL) {
2038 			cil_log(CIL_INFO, "Failed to find boolean\n");
2039 			goto exit;
2040 		}
2041 		*head = cil_malloc(sizeof(cond_expr_t));
2042 		(*head)->next = NULL;
2043 		(*head)->expr_type = COND_BOOL;
2044 		(*head)->bool = sepol_bool->s.value;
2045 		*tail = *head;
2046 	} else if (item->flavor == CIL_LIST) {
2047 		struct cil_list *l = item->data;
2048 		int rc = __cil_cond_expr_to_sepol_expr_helper(pdb, l, head, tail);
2049 		if (rc != SEPOL_OK) {
2050 			goto exit;
2051 		}
2052 	} else {
2053 		goto exit;
2054 	}
2055 
2056 	return SEPOL_OK;
2057 
2058 exit:
2059 	return SEPOL_ERR;
2060 }
2061 
__cil_cond_expr_to_sepol_expr_helper(policydb_t * pdb,struct cil_list * cil_expr,cond_expr_t ** head,cond_expr_t ** tail)2062 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)
2063 {
2064 	int rc = SEPOL_ERR;
2065 	struct cil_list_item *item = cil_expr->head;
2066 	enum cil_flavor flavor = cil_expr->flavor;
2067 	cond_expr_t *op, *h1, *h2, *t1, *t2;
2068 
2069 	if (flavor != CIL_BOOL) {
2070 		cil_log(CIL_INFO, "Expected boolean expression\n");
2071 		goto exit;
2072 	}
2073 
2074 	if (item == NULL) {
2075 		goto exit;
2076 	} else if (item->flavor == CIL_OP) {
2077 		enum cil_flavor cil_op = (enum cil_flavor)(uintptr_t)item->data;
2078 
2079 		op = cil_malloc(sizeof(*op));
2080 		op->bool = 0;
2081 		op->next = NULL;
2082 
2083 		switch (cil_op) {
2084 		case CIL_NOT:
2085 			op->expr_type = COND_NOT;
2086 			break;
2087 		case CIL_OR:
2088 			op->expr_type = COND_OR;
2089 			break;
2090 		case CIL_AND:
2091 			op->expr_type = COND_AND;
2092 			break;
2093 		case CIL_XOR:
2094 			op->expr_type = COND_XOR;
2095 			break;
2096 		case CIL_EQ:
2097 			op->expr_type = COND_EQ;
2098 			break;
2099 		case CIL_NEQ:
2100 			op->expr_type = COND_NEQ;
2101 			break;
2102 		default:
2103 			free(op);
2104 			goto exit;
2105 		}
2106 
2107 		rc = __cil_cond_item_to_sepol_expr(pdb, item->next, &h1, &t1);
2108 		if (rc != SEPOL_OK) {
2109 			cil_log(CIL_INFO, "Failed to get first operand of conditional expression\n");
2110 			free(op);
2111 			goto exit;
2112 		}
2113 
2114 		if (cil_op == CIL_NOT) {
2115 			*head = h1;
2116 			t1->next = op;
2117 			*tail = op;
2118 		} else {
2119 			rc = __cil_cond_item_to_sepol_expr(pdb, item->next->next, &h2, &t2);
2120 			if (rc != SEPOL_OK) {
2121 				cil_log(CIL_INFO, "Failed to get second operand of conditional expression\n");
2122 				free(op);
2123 				cond_expr_destroy(h1);
2124 				goto exit;
2125 			}
2126 
2127 			*head = h1;
2128 			t1->next = h2;
2129 			t2->next = op;
2130 			*tail = op;
2131 		}
2132 	} else {
2133 		rc = __cil_cond_item_to_sepol_expr(pdb, item, &h1, &t1);
2134 		if (rc != SEPOL_OK) {
2135 			cil_log(CIL_INFO, "Failed to get initial item in conditional list\n");
2136 			goto exit;
2137 		}
2138 		*head = h1;
2139 		for (item = item->next; item; item = item->next) {
2140 			rc = __cil_cond_item_to_sepol_expr(pdb, item, &h2, &t2);
2141 			if (rc != SEPOL_OK) {
2142 				cil_log(CIL_INFO, "Failed to get item in conditional list\n");
2143 				cond_expr_destroy(*head);
2144 				goto exit;
2145 			}
2146 			op = cil_malloc(sizeof(*op));
2147 			op->bool = 0;
2148 			op->next = NULL;
2149 			op->expr_type = COND_OR;
2150 			t1->next = h2;
2151 			t2->next = op;
2152 			t1 = op;
2153 		}
2154 		*tail = t1;
2155 	}
2156 
2157 	return SEPOL_OK;
2158 
2159 exit:
2160 	return SEPOL_ERR;
2161 }
2162 
__cil_cond_expr_to_sepol_expr(policydb_t * pdb,struct cil_list * cil_expr,cond_expr_t ** sepol_expr)2163 static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **sepol_expr)
2164 {
2165 	int rc;
2166 	cond_expr_t *head, *tail;
2167 
2168 	rc = __cil_cond_expr_to_sepol_expr_helper(pdb, cil_expr, &head, &tail);
2169 	if (rc != SEPOL_OK) {
2170 		return SEPOL_ERR;
2171 	}
2172 	*sepol_expr = head;
2173 
2174 	return SEPOL_OK;
2175 }
2176 
__cil_validate_cond_expr(cond_expr_t * cond_expr)2177 int __cil_validate_cond_expr(cond_expr_t *cond_expr)
2178 {
2179 	cond_expr_t *e;
2180 	int depth = -1;
2181 
2182 	for (e = cond_expr; e != NULL; e = e->next) {
2183 		switch (e->expr_type) {
2184 		case COND_BOOL:
2185 			if (depth == (COND_EXPR_MAXDEPTH - 1)) {
2186 				cil_log(CIL_ERR,"Conditional expression exceeded max allowable depth\n");
2187 				return SEPOL_ERR;
2188 			}
2189 			depth++;
2190 			break;
2191 		case COND_NOT:
2192 			if (depth < 0) {
2193 				cil_log(CIL_ERR,"Invalid conditional expression\n");
2194 				return SEPOL_ERR;
2195 			}
2196 			break;
2197 		case COND_OR:
2198 		case COND_AND:
2199 		case COND_XOR:
2200 		case COND_EQ:
2201 		case COND_NEQ:
2202 			if (depth < 1) {
2203 				cil_log(CIL_ERR,"Invalid conditional expression\n");
2204 				return SEPOL_ERR;
2205 			}
2206 			depth--;
2207 			break;
2208 		default:
2209 			cil_log(CIL_ERR,"Invalid conditional expression\n");
2210 			return SEPOL_ERR;
2211 		}
2212 	}
2213 
2214 	if (depth != 0) {
2215 		cil_log(CIL_ERR,"Invalid conditional expression\n");
2216 		return SEPOL_ERR;
2217 	}
2218 
2219 	return SEPOL_OK;
2220 }
2221 
cil_booleanif_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_tree_node * node)2222 int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node)
2223 {
2224 	int rc = SEPOL_ERR;
2225 	struct cil_args_booleanif bool_args;
2226 	struct cil_booleanif *cil_boolif = (struct cil_booleanif*)node->data;
2227 	struct cil_tree_node *cb_node;
2228 	struct cil_tree_node *true_node = NULL;
2229 	struct cil_tree_node *false_node = NULL;
2230 	struct cil_tree_node *tmp_node = NULL;
2231 	cond_node_t *tmp_cond = NULL;
2232 	cond_node_t *cond_node = NULL;
2233 	int was_created;
2234 	int swapped = CIL_FALSE;
2235 	cond_av_list_t tmp_cl;
2236 
2237 	tmp_cond = cond_node_create(pdb, NULL);
2238 	if (tmp_cond == NULL) {
2239 		rc = SEPOL_ERR;
2240 		cil_tree_log(node, CIL_INFO, "Failed to create sepol conditional node");
2241 		goto exit;
2242 	}
2243 
2244 	rc = __cil_cond_expr_to_sepol_expr(pdb, cil_boolif->datum_expr, &tmp_cond->expr);
2245 	if (rc != SEPOL_OK) {
2246 		cil_tree_log(node, CIL_INFO, "Failed to convert CIL conditional expression to sepol expression");
2247 		goto exit;
2248 	}
2249 
2250 	rc = __cil_validate_cond_expr(tmp_cond->expr);
2251 	if (rc != SEPOL_OK) {
2252 		goto exit;
2253 	}
2254 
2255 	tmp_cond->true_list = &tmp_cl;
2256 
2257 	rc = cond_normalize_expr(pdb, tmp_cond);
2258 	if (rc != SEPOL_OK) {
2259 		goto exit;
2260 	}
2261 
2262 	if (tmp_cond->false_list != NULL) {
2263 		tmp_cond->true_list = NULL;
2264 		swapped = CIL_TRUE;
2265 	}
2266 
2267 	cond_node = cond_node_find(pdb, tmp_cond, pdb->cond_list, &was_created);
2268 	if (cond_node == NULL) {
2269 		rc = SEPOL_ERR;
2270 		goto exit;
2271 	}
2272 
2273 	if (was_created) {
2274 		cond_node->next = pdb->cond_list;
2275 		pdb->cond_list = cond_node;
2276 	}
2277 
2278 	cond_expr_destroy(tmp_cond->expr);
2279 	free(tmp_cond);
2280 	tmp_cond = NULL;
2281 
2282 	for (cb_node = node->cl_head; cb_node != NULL; cb_node = cb_node->next) {
2283 		if (cb_node->flavor == CIL_CONDBLOCK) {
2284 			struct cil_condblock *cb = cb_node->data;
2285 			if (cb->flavor == CIL_CONDTRUE) {
2286 					true_node = cb_node;
2287 			} else if (cb->flavor == CIL_CONDFALSE) {
2288 					false_node = cb_node;
2289 			}
2290 		}
2291 	}
2292 
2293 	if (swapped) {
2294 		tmp_node = true_node;
2295 		true_node = false_node;
2296 		false_node = tmp_node;
2297 	}
2298 
2299 	bool_args.db = db;
2300 	bool_args.pdb = pdb;
2301 	bool_args.cond_node = cond_node;
2302 
2303 	if (true_node != NULL) {
2304 		bool_args.cond_flavor = CIL_CONDTRUE;
2305 		rc = cil_tree_walk(true_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args);
2306 		if (rc != SEPOL_OK) {
2307 			cil_tree_log(true_node, CIL_ERR, "Failure while walking true conditional block");
2308 			goto exit;
2309 		}
2310 	}
2311 
2312 	if (false_node != NULL) {
2313 		bool_args.cond_flavor = CIL_CONDFALSE;
2314 		rc = cil_tree_walk(false_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args);
2315 		if (rc != SEPOL_OK) {
2316 			cil_tree_log(false_node, CIL_ERR, "Failure while walking false conditional block");
2317 			goto exit;
2318 		}
2319 	}
2320 
2321 	return SEPOL_OK;
2322 
2323 exit:
2324 	if (tmp_cond) {
2325 		if (tmp_cond->expr)
2326 			cond_expr_destroy(tmp_cond->expr);
2327 		free(tmp_cond);
2328 	}
2329 	return rc;
2330 }
2331 
cil_roletrans_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_roletransition * roletrans,hashtab_t role_trans_table)2332 int cil_roletrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roletransition *roletrans, hashtab_t role_trans_table)
2333 {
2334 	int rc = SEPOL_ERR;
2335 	role_datum_t *sepol_src = NULL;
2336 	type_datum_t *sepol_tgt = NULL;
2337 	class_datum_t *sepol_obj = NULL;
2338 	struct cil_list *class_list = NULL;
2339 	role_datum_t *sepol_result = NULL;
2340 	role_trans_t *new = NULL;
2341 	uint32_t *new_role = NULL;
2342 	ebitmap_t role_bitmap, type_bitmap;
2343 	ebitmap_node_t *rnode, *tnode;
2344 	unsigned int i, j;
2345 	struct cil_list_item *c;
2346 
2347 	rc = __cil_expand_role(DATUM(roletrans->src), &role_bitmap);
2348 	if (rc != SEPOL_OK) goto exit;
2349 
2350 	rc = __cil_expand_type(roletrans->tgt, &type_bitmap);
2351 	if (rc != SEPOL_OK) goto exit;
2352 
2353 	class_list = cil_expand_class(roletrans->obj);
2354 
2355 	rc = __cil_get_sepol_role_datum(pdb, DATUM(roletrans->result), &sepol_result);
2356 	if (rc != SEPOL_OK) goto exit;
2357 
2358 	ebitmap_for_each_positive_bit(&role_bitmap, rnode, i) {
2359 		rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src);
2360 		if (rc != SEPOL_OK) goto exit;
2361 
2362 		ebitmap_for_each_positive_bit(&type_bitmap, tnode, j) {
2363 			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
2364 			if (rc != SEPOL_OK) goto exit;
2365 
2366 			cil_list_for_each(c, class_list) {
2367 				int add = CIL_TRUE;
2368 				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
2369 				if (rc != SEPOL_OK) goto exit;
2370 
2371 				new = cil_malloc(sizeof(*new));
2372 				memset(new, 0, sizeof(*new));
2373 				new->role = sepol_src->s.value;
2374 				new->type = sepol_tgt->s.value;
2375 				new->tclass = sepol_obj->s.value;
2376 				new->new_role = sepol_result->s.value;
2377 
2378 				rc = hashtab_insert(role_trans_table, (hashtab_key_t)new, &(new->new_role));
2379 				if (rc != SEPOL_OK) {
2380 					if (rc == SEPOL_EEXIST) {
2381 						add = CIL_FALSE;
2382 						new_role = hashtab_search(role_trans_table, (hashtab_key_t)new);
2383 						if (new->new_role != *new_role) {
2384 							cil_log(CIL_ERR, "Conflicting role transition rules\n");
2385 						} else {
2386 							rc = SEPOL_OK;
2387 						}
2388 					} else {
2389 						cil_log(CIL_ERR, "Out of memory\n");
2390 					}
2391 				}
2392 
2393 				if (add == CIL_TRUE) {
2394 					new->next = pdb->role_tr;
2395 					pdb->role_tr = new;
2396 				} else {
2397 					free(new);
2398 					if (rc != SEPOL_OK) {
2399 						goto exit;
2400 					}
2401 				}
2402 			}
2403 		}
2404 	}
2405 
2406 	rc = SEPOL_OK;
2407 
2408 exit:
2409 	ebitmap_destroy(&role_bitmap);
2410 	ebitmap_destroy(&type_bitmap);
2411 	cil_list_destroy(&class_list, CIL_FALSE);
2412 	return rc;
2413 }
2414 
cil_roleallow_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_roleallow * roleallow)2415 int cil_roleallow_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roleallow *roleallow)
2416 {
2417 	int rc = SEPOL_ERR;
2418 	role_datum_t *sepol_src = NULL;
2419 	role_datum_t *sepol_tgt = NULL;
2420 	role_allow_t *sepol_roleallow = NULL;
2421 	ebitmap_t src_bitmap, tgt_bitmap;
2422 	ebitmap_node_t *node1, *node2;
2423 	unsigned int i, j;
2424 
2425 	rc = __cil_expand_role(roleallow->src, &src_bitmap);
2426 	if (rc != SEPOL_OK) goto exit;
2427 
2428 	rc = __cil_expand_role(roleallow->tgt, &tgt_bitmap);
2429 	if (rc != SEPOL_OK) goto exit;
2430 
2431 	ebitmap_for_each_positive_bit(&src_bitmap, node1, i) {
2432 		rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src);
2433 		if (rc != SEPOL_OK) goto exit;
2434 
2435 		ebitmap_for_each_positive_bit(&tgt_bitmap, node2, j) {
2436 			rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[j]), &sepol_tgt);
2437 			if (rc != SEPOL_OK) goto exit;
2438 
2439 			sepol_roleallow = cil_malloc(sizeof(*sepol_roleallow));
2440 			memset(sepol_roleallow, 0, sizeof(role_allow_t));
2441 			sepol_roleallow->role = sepol_src->s.value;
2442 			sepol_roleallow->new_role = sepol_tgt->s.value;
2443 
2444 			sepol_roleallow->next = pdb->role_allow;
2445 			pdb->role_allow = sepol_roleallow;
2446 		}
2447 	}
2448 
2449 	rc = SEPOL_OK;
2450 
2451 exit:
2452 	ebitmap_destroy(&src_bitmap);
2453 	ebitmap_destroy(&tgt_bitmap);
2454 	return rc;
2455 }
2456 
__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)2457 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)
2458 {
2459 	int rc = SEPOL_ERR;
2460 
2461 	if (expr_flavor == CIL_USER) {
2462 		user_datum_t *sepol_user = NULL;
2463 		ebitmap_t user_bitmap;
2464 		ebitmap_node_t *unode;
2465 		unsigned int i;
2466 
2467 		rc = __cil_expand_user(item->data, &user_bitmap);
2468 		if (rc != SEPOL_OK) goto exit;
2469 
2470 		ebitmap_for_each_positive_bit(&user_bitmap, unode, i) {
2471 			rc = __cil_get_sepol_user_datum(pdb, DATUM(db->val_to_user[i]), &sepol_user);
2472 			if (rc != SEPOL_OK) {
2473 				ebitmap_destroy(&user_bitmap);
2474 				goto exit;
2475 			}
2476 
2477 			if (ebitmap_set_bit(&expr->names, sepol_user->s.value - 1, 1)) {
2478 				ebitmap_destroy(&user_bitmap);
2479 				goto exit;
2480 			}
2481 		}
2482 		ebitmap_destroy(&user_bitmap);
2483 	} else if (expr_flavor == CIL_ROLE) {
2484 		role_datum_t *sepol_role = NULL;
2485 		ebitmap_t role_bitmap;
2486 		ebitmap_node_t *rnode;
2487 		unsigned int i;
2488 
2489 		rc = __cil_expand_role(item->data, &role_bitmap);
2490 		if (rc != SEPOL_OK) goto exit;
2491 
2492 		ebitmap_for_each_positive_bit(&role_bitmap, rnode, i) {
2493 			rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role);
2494 			if (rc != SEPOL_OK) {
2495 				ebitmap_destroy(&role_bitmap);
2496 				goto exit;
2497 			}
2498 
2499 			if (ebitmap_set_bit(&expr->names, sepol_role->s.value - 1, 1)) {
2500 				ebitmap_destroy(&role_bitmap);
2501 				goto exit;
2502 			}
2503 		}
2504 		ebitmap_destroy(&role_bitmap);
2505 	} else if (expr_flavor == CIL_TYPE) {
2506 		type_datum_t *sepol_type = NULL;
2507 		ebitmap_t type_bitmap;
2508 		ebitmap_node_t *tnode;
2509 		unsigned int i;
2510 
2511 		if (pdb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) {
2512 			rc = __cil_get_sepol_type_datum(pdb, item->data, &sepol_type);
2513 			if (rc != SEPOL_OK) {
2514 				if (FLAVOR(item->data) == CIL_TYPEATTRIBUTE) {
2515 					struct cil_typeattribute *attr = item->data;
2516 					if (!attr->keep) {
2517 						rc = 0;
2518 					}
2519 				}
2520 			}
2521 
2522 			if (sepol_type) {
2523 				rc = ebitmap_set_bit(&expr->type_names->types, sepol_type->s.value - 1, 1);
2524 			}
2525 
2526 			if (rc != SEPOL_OK) {
2527 				goto exit;
2528 			}
2529 		}
2530 
2531 		rc = __cil_expand_type(item->data, &type_bitmap);
2532 		if (rc != SEPOL_OK) goto exit;
2533 
2534 		ebitmap_for_each_positive_bit(&type_bitmap, tnode, i) {
2535 			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type);
2536 			if (rc != SEPOL_OK) {
2537 				ebitmap_destroy(&type_bitmap);
2538 				goto exit;
2539 			}
2540 
2541 			if (ebitmap_set_bit(&expr->names, sepol_type->s.value - 1, 1)) {
2542 				ebitmap_destroy(&type_bitmap);
2543 				goto exit;
2544 			}
2545 		}
2546 		ebitmap_destroy(&type_bitmap);
2547 	} else {
2548 		goto exit;
2549 	}
2550 
2551 	return SEPOL_OK;
2552 
2553 exit:
2554 	return SEPOL_ERR;
2555 }
2556 
__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)2557 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)
2558 {
2559 	int rc = SEPOL_ERR;
2560 	struct cil_list_item *l_item = op_item->next;
2561 	struct cil_list_item *r_item = op_item->next->next;
2562 
2563 	enum cil_flavor l_operand = (enum cil_flavor)(uintptr_t)l_item->data;
2564 
2565 	switch (l_operand) {
2566 	case CIL_CONS_U1:
2567 		expr->attr = CEXPR_USER;
2568 		break;
2569 	case CIL_CONS_U2:
2570 		expr->attr = CEXPR_USER | CEXPR_TARGET;
2571 		break;
2572 	case CIL_CONS_U3:
2573 		expr->attr = CEXPR_USER | CEXPR_XTARGET;
2574 		break;
2575 	case CIL_CONS_R1:
2576 		expr->attr = CEXPR_ROLE;
2577 		break;
2578 	case CIL_CONS_R2:
2579 		expr->attr = CEXPR_ROLE | CEXPR_TARGET;
2580 		break;
2581 	case CIL_CONS_R3:
2582 		expr->attr = CEXPR_ROLE | CEXPR_XTARGET;
2583 		break;
2584 	case CIL_CONS_T1:
2585 		expr->attr = CEXPR_TYPE;
2586 		break;
2587 	case CIL_CONS_T2:
2588 		expr->attr = CEXPR_TYPE | CEXPR_TARGET;
2589 		break;
2590 	case CIL_CONS_T3:
2591 		expr->attr = CEXPR_TYPE | CEXPR_XTARGET;
2592 		break;
2593 	case CIL_CONS_L1: {
2594 		enum cil_flavor r_operand = (enum cil_flavor)(uintptr_t)r_item->data;
2595 
2596 		if (r_operand == CIL_CONS_L2) {
2597 			expr->attr = CEXPR_L1L2;
2598 		} else if (r_operand == CIL_CONS_H1) {
2599 			expr->attr = CEXPR_L1H1;
2600 		} else {
2601 			expr->attr = CEXPR_L1H2;
2602 		}
2603 		break;
2604 	}
2605 	case CIL_CONS_L2:
2606 		expr->attr = CEXPR_L2H2;
2607 		break;
2608 	case CIL_CONS_H1: {
2609 		enum cil_flavor r_operand = (enum cil_flavor)(uintptr_t)r_item->data;
2610 		if (r_operand == CIL_CONS_L2) {
2611 			expr->attr = CEXPR_H1L2;
2612 		} else {
2613 			expr->attr = CEXPR_H1H2;
2614 		}
2615 		break;
2616 	}
2617 	default:
2618 		goto exit;
2619 		break;
2620 	}
2621 
2622 	if (r_item->flavor == CIL_CONS_OPERAND) {
2623 		expr->expr_type = CEXPR_ATTR;
2624 	} else {
2625 		expr->expr_type = CEXPR_NAMES;
2626 		if (r_item->flavor == CIL_DATUM) {
2627 			rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, r_item, expr_flavor, expr);
2628 			if (rc != SEPOL_OK) {
2629 				goto exit;
2630 			}
2631 		} else if (r_item->flavor == CIL_LIST) {
2632 			struct cil_list *r_expr = r_item->data;
2633 			struct cil_list_item *curr;
2634 			cil_list_for_each(curr, r_expr) {
2635 				rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, curr, expr_flavor, expr);
2636 				if (rc != SEPOL_OK) {
2637 					goto exit;
2638 				}
2639 			}
2640 		} else {
2641 			rc = SEPOL_ERR;
2642 			goto exit;
2643 		}
2644 	}
2645 
2646 	return SEPOL_OK;
2647 
2648 exit:
2649 	return rc;
2650 }
2651 
__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)2652 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)
2653 {
2654 	int rc = SEPOL_ERR;
2655 	struct cil_list_item *item;
2656 	enum cil_flavor flavor;
2657 	enum cil_flavor cil_op;
2658 	constraint_expr_t *op, *h1, *h2, *t1, *t2;
2659 	int is_leaf = CIL_FALSE;
2660 
2661 	if (cil_expr == NULL) {
2662 		return SEPOL_ERR;
2663 	}
2664 
2665 	item = cil_expr->head;
2666 	flavor = cil_expr->flavor;
2667 
2668 	op = cil_malloc(sizeof(constraint_expr_t));
2669 	rc = constraint_expr_init(op);
2670 	if (rc != SEPOL_OK) {
2671 		goto exit;
2672 	}
2673 
2674 	cil_op = (enum cil_flavor)(uintptr_t)item->data;
2675 	switch (cil_op) {
2676 	case CIL_NOT:
2677 		op->expr_type = CEXPR_NOT;
2678 		break;
2679 	case CIL_AND:
2680 		op->expr_type = CEXPR_AND;
2681 		break;
2682 	case CIL_OR:
2683 		op->expr_type = CEXPR_OR;
2684 		break;
2685 	case CIL_EQ:
2686 		op->op = CEXPR_EQ;
2687 		is_leaf = CIL_TRUE;
2688 		break;
2689 	case CIL_NEQ:
2690 		op->op = CEXPR_NEQ;
2691 		is_leaf = CIL_TRUE;
2692 		break;
2693 	case CIL_CONS_DOM:
2694 		op->op = CEXPR_DOM;
2695 		is_leaf = CIL_TRUE;
2696 		break;
2697 	case CIL_CONS_DOMBY:
2698 		op->op = CEXPR_DOMBY;
2699 		is_leaf = CIL_TRUE;
2700 		break;
2701 	case CIL_CONS_INCOMP:
2702 		op->op = CEXPR_INCOMP;
2703 		is_leaf = CIL_TRUE;
2704 		break;
2705 	default:
2706 		goto exit;
2707 	}
2708 
2709 	if (is_leaf == CIL_TRUE) {
2710 		rc = __cil_constrain_expr_leaf_to_sepol_expr(pdb, db, item, flavor, op);
2711 		if (rc != SEPOL_OK) {
2712 			goto exit;
2713 		}
2714 		*head = op;
2715 		*tail = op;
2716 	} else if (cil_op == CIL_NOT) {
2717 		struct cil_list *l_expr = item->next->data;
2718 		rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1);
2719 		if (rc != SEPOL_OK) {
2720 			goto exit;
2721 		}
2722 		t1->next = op;
2723 		*head = h1;
2724 		*tail = op;
2725 	} else {
2726 		struct cil_list *l_expr = item->next->data;
2727 		struct cil_list *r_expr = item->next->next->data;
2728 		rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1);
2729 		if (rc != SEPOL_OK) {
2730 			goto exit;
2731 		}
2732 		rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, r_expr, &h2, &t2);
2733 		if (rc != SEPOL_OK) {
2734 			constraint_expr_destroy(h1);
2735 			goto exit;
2736 		}
2737 		t1->next = h2;
2738 		t2->next = op;
2739 		*head = h1;
2740 		*tail = op;
2741 	}
2742 
2743 	return SEPOL_OK;
2744 
2745 exit:
2746 	constraint_expr_destroy(op);
2747 	return SEPOL_ERR;
2748 }
2749 
__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)2750 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)
2751 {
2752 	int rc;
2753 	constraint_expr_t *head, *tail;
2754 
2755 	rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, cil_expr, &head, &tail);
2756 	if (rc != SEPOL_OK) {
2757 		return SEPOL_ERR;
2758 	}
2759 
2760 	*sepol_expr = head;
2761 
2762 	return SEPOL_OK;
2763 }
2764 
__cil_validate_constrain_expr(constraint_expr_t * sepol_expr)2765 int __cil_validate_constrain_expr(constraint_expr_t *sepol_expr)
2766 {
2767 	constraint_expr_t *e;
2768 	int depth = -1;
2769 
2770 	for (e = sepol_expr; e != NULL; e = e->next) {
2771 		switch (e->expr_type) {
2772 		case CEXPR_NOT:
2773 			if (depth < 0) {
2774 				cil_log(CIL_ERR,"Invalid constraint expression\n");
2775 				return SEPOL_ERR;
2776 			}
2777 			break;
2778 		case CEXPR_AND:
2779 		case CEXPR_OR:
2780 			if (depth < 1) {
2781 				cil_log(CIL_ERR,"Invalid constraint expression\n");
2782 				return SEPOL_ERR;
2783 			}
2784 			depth--;
2785 			break;
2786 		case CEXPR_ATTR:
2787 		case CEXPR_NAMES:
2788 			if (depth == (CEXPR_MAXDEPTH - 1)) {
2789 				cil_log(CIL_ERR,"Constraint expression exceeded max allowable depth\n");
2790 				return SEPOL_ERR;
2791 			}
2792 			depth++;
2793 			break;
2794 		default:
2795 			cil_log(CIL_ERR,"Invalid constraint expression\n");
2796 			return SEPOL_ERR;
2797 		}
2798 	}
2799 
2800 	if (depth != 0) {
2801 		cil_log(CIL_ERR,"Invalid constraint expression\n");
2802 		return SEPOL_ERR;
2803 	}
2804 
2805 	return SEPOL_OK;
2806 }
2807 
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)2808 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)
2809 {
2810 	int rc = SEPOL_ERR;
2811 	constraint_node_t *sepol_constrain = NULL;
2812 	constraint_expr_t *sepol_expr = NULL;
2813 	class_datum_t *sepol_class = NULL;
2814 
2815 	sepol_constrain = cil_malloc(sizeof(*sepol_constrain));
2816 	memset(sepol_constrain, 0, sizeof(constraint_node_t));
2817 
2818 	rc = __cil_get_sepol_class_datum(pdb, class, &sepol_class);
2819 	if (rc != SEPOL_OK) goto exit;
2820 
2821 	rc = __cil_perms_to_datum(perms, sepol_class, &sepol_constrain->permissions);
2822 	if (rc != SEPOL_OK) {
2823 		goto exit;
2824 	}
2825 
2826 	rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr);
2827 	if (rc != SEPOL_OK) {
2828 		goto exit;
2829 	}
2830 
2831 	rc = __cil_validate_constrain_expr(sepol_expr);
2832 	if (rc != SEPOL_OK) {
2833 		goto exit;
2834 	}
2835 
2836 	sepol_constrain->expr = sepol_expr;
2837 	sepol_constrain->next = sepol_class->constraints;
2838 	sepol_class->constraints = sepol_constrain;
2839 
2840 	return SEPOL_OK;
2841 
2842 exit:
2843 	constraint_expr_destroy(sepol_expr);
2844 	free(sepol_constrain);
2845 	return rc;
2846 }
2847 
cil_constrain_expand(policydb_t * pdb,const struct cil_db * db,struct cil_list * classperms,struct cil_list * expr)2848 int cil_constrain_expand(policydb_t *pdb, const struct cil_db *db, struct cil_list *classperms, struct cil_list *expr)
2849 {
2850 	int rc = SEPOL_ERR;
2851 	struct cil_list_item *curr;
2852 
2853 	cil_list_for_each(curr, classperms) {
2854 		if (curr->flavor == CIL_CLASSPERMS) {
2855 			struct cil_classperms *cp = curr->data;
2856 			if (FLAVOR(cp->class) == CIL_CLASS) {
2857 				rc = cil_constrain_to_policydb_helper(pdb, db, DATUM(cp->class), cp->perms, expr);
2858 				if (rc != SEPOL_OK) {
2859 					goto exit;
2860 				}
2861 			} else { /* MAP */
2862 				struct cil_list_item *i = NULL;
2863 				cil_list_for_each(i, cp->perms) {
2864 					struct cil_perm *cmp = i->data;
2865 					rc = cil_constrain_expand(pdb, db, cmp->classperms, expr);
2866 					if (rc != SEPOL_OK) {
2867 						goto exit;
2868 					}
2869 				}
2870 			}
2871 		} else { /* SET */
2872 			struct cil_classperms_set *cp_set = curr->data;
2873 			struct cil_classpermission *cp = cp_set->set;
2874 			rc = cil_constrain_expand(pdb, db, cp->classperms, expr);
2875 			if (rc != SEPOL_OK) {
2876 				goto exit;
2877 			}
2878 		}
2879 	}
2880 
2881 	return SEPOL_OK;
2882 
2883 exit:
2884 	return rc;
2885 }
2886 
cil_constrain_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_constrain * cil_constrain)2887 int cil_constrain_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_constrain *cil_constrain)
2888 {
2889 	int rc = SEPOL_ERR;
2890 	rc = cil_constrain_expand(pdb, db, cil_constrain->classperms, cil_constrain->datum_expr);
2891 	if (rc != SEPOL_OK) {
2892 		goto exit;
2893 	}
2894 
2895 	return SEPOL_OK;
2896 
2897 exit:
2898 	cil_log(CIL_ERR, "Failed to insert constraint into policydb\n");
2899 	return rc;
2900 }
2901 
cil_validatetrans_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_validatetrans * cil_validatetrans)2902 int cil_validatetrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_validatetrans *cil_validatetrans)
2903 {
2904 	int rc = SEPOL_ERR;
2905 	struct cil_list *expr = cil_validatetrans->datum_expr;
2906 	class_datum_t *sepol_class = NULL;
2907 	struct cil_list *class_list;
2908 	constraint_node_t *sepol_validatetrans = NULL;
2909 	constraint_expr_t *sepol_expr = NULL;
2910 	struct cil_list_item *c;
2911 
2912 	class_list = cil_expand_class(cil_validatetrans->class);
2913 
2914 	cil_list_for_each(c, class_list) {
2915 		rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
2916 		if (rc != SEPOL_OK) goto exit;
2917 
2918 		sepol_validatetrans = cil_malloc(sizeof(*sepol_validatetrans));
2919 		memset(sepol_validatetrans, 0, sizeof(constraint_node_t));
2920 
2921 		rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr);
2922 		if (rc != SEPOL_OK) {
2923 			free(sepol_validatetrans);
2924 			goto exit;
2925 		}
2926 		sepol_validatetrans->expr = sepol_expr;
2927 
2928 		sepol_validatetrans->next = sepol_class->validatetrans;
2929 		sepol_class->validatetrans = sepol_validatetrans;
2930 	}
2931 
2932 	rc = SEPOL_OK;
2933 
2934 exit:
2935 	cil_list_destroy(&class_list, CIL_FALSE);
2936 	return rc;
2937 }
2938 
__cil_cats_to_mls_level(policydb_t * pdb,struct cil_cats * cats,mls_level_t * mls_level)2939 int __cil_cats_to_mls_level(policydb_t *pdb, struct cil_cats *cats, mls_level_t *mls_level)
2940 {
2941 	int rc = SEPOL_ERR;
2942 	struct cil_list_item *i;
2943 	cat_datum_t *sepol_cat = NULL;
2944 
2945 	cil_list_for_each(i, cats->datum_expr) {
2946 		struct cil_tree_node *node = NODE(i->data);
2947 		if (node->flavor == CIL_CATSET) {
2948 			struct cil_list_item *j;
2949 			struct cil_catset *cs = i->data;
2950 			cil_list_for_each(j, cs->cats->datum_expr) {
2951 				rc = __cil_get_sepol_cat_datum(pdb, j->data, &sepol_cat);
2952 				if (rc != SEPOL_OK) goto exit;
2953 
2954 				rc = ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1);
2955 				if (rc != SEPOL_OK) goto exit;
2956 			}
2957 		} else {
2958 			rc = __cil_get_sepol_cat_datum(pdb, i->data, &sepol_cat);
2959 			if (rc != SEPOL_OK) goto exit;
2960 
2961 			rc = ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1);
2962 			if (rc != SEPOL_OK) goto exit;
2963 		}
2964 	}
2965 
2966 	return SEPOL_OK;
2967 
2968 exit:
2969 	return SEPOL_ERR;
2970 }
2971 
cil_sepol_level_define(policydb_t * pdb,struct cil_sens * cil_sens)2972 int cil_sepol_level_define(policydb_t *pdb, struct cil_sens *cil_sens)
2973 {
2974 	int rc = SEPOL_ERR;
2975 	struct cil_list_item *curr;
2976 	level_datum_t *sepol_level = NULL;
2977 	mls_level_t *mls_level = NULL;
2978 
2979 	rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level);
2980 	if (rc != SEPOL_OK) goto exit;
2981 
2982 	mls_level = sepol_level->level;
2983 
2984 	ebitmap_init(&mls_level->cat);
2985 
2986 	if (cil_sens->cats_list) {
2987 		cil_list_for_each(curr, cil_sens->cats_list) {
2988 			struct cil_cats *cats = curr->data;
2989 			rc = __cil_cats_to_mls_level(pdb, cats, mls_level);
2990 			if (rc != SEPOL_OK) {
2991 				cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n");
2992 				goto exit;
2993 			}
2994 		}
2995 	}
2996 
2997 	sepol_level->defined = 1;
2998 
2999 	return SEPOL_OK;
3000 
3001 exit:
3002 	return rc;
3003 }
3004 
cil_level_to_mls_level(policydb_t * pdb,struct cil_level * cil_level,mls_level_t * mls_level)3005 int cil_level_to_mls_level(policydb_t *pdb, struct cil_level *cil_level, mls_level_t *mls_level)
3006 {
3007 	int rc = SEPOL_ERR;
3008 	struct cil_sens *cil_sens = cil_level->sens;
3009 	struct cil_cats *cats = cil_level->cats;
3010 	level_datum_t *sepol_level = NULL;
3011 
3012 	rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level);
3013 	if (rc != SEPOL_OK) goto exit;
3014 
3015 	mls_level->sens = sepol_level->level->sens;
3016 
3017 	ebitmap_init(&mls_level->cat);
3018 
3019 	if (cats != NULL) {
3020 		rc = __cil_cats_to_mls_level(pdb, cats, mls_level);
3021 		if (rc != SEPOL_OK) {
3022 			cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n");
3023 			goto exit;
3024 		}
3025 	}
3026 
3027 	rc = SEPOL_OK;
3028 exit:
3029 	return rc;
3030 }
3031 
__cil_levelrange_to_mls_range(policydb_t * pdb,struct cil_levelrange * cil_lvlrange,mls_range_t * mls_range)3032 int __cil_levelrange_to_mls_range(policydb_t *pdb, struct cil_levelrange *cil_lvlrange, mls_range_t *mls_range)
3033 {
3034 	int rc = SEPOL_ERR;
3035 	struct cil_level *low = cil_lvlrange->low;
3036 	struct cil_level *high = cil_lvlrange->high;
3037 	mls_level_t *mls_level = NULL;
3038 
3039 	mls_level = &mls_range->level[0];
3040 
3041 	rc = cil_level_to_mls_level(pdb, low, mls_level);
3042 	if (rc != SEPOL_OK) {
3043 		goto exit;
3044 	}
3045 
3046 	mls_level = &mls_range->level[1];
3047 
3048 	rc = cil_level_to_mls_level(pdb, high, mls_level);
3049 	if (rc != SEPOL_OK) {
3050 		goto exit;
3051 	}
3052 
3053 	return SEPOL_OK;
3054 
3055 exit:
3056 	return rc;
3057 }
3058 
cil_userlevel_userrange_to_policydb(policydb_t * pdb,struct cil_user * cil_user)3059 int cil_userlevel_userrange_to_policydb(policydb_t *pdb, struct cil_user *cil_user)
3060 {
3061 	int rc = SEPOL_ERR;
3062 	struct cil_level *cil_level = cil_user->dftlevel;
3063 	struct cil_levelrange *cil_levelrange = cil_user->range;
3064 	user_datum_t *sepol_user = NULL;
3065 
3066 	rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user);
3067 	if (rc != SEPOL_OK) goto exit;
3068 
3069 	rc = cil_level_to_mls_level(pdb, cil_level, &sepol_user->exp_dfltlevel);
3070 	if (rc != SEPOL_OK) {
3071 		goto exit;
3072 	}
3073 
3074 	rc = __cil_levelrange_to_mls_range(pdb, cil_levelrange, &sepol_user->exp_range);
3075 	if (rc != SEPOL_OK) {
3076 		goto exit;
3077 	}
3078 
3079 	return SEPOL_OK;
3080 
3081 exit:
3082 	return rc;
3083 }
3084 
__cil_context_to_sepol_context(policydb_t * pdb,struct cil_context * cil_context,context_struct_t * sepol_context)3085 int __cil_context_to_sepol_context(policydb_t *pdb, struct cil_context *cil_context, context_struct_t *sepol_context)
3086 {
3087 	int rc = SEPOL_ERR;
3088 	struct cil_levelrange *cil_lvlrange = cil_context->range;
3089 	user_datum_t *sepol_user = NULL;
3090 	role_datum_t *sepol_role = NULL;
3091 	type_datum_t *sepol_type = NULL;
3092 
3093 	rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_context->user), &sepol_user);
3094 	if (rc != SEPOL_OK) goto exit;
3095 
3096 	rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_context->role), &sepol_role);
3097 	if (rc != SEPOL_OK) goto exit;
3098 
3099 	rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_context->type), &sepol_type);
3100 	if (rc != SEPOL_OK) goto exit;
3101 
3102 	sepol_context->user = sepol_user->s.value;
3103 	sepol_context->role = sepol_role->s.value;
3104 	sepol_context->type = sepol_type->s.value;
3105 
3106 	if (pdb->mls == CIL_TRUE) {
3107 		mls_context_init(sepol_context);
3108 
3109 		rc = __cil_levelrange_to_mls_range(pdb, cil_lvlrange, &sepol_context->range);
3110 		if (rc != SEPOL_OK) {
3111 			cil_log(CIL_ERR,"Problem with MLS\n");
3112 			mls_context_destroy(sepol_context);
3113 			goto exit;
3114 		}
3115 	}
3116 
3117 	return SEPOL_OK;
3118 
3119 exit:
3120 	return rc;
3121 }
3122 
cil_sidorder_to_policydb(policydb_t * pdb,const struct cil_db * db)3123 int cil_sidorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
3124 {
3125 	int rc = SEPOL_ERR;
3126 	struct cil_list_item *curr;
3127 	unsigned count = 0;
3128 	ocontext_t *tail = NULL;
3129 
3130 	if (db->sidorder == NULL || db->sidorder->head == NULL) {
3131 		cil_log(CIL_WARN, "No sidorder statement in policy\n");
3132 		return SEPOL_OK;
3133 	}
3134 
3135 	cil_list_for_each(curr, db->sidorder) {
3136 		struct cil_sid *cil_sid = (struct cil_sid*)curr->data;
3137 		struct cil_context *cil_context = cil_sid->context;
3138 
3139 		/* even if no context, we must preserve initial SID values */
3140 		count++;
3141 
3142 		if (cil_context != NULL) {
3143 			ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_ISID], &tail);
3144 			new_ocon->sid[0] = count;
3145 			new_ocon->u.name = cil_strdup(cil_sid->datum.fqn);
3146 			rc = __cil_context_to_sepol_context(pdb, cil_context, &new_ocon->context[0]);
3147 			if (rc != SEPOL_OK) {
3148 				cil_log(CIL_ERR,"Problem with context for SID %s\n",cil_sid->datum.fqn);
3149 				goto exit;
3150 			}
3151 		}
3152 	}
3153 
3154 	return SEPOL_OK;
3155 
3156 exit:
3157 	return rc;
3158 }
3159 
cil_rangetransition_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_rangetransition * rangetrans)3160 int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans)
3161 {
3162 	int rc = SEPOL_ERR;
3163 	type_datum_t *sepol_src = NULL;
3164 	type_datum_t *sepol_tgt = NULL;
3165 	class_datum_t *sepol_class = NULL;
3166 	struct cil_list *class_list = NULL;
3167 	range_trans_t *newkey = NULL;
3168 	struct mls_range *newdatum = NULL;
3169 	ebitmap_t src_bitmap, tgt_bitmap;
3170 	ebitmap_node_t *node1, *node2;
3171 	unsigned int i, j;
3172 	struct cil_list_item *c;
3173 	struct mls_range *o_range = NULL;
3174 
3175 	rc = __cil_expand_type(rangetrans->src, &src_bitmap);
3176 	if (rc != SEPOL_OK) goto exit;
3177 
3178 	rc = __cil_expand_type(rangetrans->exec, &tgt_bitmap);
3179 	if (rc != SEPOL_OK) goto exit;
3180 
3181 	class_list = cil_expand_class(rangetrans->obj);
3182 
3183 	ebitmap_for_each_positive_bit(&src_bitmap, node1, i) {
3184 		rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src);
3185 		if (rc != SEPOL_OK) goto exit;
3186 
3187 		ebitmap_for_each_positive_bit(&tgt_bitmap, node2, j) {
3188 			rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
3189 			if (rc != SEPOL_OK) goto exit;
3190 
3191 			cil_list_for_each(c, class_list) {
3192 				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
3193 				if (rc != SEPOL_OK) goto exit;
3194 
3195 				newkey = cil_calloc(1, sizeof(*newkey));
3196 				newdatum = cil_calloc(1, sizeof(*newdatum));
3197 				newkey->source_type = sepol_src->s.value;
3198 				newkey->target_type = sepol_tgt->s.value;
3199 				newkey->target_class = sepol_class->s.value;
3200 				rc = __cil_levelrange_to_mls_range(pdb, rangetrans->range, newdatum);
3201 				if (rc != SEPOL_OK) {
3202 					free(newkey);
3203 					free(newdatum);
3204 					goto exit;
3205 				}
3206 
3207 				rc = hashtab_insert(pdb->range_tr, (hashtab_key_t)newkey, newdatum);
3208 				if (rc != SEPOL_OK) {
3209 					if (rc == SEPOL_EEXIST) {
3210 						o_range = hashtab_search(pdb->range_tr, (hashtab_key_t)newkey);
3211 						if (!mls_range_eq(newdatum, o_range)) {
3212 							cil_log(CIL_ERR, "Conflicting Range transition rules\n");
3213 						} else {
3214 							rc = SEPOL_OK;
3215 						}
3216 					} else {
3217 						cil_log(CIL_ERR, "Out of memory\n");
3218 					}
3219 					mls_range_destroy(newdatum);
3220 					free(newdatum);
3221 					free(newkey);
3222 					if (rc != SEPOL_OK) {
3223 						goto exit;
3224 					}
3225 				}
3226 			}
3227 		}
3228 	}
3229 
3230 	rc = SEPOL_OK;
3231 
3232 exit:
3233 	ebitmap_destroy(&src_bitmap);
3234 	ebitmap_destroy(&tgt_bitmap);
3235 	cil_list_destroy(&class_list, CIL_FALSE);
3236 	return rc;
3237 }
3238 
cil_ibpkeycon_to_policydb(policydb_t * pdb,struct cil_sort * ibpkeycons)3239 int cil_ibpkeycon_to_policydb(policydb_t *pdb, struct cil_sort *ibpkeycons)
3240 {
3241 	int rc = SEPOL_ERR;
3242 	uint32_t i = 0;
3243 	ocontext_t *tail = NULL;
3244 	struct in6_addr subnet_prefix;
3245 
3246 	for (i = 0; i < ibpkeycons->count; i++) {
3247 		struct cil_ibpkeycon *cil_ibpkeycon = ibpkeycons->array[i];
3248 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_IBPKEY], &tail);
3249 
3250 		rc = inet_pton(AF_INET6, cil_ibpkeycon->subnet_prefix_str, &subnet_prefix);
3251 		if (rc != 1) {
3252 			cil_log(CIL_ERR, "ibpkeycon subnet prefix not in valid IPV6 format\n");
3253 			rc = SEPOL_ERR;
3254 			goto exit;
3255 		}
3256 
3257 		memcpy(&new_ocon->u.ibpkey.subnet_prefix, &subnet_prefix.s6_addr[0],
3258 		       sizeof(new_ocon->u.ibpkey.subnet_prefix));
3259 		new_ocon->u.ibpkey.low_pkey = cil_ibpkeycon->pkey_low;
3260 		new_ocon->u.ibpkey.high_pkey = cil_ibpkeycon->pkey_high;
3261 
3262 		rc = __cil_context_to_sepol_context(pdb, cil_ibpkeycon->context, &new_ocon->context[0]);
3263 		if (rc != SEPOL_OK)
3264 			goto exit;
3265 	}
3266 
3267 	return SEPOL_OK;
3268 
3269 exit:
3270 	return rc;
3271 }
3272 
cil_portcon_to_policydb(policydb_t * pdb,struct cil_sort * portcons)3273 int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons)
3274 {
3275 	int rc = SEPOL_ERR;
3276 	uint32_t i = 0;
3277 	ocontext_t *tail = NULL;
3278 
3279 	for (i = 0; i < portcons->count; i++) {
3280 		struct cil_portcon *cil_portcon = portcons->array[i];
3281 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_PORT], &tail);
3282 
3283 		switch (cil_portcon->proto) {
3284 		case CIL_PROTOCOL_UDP:
3285 			new_ocon->u.port.protocol = IPPROTO_UDP;
3286 			break;
3287 		case CIL_PROTOCOL_TCP:
3288 			new_ocon->u.port.protocol = IPPROTO_TCP;
3289 			break;
3290 		case CIL_PROTOCOL_DCCP:
3291 			new_ocon->u.port.protocol = IPPROTO_DCCP;
3292 			break;
3293 		case CIL_PROTOCOL_SCTP:
3294 			new_ocon->u.port.protocol = IPPROTO_SCTP;
3295 			break;
3296 		default:
3297 			/* should not get here */
3298 			rc = SEPOL_ERR;
3299 			goto exit;
3300 		}
3301 
3302 		new_ocon->u.port.low_port = cil_portcon->port_low;
3303 		new_ocon->u.port.high_port = cil_portcon->port_high;
3304 
3305 		rc = __cil_context_to_sepol_context(pdb, cil_portcon->context, &new_ocon->context[0]);
3306 		if (rc != SEPOL_OK) {
3307 			goto exit;
3308 		}
3309 	}
3310 
3311 	return SEPOL_OK;
3312 
3313 exit:
3314 	return rc;
3315 }
3316 
cil_netifcon_to_policydb(policydb_t * pdb,struct cil_sort * netifcons)3317 int cil_netifcon_to_policydb(policydb_t *pdb, struct cil_sort *netifcons)
3318 {
3319 	int rc = SEPOL_ERR;
3320 	uint32_t i = 0;
3321 	ocontext_t *tail = NULL;
3322 
3323 	for (i = 0; i < netifcons->count; i++) {
3324 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NETIF], &tail);
3325 		struct cil_netifcon *cil_netifcon = netifcons->array[i];
3326 
3327 		new_ocon->u.name = cil_strdup(cil_netifcon->interface_str);
3328 
3329 		rc = __cil_context_to_sepol_context(pdb, cil_netifcon->if_context, &new_ocon->context[0]);
3330 		if (rc != SEPOL_OK) {
3331 			goto exit;
3332 		}
3333 
3334 		rc = __cil_context_to_sepol_context(pdb, cil_netifcon->packet_context, &new_ocon->context[1]);
3335 		if (rc != SEPOL_OK) {
3336 			context_destroy(&new_ocon->context[0]);
3337 			goto exit;
3338 		}
3339 	}
3340 
3341 	return SEPOL_OK;
3342 
3343 exit:
3344 	return rc;
3345 }
3346 
cil_ibendportcon_to_policydb(policydb_t * pdb,struct cil_sort * ibendportcons)3347 int cil_ibendportcon_to_policydb(policydb_t *pdb, struct cil_sort *ibendportcons)
3348 {
3349 	int rc = SEPOL_ERR;
3350 	uint32_t i;
3351 	ocontext_t *tail = NULL;
3352 
3353 	for (i = 0; i < ibendportcons->count; i++) {
3354 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_IBENDPORT], &tail);
3355 		struct cil_ibendportcon *cil_ibendportcon = ibendportcons->array[i];
3356 
3357 		new_ocon->u.ibendport.dev_name = cil_strdup(cil_ibendportcon->dev_name_str);
3358 		new_ocon->u.ibendport.port = cil_ibendportcon->port;
3359 
3360 		rc = __cil_context_to_sepol_context(pdb, cil_ibendportcon->context, &new_ocon->context[0]);
3361 		if (rc != SEPOL_OK)
3362 			goto exit;
3363 	}
3364 
3365 	return SEPOL_OK;
3366 
3367 exit:
3368 	return rc;
3369 }
3370 
cil_nodecon_to_policydb(policydb_t * pdb,struct cil_sort * nodecons)3371 int cil_nodecon_to_policydb(policydb_t *pdb, struct cil_sort *nodecons)
3372 {
3373 	int rc = SEPOL_ERR;
3374 	uint32_t i = 0;
3375 	ocontext_t *tail = NULL;
3376 	ocontext_t *tail6 = NULL;
3377 
3378 	for (i = 0; i < nodecons->count; i++) {
3379 		ocontext_t *new_ocon = NULL;
3380 		struct cil_nodecon *cil_nodecon = nodecons->array[i];
3381 
3382 		if (cil_nodecon->addr->family == AF_INET) {
3383 			new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE], &tail);
3384 			new_ocon->u.node.addr = cil_nodecon->addr->ip.v4.s_addr;
3385 			new_ocon->u.node.mask = cil_nodecon->mask->ip.v4.s_addr;
3386 		} else if (cil_nodecon->addr->family == AF_INET6) {
3387 			new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE6], &tail6);
3388 			memcpy(new_ocon->u.node6.addr, &cil_nodecon->addr->ip.v6.s6_addr[0], 16);
3389 			memcpy(new_ocon->u.node6.mask, &cil_nodecon->mask->ip.v6.s6_addr[0], 16);
3390 		} else {
3391 			/* should not get here */
3392 			rc = SEPOL_ERR;
3393 			goto exit;
3394 		}
3395 
3396 		rc = __cil_context_to_sepol_context(pdb, cil_nodecon->context, &new_ocon->context[0]);
3397 		if (rc != SEPOL_OK) {
3398 			goto exit;
3399 		}
3400 	}
3401 
3402 	return SEPOL_OK;
3403 
3404 exit:
3405 	return rc;
3406 }
3407 
cil_fsuse_to_policydb(policydb_t * pdb,struct cil_sort * fsuses)3408 int cil_fsuse_to_policydb(policydb_t *pdb, struct cil_sort *fsuses)
3409 {
3410 	int rc = SEPOL_ERR;
3411 	uint32_t i = 0;
3412 	ocontext_t *tail = NULL;
3413 
3414 	for (i = 0; i < fsuses->count; i++) {
3415 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_FSUSE], &tail);
3416 		struct cil_fsuse *cil_fsuse = fsuses->array[i];
3417 
3418 		new_ocon->u.name = cil_strdup(cil_fsuse->fs_str);
3419 		new_ocon->v.behavior = cil_fsuse->type;
3420 
3421 		rc = __cil_context_to_sepol_context(pdb, cil_fsuse->context, &new_ocon->context[0]);
3422 		if (rc != SEPOL_OK) {
3423 			goto exit;
3424 		}
3425 	}
3426 
3427 	return SEPOL_OK;
3428 
3429 exit:
3430 	return rc;
3431 }
3432 
cil_genfscon_to_policydb(policydb_t * pdb,struct cil_sort * genfscons)3433 int cil_genfscon_to_policydb(policydb_t *pdb, struct cil_sort *genfscons)
3434 {
3435 	int rc = SEPOL_ERR;
3436 	uint32_t i = 0;
3437 	genfs_t *genfs_tail = NULL;
3438 	ocontext_t *ocon_tail = NULL;
3439 
3440 	for (i = 0; i < genfscons->count; i++) {
3441 		struct cil_genfscon *cil_genfscon = genfscons->array[i];
3442 		ocontext_t *new_ocon = cil_malloc(sizeof(ocontext_t));
3443 		memset(new_ocon, 0, sizeof(ocontext_t));
3444 
3445 		if (genfs_tail && strcmp(genfs_tail->fstype, cil_genfscon->fs_str) == 0) {
3446 			ocon_tail->next = new_ocon;
3447 		} else {
3448 			genfs_t *new_genfs = cil_malloc(sizeof(genfs_t));
3449 			memset(new_genfs, 0, sizeof(genfs_t));
3450 			new_genfs->fstype = cil_strdup(cil_genfscon->fs_str);
3451 			new_genfs->head = new_ocon;
3452 
3453 			if (genfs_tail) {
3454 				genfs_tail->next = new_genfs;
3455 			} else {
3456 				pdb->genfs = new_genfs;
3457 			}
3458 			genfs_tail = new_genfs;
3459 		}
3460 
3461 		ocon_tail = new_ocon;
3462 
3463 		new_ocon->u.name = cil_strdup(cil_genfscon->path_str);
3464 
3465 		rc = __cil_context_to_sepol_context(pdb, cil_genfscon->context, &new_ocon->context[0]);
3466 		if (rc != SEPOL_OK) {
3467 			goto exit;
3468 		}
3469 	}
3470 
3471 	return SEPOL_OK;
3472 
3473 exit:
3474 	return rc;
3475 }
3476 
cil_pirqcon_to_policydb(policydb_t * pdb,struct cil_sort * pirqcons)3477 int cil_pirqcon_to_policydb(policydb_t *pdb, struct cil_sort *pirqcons)
3478 {
3479 	int rc = SEPOL_ERR;
3480 	uint32_t i = 0;
3481 	ocontext_t *tail = NULL;
3482 
3483 	for (i = 0; i < pirqcons->count; i++) {
3484 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PIRQ], &tail);
3485 		struct cil_pirqcon *cil_pirqcon = pirqcons->array[i];
3486 
3487 		new_ocon->u.pirq = cil_pirqcon->pirq;
3488 
3489 		rc = __cil_context_to_sepol_context(pdb, cil_pirqcon->context, &new_ocon->context[0]);
3490 		if (rc != SEPOL_OK) {
3491 			goto exit;
3492 		}
3493 	}
3494 
3495 	return SEPOL_OK;
3496 
3497 exit:
3498 	return rc;
3499 }
3500 
cil_iomemcon_to_policydb(policydb_t * pdb,struct cil_sort * iomemcons)3501 int cil_iomemcon_to_policydb(policydb_t *pdb, struct cil_sort *iomemcons)
3502 {
3503 	int rc = SEPOL_ERR;
3504 	uint32_t i = 0;
3505 	ocontext_t *tail = NULL;
3506 
3507 	for (i = 0; i < iomemcons->count; i++) {
3508 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOMEM], &tail);
3509 		struct cil_iomemcon *cil_iomemcon = iomemcons->array[i];
3510 
3511 		new_ocon->u.iomem.low_iomem = cil_iomemcon->iomem_low;
3512 		new_ocon->u.iomem.high_iomem = cil_iomemcon->iomem_high;
3513 
3514 		rc = __cil_context_to_sepol_context(pdb, cil_iomemcon->context, &new_ocon->context[0]);
3515 		if (rc != SEPOL_OK) {
3516 			goto exit;
3517 		}
3518 	}
3519 
3520 	return SEPOL_OK;
3521 
3522 exit:
3523 	return rc;
3524 }
3525 
cil_ioportcon_to_policydb(policydb_t * pdb,struct cil_sort * ioportcons)3526 int cil_ioportcon_to_policydb(policydb_t *pdb, struct cil_sort *ioportcons)
3527 {
3528 	int rc = SEPOL_ERR;
3529 	uint32_t i = 0;
3530 	ocontext_t *tail = NULL;
3531 
3532 	for (i = 0; i < ioportcons->count; i++) {
3533 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOPORT], &tail);
3534 		struct cil_ioportcon *cil_ioportcon = ioportcons->array[i];
3535 
3536 		new_ocon->u.ioport.low_ioport = cil_ioportcon->ioport_low;
3537 		new_ocon->u.ioport.high_ioport = cil_ioportcon->ioport_high;
3538 
3539 		rc = __cil_context_to_sepol_context(pdb, cil_ioportcon->context, &new_ocon->context[0]);
3540 		if (rc != SEPOL_OK) {
3541 			goto exit;
3542 		}
3543 	}
3544 
3545 	return SEPOL_OK;
3546 
3547 exit:
3548 	return rc;
3549 }
3550 
cil_pcidevicecon_to_policydb(policydb_t * pdb,struct cil_sort * pcidevicecons)3551 int cil_pcidevicecon_to_policydb(policydb_t *pdb, struct cil_sort *pcidevicecons)
3552 {
3553 	int rc = SEPOL_ERR;
3554 	uint32_t i = 0;
3555 	ocontext_t *tail = NULL;
3556 
3557 	for (i = 0; i < pcidevicecons->count; i++) {
3558 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PCIDEVICE], &tail);
3559 		struct cil_pcidevicecon *cil_pcidevicecon = pcidevicecons->array[i];
3560 
3561 		new_ocon->u.device = cil_pcidevicecon->dev;
3562 
3563 		rc = __cil_context_to_sepol_context(pdb, cil_pcidevicecon->context, &new_ocon->context[0]);
3564 		if (rc != SEPOL_OK) {
3565 			goto exit;
3566 		}
3567 	}
3568 
3569 	return SEPOL_OK;
3570 
3571 exit:
3572 	return rc;
3573 }
3574 
cil_devicetreecon_to_policydb(policydb_t * pdb,struct cil_sort * devicetreecons)3575 int cil_devicetreecon_to_policydb(policydb_t *pdb, struct cil_sort *devicetreecons)
3576 {
3577 	int rc = SEPOL_ERR;
3578 	uint32_t i = 0;
3579 	ocontext_t *tail = NULL;
3580 
3581 	for (i = 0; i < devicetreecons->count; i++) {
3582 		ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_DEVICETREE], &tail);
3583 		struct cil_devicetreecon *cil_devicetreecon = devicetreecons->array[i];
3584 
3585 		new_ocon->u.name = cil_strdup(cil_devicetreecon->path);
3586 
3587 		rc = __cil_context_to_sepol_context(pdb, cil_devicetreecon->context, &new_ocon->context[0]);
3588 		if (rc != SEPOL_OK) {
3589 			goto exit;
3590 		}
3591 	}
3592 
3593 	return SEPOL_OK;
3594 
3595 exit:
3596 	return rc;
3597 }
3598 
cil_default_to_policydb(policydb_t * pdb,struct cil_default * def)3599 int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def)
3600 {
3601 	struct cil_list_item *curr;
3602 	class_datum_t *sepol_class;
3603 	struct cil_list *class_list = NULL;
3604 
3605 	cil_list_for_each(curr, def->class_datums) {
3606 		struct cil_list_item *c;
3607 
3608 		class_list = cil_expand_class(curr->data);
3609 
3610 		cil_list_for_each(c, class_list) {
3611 			int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
3612 			if (rc != SEPOL_OK) goto exit;
3613 
3614 			switch (def->flavor) {
3615 			case CIL_DEFAULTUSER:
3616 				if (!sepol_class->default_user) {
3617 					sepol_class->default_user = def->object;
3618 				} else if (sepol_class->default_user != (char)def->object) {
3619 					cil_log(CIL_ERR,"User default labeling for class %s already specified\n",DATUM(c->data)->fqn);
3620 					goto exit;
3621 				}
3622 				break;
3623 			case CIL_DEFAULTROLE:
3624 				if (!sepol_class->default_role) {
3625 					sepol_class->default_role = def->object;
3626 				} else if (sepol_class->default_role != (char)def->object) {
3627 					cil_log(CIL_ERR,"Role default labeling for class %s already specified\n",DATUM(c->data)->fqn);
3628 					goto exit;
3629 				}
3630 				break;
3631 			case CIL_DEFAULTTYPE:
3632 				if (!sepol_class->default_type) {
3633 					sepol_class->default_type = def->object;
3634 				} else if (sepol_class->default_type != (char)def->object) {
3635 					cil_log(CIL_ERR,"Type default labeling for class %s already specified\n",DATUM(c->data)->fqn);
3636 					goto exit;
3637 				}
3638 				break;
3639 			default:
3640 				goto exit;
3641 			}
3642 		}
3643 
3644 		cil_list_destroy(&class_list, CIL_FALSE);
3645 	}
3646 
3647 	return SEPOL_OK;
3648 
3649 exit:
3650 	cil_list_destroy(&class_list, CIL_FALSE);
3651 	return SEPOL_ERR;
3652 }
3653 
cil_defaultrange_to_policydb(policydb_t * pdb,struct cil_defaultrange * def)3654 int cil_defaultrange_to_policydb(policydb_t *pdb, struct cil_defaultrange *def)
3655 {
3656 	struct cil_list_item *curr;
3657 	class_datum_t *sepol_class;
3658 	struct cil_list *class_list = NULL;
3659 
3660 	cil_list_for_each(curr, def->class_datums) {
3661 		struct cil_list_item *c;
3662 
3663 		class_list = cil_expand_class(curr->data);
3664 
3665 		cil_list_for_each(c, class_list) {
3666 			int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
3667 			if (rc != SEPOL_OK) goto exit;
3668 
3669 			if (!sepol_class->default_range) {
3670 				sepol_class->default_range = def->object_range;
3671 			} else if (sepol_class->default_range != (char)def->object_range) {
3672 				cil_log(CIL_ERR,"Range default labeling for class %s already specified\n", DATUM(curr->data)->fqn);
3673 				goto exit;
3674 			}
3675 		}
3676 
3677 		cil_list_destroy(&class_list, CIL_FALSE);
3678 	}
3679 
3680 	return SEPOL_OK;
3681 
3682 exit:
3683 	cil_list_destroy(&class_list, CIL_FALSE);
3684 	return SEPOL_ERR;
3685 }
3686 
__cil_node_to_policydb(struct cil_tree_node * node,void * extra_args)3687 int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
3688 {
3689 	int rc = SEPOL_OK;
3690 	int pass;
3691 	struct cil_args_binary *args = extra_args;
3692 	const struct cil_db *db;
3693 	policydb_t *pdb;
3694 	hashtab_t role_trans_table;
3695 	void **type_value_to_cil;
3696 
3697 	db = args->db;
3698 	pdb = args->pdb;
3699 	pass = args->pass;
3700 	role_trans_table = args->role_trans_table;
3701 	type_value_to_cil = args->type_value_to_cil;
3702 
3703 	if (node->flavor >= CIL_MIN_DECLARATIVE) {
3704 		if (node != NODE(node->data)) {
3705 			goto exit;
3706 		}
3707 	}
3708 
3709 	switch (pass) {
3710 	case 1:
3711 		switch (node->flavor) {
3712 		case CIL_ROLE:
3713 			rc = cil_role_to_policydb(pdb, node->data);
3714 			break;
3715 		case CIL_TYPE:
3716 			rc = cil_type_to_policydb(pdb, node->data, type_value_to_cil);
3717 			break;
3718 		case CIL_TYPEATTRIBUTE:
3719 			rc = cil_typeattribute_to_policydb(pdb, node->data, type_value_to_cil);
3720 			break;
3721 		case CIL_POLICYCAP:
3722 			rc = cil_policycap_to_policydb(pdb, node->data);
3723 			break;
3724 		case CIL_USER:
3725 			rc = cil_user_to_policydb(pdb, node->data);
3726 			break;
3727 		case CIL_BOOL:
3728 			rc = cil_bool_to_policydb(pdb, node->data);
3729 			break;
3730 		case CIL_CATALIAS:
3731 			if (pdb->mls == CIL_TRUE) {
3732 				rc = cil_catalias_to_policydb(pdb, node->data);
3733 			}
3734 			break;
3735 		case CIL_SENS:
3736 			if (pdb->mls == CIL_TRUE) {
3737 				rc = cil_sepol_level_define(pdb, node->data);
3738 			}
3739 			break;
3740 		default:
3741 			break;
3742 		}
3743 		break;
3744 	case 2:
3745 		switch (node->flavor) {
3746 		case CIL_TYPE:
3747 			rc = cil_type_bounds_to_policydb(pdb, node->data);
3748 			break;
3749 		case CIL_TYPEALIAS:
3750 			rc = cil_typealias_to_policydb(pdb, node->data);
3751 			break;
3752 		case CIL_TYPEPERMISSIVE:
3753 			rc = cil_typepermissive_to_policydb(pdb, node->data);
3754 			break;
3755 		case CIL_TYPEATTRIBUTE:
3756 			rc = cil_typeattribute_to_bitmap(pdb, db, node->data);
3757 			break;
3758 		case CIL_SENSALIAS:
3759 			if (pdb->mls == CIL_TRUE) {
3760 				rc = cil_sensalias_to_policydb(pdb, node->data);
3761 			}
3762 			break;
3763 		case CIL_ROLE:
3764 			rc = cil_role_bounds_to_policydb(pdb, node->data);
3765 			if (rc != SEPOL_OK) goto exit;
3766 			rc = cil_roletype_to_policydb(pdb, db, node->data);
3767 			break;
3768 		case CIL_USER:
3769 			rc = cil_user_bounds_to_policydb(pdb, node->data);
3770 			if (rc != SEPOL_OK) goto exit;
3771 			if (pdb->mls == CIL_TRUE) {
3772 				rc = cil_userlevel_userrange_to_policydb(pdb, node->data);
3773 				if (rc != SEPOL_OK) {
3774 					goto exit;
3775 				}
3776 			}
3777 			rc = cil_userrole_to_policydb(pdb, db, node->data);
3778 			break;
3779 		case CIL_TYPE_RULE:
3780 			rc = cil_type_rule_to_policydb(pdb, db, node->data);
3781 			break;
3782 		case CIL_AVRULE:
3783 		case CIL_AVRULEX: {
3784 			struct cil_avrule *rule = node->data;
3785 			if (db->disable_neverallow != CIL_TRUE && rule->rule_kind == CIL_AVRULE_NEVERALLOW) {
3786 				struct cil_list *neverallows = args->neverallows;
3787 				cil_list_prepend(neverallows, CIL_LIST_ITEM, node);
3788 			}
3789 			break;
3790 		}
3791 		case CIL_ROLETRANSITION:
3792 			rc = cil_roletrans_to_policydb(pdb, db, node->data, role_trans_table);
3793 			break;
3794 		case CIL_ROLEATTRIBUTESET:
3795 		  /*rc = cil_roleattributeset_to_policydb(pdb, node->data);*/
3796 			break;
3797 		case CIL_NAMETYPETRANSITION:
3798 			rc = cil_typetransition_to_policydb(pdb, db, node->data);
3799 			break;
3800 		case CIL_CONSTRAIN:
3801 			rc = cil_constrain_to_policydb(pdb, db, node->data);
3802 			break;
3803 		case CIL_MLSCONSTRAIN:
3804 			if (pdb->mls == CIL_TRUE) {
3805 				rc = cil_constrain_to_policydb(pdb, db, node->data);
3806 			}
3807 			break;
3808 		case CIL_VALIDATETRANS:
3809 			rc = cil_validatetrans_to_policydb(pdb, db, node->data);
3810 			break;
3811 		case CIL_MLSVALIDATETRANS:
3812 			if (pdb->mls == CIL_TRUE) {
3813 				rc = cil_validatetrans_to_policydb(pdb, db, node->data);
3814 			}
3815 			break;
3816 		case CIL_RANGETRANSITION:
3817 			if (pdb->mls == CIL_TRUE) {
3818 				rc = cil_rangetransition_to_policydb(pdb, db, node->data);
3819 			}
3820 			break;
3821 		case CIL_DEFAULTUSER:
3822 		case CIL_DEFAULTROLE:
3823 		case CIL_DEFAULTTYPE:
3824 			rc = cil_default_to_policydb(pdb, node->data);
3825 			break;
3826 		case CIL_DEFAULTRANGE:
3827 			rc = cil_defaultrange_to_policydb(pdb, node->data);
3828 			break;
3829 		default:
3830 			break;
3831 		}
3832 		break;
3833 	case 3:
3834 		switch (node->flavor) {
3835 		case CIL_BOOLEANIF:
3836 			rc = cil_booleanif_to_policydb(pdb, db, node);
3837 			break;
3838 		case CIL_AVRULE: {
3839 				struct cil_avrule *rule = node->data;
3840 				if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) {
3841 					rc = cil_avrule_to_policydb(pdb, db, node->data);
3842 				}
3843 			}
3844 			break;
3845 		case CIL_AVRULEX: {
3846 				struct cil_avrule *rule = node->data;
3847 				if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) {
3848 					rc = cil_avrulex_to_hashtable(pdb, db, node->data, args);
3849 				}
3850 			}
3851 			break;
3852 		case CIL_ROLEALLOW:
3853 			rc = cil_roleallow_to_policydb(pdb, db, node->data);
3854 			break;
3855 		default:
3856 			break;
3857 		}
3858 	default:
3859 		break;
3860 	}
3861 
3862 exit:
3863 	if (rc != SEPOL_OK) {
3864 		cil_tree_log(node, CIL_ERR, "Binary policy creation failed");
3865 	}
3866 	return rc;
3867 }
3868 
__cil_binary_create_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)3869 int __cil_binary_create_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
3870 {
3871 	int rc = SEPOL_ERR;
3872 
3873 	if (node->flavor == CIL_BLOCK) {
3874 		struct cil_block *blk = node->data;
3875 		if (blk->is_abstract == CIL_TRUE) {
3876 			*finished = CIL_TREE_SKIP_HEAD;
3877 			rc = SEPOL_OK;
3878 			goto exit;
3879 		}
3880 	} else if (node->flavor == CIL_MACRO) {
3881 		*finished = CIL_TREE_SKIP_HEAD;
3882 		rc = SEPOL_OK;
3883 		goto exit;
3884 	} else if (node->flavor == CIL_BOOLEANIF) {
3885 		*finished = CIL_TREE_SKIP_HEAD;
3886 	}
3887 
3888 	rc = __cil_node_to_policydb(node, extra_args);
3889 	if (rc != SEPOL_OK) {
3890 		goto exit;
3891 	}
3892 
3893 exit:
3894 	return rc;
3895 }
3896 
__cil_contexts_to_policydb(policydb_t * pdb,const struct cil_db * db)3897 int __cil_contexts_to_policydb(policydb_t *pdb, const struct cil_db *db)
3898 {
3899 	int rc = SEPOL_ERR;
3900 
3901 	rc = cil_portcon_to_policydb(pdb, db->portcon);
3902 	if (rc != SEPOL_OK) {
3903 		goto exit;
3904 	}
3905 
3906 	rc = cil_netifcon_to_policydb(pdb, db->netifcon);
3907 	if (rc != SEPOL_OK) {
3908 		goto exit;
3909 	}
3910 
3911 	rc = cil_nodecon_to_policydb(pdb, db->nodecon);
3912 	if (rc != SEPOL_OK) {
3913 		goto exit;
3914 	}
3915 
3916 	rc = cil_fsuse_to_policydb(pdb, db->fsuse);
3917 	if (rc != SEPOL_OK) {
3918 		goto exit;
3919 	}
3920 
3921 	rc = cil_genfscon_to_policydb(pdb, db->genfscon);
3922 	if (rc != SEPOL_OK) {
3923 		goto exit;
3924 	}
3925 
3926 	rc = cil_ibpkeycon_to_policydb(pdb, db->ibpkeycon);
3927 	if (rc != SEPOL_OK) {
3928 		goto exit;
3929 	}
3930 
3931 	rc = cil_ibendportcon_to_policydb(pdb, db->ibendportcon);
3932 	if (rc != SEPOL_OK) {
3933 		goto exit;
3934 	}
3935 
3936 	if (db->target_platform == SEPOL_TARGET_XEN) {
3937 		rc = cil_pirqcon_to_policydb(pdb, db->pirqcon);
3938 		if (rc != SEPOL_OK) {
3939 			goto exit;
3940 		}
3941 
3942 		rc = cil_iomemcon_to_policydb(pdb, db->iomemcon);
3943 		if (rc != SEPOL_OK) {
3944 			goto exit;
3945 		}
3946 
3947 		rc = cil_ioportcon_to_policydb(pdb, db->ioportcon);
3948 		if (rc != SEPOL_OK) {
3949 			goto exit;
3950 		}
3951 
3952 		rc = cil_pcidevicecon_to_policydb(pdb, db->pcidevicecon);
3953 		if (rc != SEPOL_OK) {
3954 			goto exit;
3955 		}
3956 
3957 		rc = cil_devicetreecon_to_policydb(pdb, db->devicetreecon);
3958 		if (rc != SEPOL_OK) {
3959 			goto exit;
3960 		}
3961 	}
3962 	return SEPOL_OK;
3963 exit:
3964 	return rc;
3965 }
3966 
__cil_common_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3967 int __cil_common_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3968 {
3969 	policydb_t *pdb = data;
3970 	common_datum_t *common = (common_datum_t *)datum;
3971 
3972 	if (common->s.value < 1 || common->s.value > pdb->p_commons.nprim) {
3973 		return -EINVAL;
3974 	}
3975 	pdb->p_common_val_to_name[common->s.value - 1] = (char *)key;
3976 
3977 	return 0;
3978 }
3979 
__cil_class_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3980 int __cil_class_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3981 {
3982 	policydb_t *pdb = data;
3983 	class_datum_t *class = (class_datum_t *)datum;
3984 
3985 	if (class->s.value < 1 || class->s.value > pdb->p_classes.nprim) {
3986 		return -EINVAL;
3987 	}
3988 	pdb->p_class_val_to_name[class->s.value - 1] = (char *)key;
3989 	pdb->class_val_to_struct[class->s.value - 1] = class;
3990 
3991 	return 0;
3992 }
3993 
__cil_role_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3994 int __cil_role_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3995 {
3996 	policydb_t *pdb = data;
3997 	role_datum_t *role = (role_datum_t *)datum;
3998 
3999 	if (role->s.value < 1 || role->s.value > pdb->p_roles.nprim) {
4000 		return -EINVAL;
4001 	}
4002 	pdb->p_role_val_to_name[role->s.value - 1] = (char *)key;
4003 	pdb->role_val_to_struct[role->s.value - 1] = role;
4004 
4005 	return 0;
4006 }
4007 
__cil_type_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)4008 int __cil_type_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
4009 {
4010 	policydb_t *pdb = data;
4011 	type_datum_t *type = (type_datum_t *)datum;
4012 
4013 	if (type->s.value < 1 || type->s.value > pdb->p_types.nprim) {
4014 		return -EINVAL;
4015 	}
4016 	pdb->p_type_val_to_name[type->s.value - 1] = (char *)key;
4017 	pdb->type_val_to_struct[type->s.value - 1] = type;
4018 
4019 	return 0;
4020 }
4021 
__cil_user_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)4022 int __cil_user_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
4023 {
4024 	policydb_t *pdb = data;
4025 	user_datum_t *user = (user_datum_t *)datum;
4026 
4027 	if (user->s.value < 1 || user->s.value > pdb->p_users.nprim) {
4028 		return -EINVAL;
4029 	}
4030 	pdb->p_user_val_to_name[user->s.value - 1] = (char *)key;
4031 	pdb->user_val_to_struct[user->s.value - 1] = user;
4032 
4033 	return 0;
4034 }
4035 
__cil_bool_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)4036 int __cil_bool_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
4037 {
4038 	policydb_t *pdb = data;
4039 	cond_bool_datum_t *bool = (cond_bool_datum_t *)datum;
4040 
4041 	if (bool->s.value < 1 || bool->s.value > pdb->p_bools.nprim) {
4042 		return -EINVAL;
4043 	}
4044 	pdb->p_bool_val_to_name[bool->s.value - 1] = (char *)key;
4045 	pdb->bool_val_to_struct[bool->s.value - 1] = bool;
4046 
4047 	return 0;
4048 }
4049 
__cil_level_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)4050 int __cil_level_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
4051 {
4052 	policydb_t *pdb = data;
4053 	level_datum_t *level = (level_datum_t *)datum;
4054 
4055 	if (level->level->sens < 1 || level->level->sens > pdb->p_levels.nprim) {
4056 		return -EINVAL;
4057 	}
4058 	pdb->p_sens_val_to_name[level->level->sens - 1] = (char *)key;
4059 
4060 	return 0;
4061 }
4062 
__cil_cat_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)4063 int __cil_cat_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
4064 {
4065 	policydb_t *pdb = data;
4066 	cat_datum_t *cat = (cat_datum_t *)datum;
4067 
4068 	if (cat->s.value < 1 || cat->s.value > pdb->p_cats.nprim) {
4069 		return -EINVAL;
4070 	}
4071 	pdb->p_cat_val_to_name[cat->s.value - 1] = (char *)key;
4072 
4073 	return 0;
4074 }
4075 
__cil_policydb_val_arrays_create(policydb_t * policydb)4076 int __cil_policydb_val_arrays_create(policydb_t *policydb)
4077 {
4078 	int rc = SEPOL_ERR;
4079 
4080 	policydb->p_common_val_to_name = cil_malloc(sizeof(char *) * policydb->p_commons.nprim);
4081 	rc = hashtab_map(policydb->p_commons.table, &__cil_common_val_array_insert, policydb);
4082 	if (rc != SEPOL_OK) {
4083 		goto exit;
4084 	}
4085 
4086 	policydb->p_class_val_to_name = cil_malloc(sizeof(char *) * policydb->p_classes.nprim);
4087 	policydb->class_val_to_struct = cil_malloc(sizeof(class_datum_t *) * policydb->p_classes.nprim);
4088 	rc = hashtab_map(policydb->p_classes.table, &__cil_class_val_array_insert, policydb);
4089 	if (rc != SEPOL_OK) {
4090 		goto exit;
4091 	}
4092 
4093 	policydb->p_role_val_to_name = cil_malloc(sizeof(char *) * policydb->p_roles.nprim);
4094 	policydb->role_val_to_struct = cil_malloc(sizeof(role_datum_t *) * policydb->p_roles.nprim);
4095 	rc = hashtab_map(policydb->p_roles.table, &__cil_role_val_array_insert, policydb);
4096 	if (rc != SEPOL_OK) {
4097 		goto exit;
4098 	}
4099 
4100 	policydb->p_type_val_to_name = cil_malloc(sizeof(char *) * policydb->p_types.nprim);
4101 	policydb->type_val_to_struct = cil_malloc(sizeof(type_datum_t *) * policydb->p_types.nprim);
4102 	rc = hashtab_map(policydb->p_types.table, &__cil_type_val_array_insert, policydb);
4103 	if (rc != SEPOL_OK) {
4104 		goto exit;
4105 	}
4106 
4107 	policydb->p_user_val_to_name = cil_malloc(sizeof(char *) * policydb->p_users.nprim);
4108 	policydb->user_val_to_struct = cil_malloc(sizeof(user_datum_t *) * policydb->p_users.nprim);
4109 	rc = hashtab_map(policydb->p_users.table, &__cil_user_val_array_insert, policydb);
4110 	if (rc != SEPOL_OK) {
4111 		goto exit;
4112 	}
4113 
4114 	policydb->p_bool_val_to_name = cil_malloc(sizeof(char *) * policydb->p_bools.nprim);
4115 	policydb->bool_val_to_struct = cil_malloc(sizeof(cond_bool_datum_t *) * policydb->p_bools.nprim);
4116 	rc = hashtab_map(policydb->p_bools.table, &__cil_bool_val_array_insert, policydb);
4117 	if (rc != SEPOL_OK) {
4118 		goto exit;
4119 	}
4120 
4121 	policydb->p_sens_val_to_name = cil_malloc(sizeof(char *) * policydb->p_levels.nprim);
4122 	rc = hashtab_map(policydb->p_levels.table, &__cil_level_val_array_insert, policydb);
4123 	if (rc != SEPOL_OK) {
4124 		goto exit;
4125 	}
4126 
4127 	policydb->p_cat_val_to_name = cil_malloc(sizeof(char *) * policydb->p_cats.nprim);
4128 	rc = hashtab_map(policydb->p_cats.table, &__cil_cat_val_array_insert, policydb);
4129 	if (rc != SEPOL_OK) {
4130 		goto exit;
4131 	}
4132 
4133 exit:
4134 	return rc;
4135 }
4136 
__cil_set_conditional_state_and_flags(policydb_t * pdb)4137 static void __cil_set_conditional_state_and_flags(policydb_t *pdb)
4138 {
4139 	cond_node_t *cur;
4140 
4141 	for (cur = pdb->cond_list; cur != NULL; cur = cur->next) {
4142 		int new_state;
4143 		cond_av_list_t *c;
4144 
4145 		new_state = cond_evaluate_expr(pdb, cur->expr);
4146 
4147 		cur->cur_state = new_state;
4148 
4149 		if (new_state == -1) {
4150 			cil_log(CIL_WARN, "Expression result was undefined - disabling all rules\n");
4151 		}
4152 
4153 		for (c = cur->true_list; c != NULL; c = c->next) {
4154 			if (new_state <= 0) {
4155 				c->node->key.specified &= ~AVTAB_ENABLED;
4156 			} else {
4157 				c->node->key.specified |= AVTAB_ENABLED;
4158 			}
4159 		}
4160 
4161 		for (c = cur->false_list; c != NULL; c = c->next) {
4162 			if (new_state) { /* -1 or 1 */
4163 				c->node->key.specified &= ~AVTAB_ENABLED;
4164 			} else {
4165 				c->node->key.specified |= AVTAB_ENABLED;
4166 			}
4167 		}
4168 	}
4169 }
4170 
__cil_policydb_create(const struct cil_db * db,struct sepol_policydb ** spdb)4171 int __cil_policydb_create(const struct cil_db *db, struct sepol_policydb **spdb)
4172 {
4173 	int rc;
4174 	struct policydb *pdb = NULL;
4175 
4176 	rc = sepol_policydb_create(spdb);
4177 	if (rc < 0) {
4178 		cil_log(CIL_ERR, "Failed to create policy db\n");
4179 		// spdb could be a dangling pointer at this point, so reset it so
4180 		// callers of this function don't need to worry about freeing garbage
4181 		*spdb = NULL;
4182 		goto exit;
4183 	}
4184 
4185 	pdb = &(*spdb)->p;
4186 
4187 	pdb->policy_type = POLICY_KERN;
4188 	pdb->target_platform = db->target_platform;
4189 	pdb->policyvers = db->policy_version;
4190 	pdb->handle_unknown = db->handle_unknown;
4191 	pdb->mls = db->mls;
4192 
4193 	return SEPOL_OK;
4194 
4195 exit:
4196 	return rc;
4197 }
4198 
4199 
__cil_policydb_init(policydb_t * pdb,const struct cil_db * db,struct cil_class * class_value_to_cil[],struct cil_perm ** perm_value_to_cil[])4200 int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
4201 {
4202 	int rc = SEPOL_ERR;
4203 
4204 	// these flags should get set in __cil_policydb_create. However, for
4205 	// backwards compatibility, it is possible that __cil_policydb_create is
4206 	// never called. So, they must also be set here.
4207 	pdb->handle_unknown = db->handle_unknown;
4208 	pdb->mls = db->mls;
4209 
4210 	rc = cil_classorder_to_policydb(pdb, db, class_value_to_cil, perm_value_to_cil);
4211 	if (rc != SEPOL_OK) {
4212 		goto exit;
4213 	}
4214 
4215 	if (pdb->mls == CIL_TRUE) {
4216 		rc = cil_catorder_to_policydb(pdb, db);
4217 		if (rc != SEPOL_OK) {
4218 			goto exit;
4219 		}
4220 
4221 		rc = cil_sensitivityorder_to_policydb(pdb, db);
4222 		if (rc != SEPOL_OK) {
4223 			goto exit;
4224 		}
4225 	}
4226 
4227 	rc = avtab_alloc(&pdb->te_avtab, MAX_AVTAB_SIZE);
4228 	if (rc != SEPOL_OK) {
4229 		goto exit;
4230 	}
4231 
4232 	rc = avtab_alloc(&pdb->te_cond_avtab, MAX_AVTAB_SIZE);
4233 	if (rc != SEPOL_OK) {
4234 		goto exit;
4235 	}
4236 
4237 	return SEPOL_OK;
4238 
4239 exit:
4240 
4241 	return rc;
4242 }
4243 
role_trans_hash(hashtab_t h,const_hashtab_key_t key)4244 static unsigned int role_trans_hash(hashtab_t h, const_hashtab_key_t key)
4245 {
4246 	const role_trans_t *k = (const role_trans_t *)key;
4247 	return ((k->role + (k->type << 2) +
4248 				(k->tclass << 5)) & (h->size - 1));
4249 }
4250 
role_trans_compare(hashtab_t h,const_hashtab_key_t key1,const_hashtab_key_t key2)4251 static int role_trans_compare(hashtab_t h
4252              __attribute__ ((unused)), const_hashtab_key_t key1,
4253 			              const_hashtab_key_t key2)
4254 {
4255 	const role_trans_t *a = (const role_trans_t *)key1;
4256 	const role_trans_t *b = (const role_trans_t *)key2;
4257 
4258 	return a->role != b->role || a->type != b->type || a->tclass != b->tclass;
4259 }
4260 
4261 /* Based on MurmurHash3, written by Austin Appleby and placed in the
4262  * public domain.
4263  */
avrulex_hash(hashtab_t h,const_hashtab_key_t key)4264 static unsigned int avrulex_hash(__attribute__((unused)) hashtab_t h, const_hashtab_key_t key)
4265 {
4266 	const avtab_key_t *k = (const avtab_key_t *)key;
4267 
4268 	static const uint32_t c1 = 0xcc9e2d51;
4269 	static const uint32_t c2 = 0x1b873593;
4270 	static const uint32_t r1 = 15;
4271 	static const uint32_t r2 = 13;
4272 	static const uint32_t m  = 5;
4273 	static const uint32_t n  = 0xe6546b64;
4274 
4275 	uint32_t hash = 0;
4276 
4277 #define mix(input) do { \
4278 	uint32_t v = input; \
4279 	v *= c1; \
4280 	v = (v << r1) | (v >> (32 - r1)); \
4281 	v *= c2; \
4282 	hash ^= v; \
4283 	hash = (hash << r2) | (hash >> (32 - r2)); \
4284 	hash = hash * m + n; \
4285 } while (0)
4286 
4287 	mix(k->target_class);
4288 	mix(k->target_type);
4289 	mix(k->source_type);
4290 	mix(k->specified);
4291 
4292 #undef mix
4293 
4294 	hash ^= hash >> 16;
4295 	hash *= 0x85ebca6b;
4296 	hash ^= hash >> 13;
4297 	hash *= 0xc2b2ae35;
4298 	hash ^= hash >> 16;
4299 
4300 	return hash & (AVRULEX_TABLE_SIZE - 1);
4301 }
4302 
avrulex_compare(hashtab_t h,const_hashtab_key_t key1,const_hashtab_key_t key2)4303 static int avrulex_compare(hashtab_t h
4304              __attribute__ ((unused)), const_hashtab_key_t key1,
4305 			              const_hashtab_key_t key2)
4306 {
4307 	const avtab_key_t *a = (const avtab_key_t *)key1;
4308 	const avtab_key_t *b = (const avtab_key_t *)key2;
4309 
4310 	return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class || a->specified != b->specified;
4311 }
4312 
cil_binary_create(const struct cil_db * db,sepol_policydb_t ** policydb)4313 int cil_binary_create(const struct cil_db *db, sepol_policydb_t **policydb)
4314 {
4315 	int rc = SEPOL_ERR;
4316 	struct sepol_policydb *pdb = NULL;
4317 
4318 	rc = __cil_policydb_create(db, &pdb);
4319 	if (rc != SEPOL_OK) {
4320 		goto exit;
4321 	}
4322 
4323 	rc = cil_binary_create_allocated_pdb(db, pdb);
4324 	if (rc != SEPOL_OK) {
4325 		goto exit;
4326 	}
4327 
4328 	*policydb = pdb;
4329 
4330 	return SEPOL_OK;
4331 
4332 exit:
4333 	sepol_policydb_free(pdb);
4334 
4335 	return rc;
4336 }
4337 
__cil_destroy_sepol_class_perms(class_perm_node_t * curr)4338 static void __cil_destroy_sepol_class_perms(class_perm_node_t *curr)
4339 {
4340 	class_perm_node_t *next;
4341 
4342 	while (curr) {
4343 		next = curr->next;
4344 		free(curr);
4345 		curr = next;
4346 	}
4347 }
4348 
__cil_rule_to_sepol_class_perms(policydb_t * pdb,struct cil_list * classperms,class_perm_node_t ** sepol_class_perms)4349 static int __cil_rule_to_sepol_class_perms(policydb_t *pdb, struct cil_list *classperms, class_perm_node_t **sepol_class_perms)
4350 {
4351 	int rc = SEPOL_ERR;
4352 	struct cil_list_item *i;
4353 	cil_list_for_each(i, classperms) {
4354 		if (i->flavor == CIL_CLASSPERMS) {
4355 			struct cil_classperms *cp = i->data;
4356 			if (FLAVOR(cp->class) == CIL_CLASS) {
4357 				class_perm_node_t *cpn = NULL;
4358 				class_datum_t *sepol_class = NULL;
4359 				uint32_t data = 0;
4360 
4361 				rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class);
4362 				if (rc != SEPOL_OK) goto exit;
4363 
4364 				rc = __cil_perms_to_datum(cp->perms, sepol_class, &data);
4365 				if (rc != SEPOL_OK) goto exit;
4366 				if (data != 0) { /* Only add if there are permissions */
4367 					cpn = cil_malloc(sizeof(class_perm_node_t));
4368 					cpn->tclass = sepol_class->s.value;
4369 					cpn->data = data;
4370 					cpn->next = *sepol_class_perms;
4371 					*sepol_class_perms = cpn;
4372 				}
4373 			} else { /* MAP */
4374 				struct cil_list_item *j = NULL;
4375 				cil_list_for_each(j, cp->perms) {
4376 					struct cil_perm *cmp = j->data;
4377 					rc = __cil_rule_to_sepol_class_perms(pdb, cmp->classperms, sepol_class_perms);
4378 					if (rc != SEPOL_OK) {
4379 						goto exit;
4380 					}
4381 				}
4382 			}
4383 		} else { /* SET */
4384 			struct cil_classperms_set *cp_set = i->data;
4385 			struct cil_classpermission *cp = cp_set->set;
4386 			rc = __cil_rule_to_sepol_class_perms(pdb, cp->classperms, sepol_class_perms);
4387 			if (rc != SEPOL_OK) {
4388 				goto exit;
4389 			}
4390 		}
4391 	}
4392 	return SEPOL_OK;
4393 
4394 exit:
4395 	return rc;
4396 }
4397 
__cil_permx_to_sepol_class_perms(policydb_t * pdb,struct cil_permissionx * permx,class_perm_node_t ** sepol_class_perms)4398 static int __cil_permx_to_sepol_class_perms(policydb_t *pdb, struct cil_permissionx *permx, class_perm_node_t **sepol_class_perms)
4399 {
4400 	int rc = SEPOL_OK;
4401 	struct cil_list *class_list = NULL;
4402 	struct cil_list_item *c;
4403 	class_datum_t *sepol_obj = NULL;
4404 	class_perm_node_t *cpn;
4405 	uint32_t data = 0;
4406 	char *perm_str = NULL;
4407 
4408 	class_list = cil_expand_class(permx->obj);
4409 
4410 	cil_list_for_each(c, class_list) {
4411 		rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
4412 		if (rc != SEPOL_OK) {
4413 			goto exit;
4414 		}
4415 
4416 		switch (permx->kind) {
4417 			case CIL_PERMX_KIND_IOCTL:
4418 				perm_str = CIL_KEY_IOCTL;
4419 				break;
4420 			default:
4421 				rc = SEPOL_ERR;
4422 				goto exit;
4423 		}
4424 
4425 		rc = __perm_str_to_datum(perm_str, sepol_obj, &data);
4426 		if (rc != SEPOL_OK) {
4427 			goto exit;
4428 		}
4429 
4430 		cpn = cil_malloc(sizeof(*cpn));
4431 		cpn->tclass = sepol_obj->s.value;
4432 		cpn->data = data;
4433 		cpn->next = *sepol_class_perms;
4434 		*sepol_class_perms = cpn;
4435 	}
4436 
4437 exit:
4438 	cil_list_destroy(&class_list, CIL_FALSE);
4439 
4440 	return rc;
4441 }
4442 
__cil_init_sepol_type_set(type_set_t * t)4443 static void __cil_init_sepol_type_set(type_set_t *t)
4444 {
4445 	ebitmap_init(&t->types);
4446 	ebitmap_init(&t->negset);
4447 	t->flags = 0;
4448 }
4449 
__cil_add_sepol_type(policydb_t * pdb,const struct cil_db * db,struct cil_symtab_datum * datum,ebitmap_t * map)4450 static int __cil_add_sepol_type(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *datum, ebitmap_t *map)
4451 {
4452 	int rc = SEPOL_ERR;
4453 	struct cil_tree_node *n = NODE(datum);
4454 	type_datum_t *sepol_datum = NULL;
4455 
4456 	if (n->flavor == CIL_TYPEATTRIBUTE) {
4457 		ebitmap_node_t *tnode;
4458 		unsigned int i;
4459 		struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
4460 		ebitmap_for_each_positive_bit(attr->types, tnode, i) {
4461 			datum = DATUM(db->val_to_type[i]);
4462 			rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum);
4463 			if (rc != SEPOL_OK) goto exit;
4464 			ebitmap_set_bit(map, sepol_datum->s.value - 1, 1);
4465 		}
4466 	} else {
4467 		rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum);
4468 		if (rc != SEPOL_OK) goto exit;
4469 		ebitmap_set_bit(map, sepol_datum->s.value - 1, 1);
4470 	}
4471 
4472 	return SEPOL_OK;
4473 
4474 exit:
4475 	return rc;
4476 }
4477 
__cil_init_sepol_avrule(uint32_t kind,struct cil_tree_node * node)4478 static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *node)
4479 {
4480 	avrule_t *avrule;
4481 	struct cil_tree_node *source_node;
4482 	char *source_path;
4483 	char *lm_kind;
4484 	uint32_t hll_line;
4485 
4486 	avrule = cil_malloc(sizeof(avrule_t));
4487 	avrule->specified = kind;
4488 	avrule->flags = 0;
4489 	__cil_init_sepol_type_set(&avrule->stypes);
4490 	__cil_init_sepol_type_set(&avrule->ttypes);
4491 	avrule->perms = NULL;
4492 	avrule->line = node->line;
4493 
4494 	avrule->source_filename = NULL;
4495 	avrule->source_line = node->line;
4496 	source_node = cil_tree_get_next_path(node, &lm_kind, &hll_line, &source_path);
4497 	if (source_node) {
4498 		avrule->source_filename = source_path;
4499 		if (lm_kind != CIL_KEY_SRC_CIL) {
4500 			avrule->source_line = hll_line + node->hll_offset - source_node->hll_offset - 1;
4501 		}
4502 	}
4503 
4504 	avrule->next = NULL;
4505 	return avrule;
4506 }
4507 
__cil_destroy_sepol_avrules(avrule_t * curr)4508 static void __cil_destroy_sepol_avrules(avrule_t *curr)
4509 {
4510 	avrule_t *next;
4511 
4512 	while (curr) {
4513 		next = curr->next;
4514 		ebitmap_destroy(&curr->stypes.types);
4515 		ebitmap_destroy(&curr->stypes.negset);
4516 		ebitmap_destroy(&curr->ttypes.types);
4517 		ebitmap_destroy(&curr->ttypes.negset);
4518 		__cil_destroy_sepol_class_perms(curr->perms);
4519 		free(curr);
4520 		curr = next;
4521 	}
4522 }
4523 
__cil_print_parents(const char * pad,struct cil_tree_node * n)4524 static void __cil_print_parents(const char *pad, struct cil_tree_node *n)
4525 {
4526 	if (!n) return;
4527 
4528 	__cil_print_parents(pad, n->parent);
4529 
4530 	if (n->flavor != CIL_SRC_INFO) {
4531 		cil_tree_log(n, CIL_ERR,"%s%s", pad, cil_node_to_string(n));
4532 	}
4533 }
4534 
__cil_print_classperm(struct cil_list * cp_list)4535 static void __cil_print_classperm(struct cil_list *cp_list)
4536 {
4537 	struct cil_list_item *i1, *i2;
4538 
4539 	i1 = cp_list->head;
4540 	if (i1->flavor == CIL_CLASSPERMS) {
4541 		struct cil_classperms *cp = i1->data;
4542 		cil_log(CIL_ERR,"(%s (", DATUM(cp->class)->fqn);
4543 		cil_list_for_each(i2, cp->perms) {
4544 			cil_log(CIL_ERR,"%s",DATUM(i2->data)->fqn);
4545 			if (i2 != cp->perms->tail) {
4546 				cil_log(CIL_ERR," ");
4547 			} else {
4548 				cil_log(CIL_ERR,"))");
4549 			}
4550 		}
4551 	} else {
4552 		struct cil_classperms_set *cp_set = i1->data;
4553 		cil_log(CIL_ERR,"%s", DATUM(cp_set->set)->fqn);
4554 	}
4555 }
4556 
__cil_print_permissionx(struct cil_permissionx * px)4557 static void __cil_print_permissionx(struct cil_permissionx *px)
4558 {
4559 	const char *kind_str = "";
4560 	char *expr_str;
4561 
4562 	switch (px->kind) {
4563 		case CIL_PERMX_KIND_IOCTL:
4564 			kind_str = CIL_KEY_IOCTL;
4565 			break;
4566 		default:
4567 			kind_str = "unknown";
4568 			break;
4569 	}
4570 
4571 	__cil_expr_to_string(px->expr_str, CIL_PERMISSIONX, &expr_str);
4572 
4573 	cil_log(CIL_ERR, "%s %s (%s)", kind_str, DATUM(px->obj)->fqn, expr_str);
4574 
4575 	free(expr_str);
4576 }
4577 
__cil_print_rule(const char * pad,const char * kind,struct cil_avrule * avrule)4578 static void __cil_print_rule(const char *pad, const char *kind, struct cil_avrule *avrule)
4579 {
4580 	cil_log(CIL_ERR,"%s(%s ", pad, kind);
4581 	cil_log(CIL_ERR,"%s %s ", DATUM(avrule->src)->fqn, DATUM(avrule->tgt)->fqn);
4582 
4583 	if (!avrule->is_extended) {
4584 		__cil_print_classperm(avrule->perms.classperms);
4585 	} else {
4586 		cil_log(CIL_ERR, "(");
4587 		__cil_print_permissionx(avrule->perms.x.permx);
4588 		cil_log(CIL_ERR, ")");
4589 	}
4590 
4591 	cil_log(CIL_ERR,")\n");
4592 }
4593 
__cil_print_neverallow_failure(const struct cil_db * db,struct cil_tree_node * node)4594 static int __cil_print_neverallow_failure(const struct cil_db *db, struct cil_tree_node *node)
4595 {
4596 	int rc;
4597 	struct cil_list_item *i2;
4598 	struct cil_list *matching;
4599 	struct cil_avrule *cil_rule = node->data;
4600 	struct cil_avrule target;
4601 	struct cil_tree_node *n2;
4602 	struct cil_avrule *r2;
4603 	char *neverallow_str;
4604 	char *allow_str;
4605 	enum cil_flavor avrule_flavor;
4606 
4607 	target.rule_kind = CIL_AVRULE_ALLOWED;
4608 	target.is_extended = cil_rule->is_extended;
4609 	target.src = cil_rule->src;
4610 	target.tgt = cil_rule->tgt;
4611 	target.perms = cil_rule->perms;
4612 
4613 	if (!cil_rule->is_extended) {
4614 		neverallow_str = CIL_KEY_NEVERALLOW;
4615 		allow_str = CIL_KEY_ALLOW;
4616 		avrule_flavor = CIL_AVRULE;
4617 	} else {
4618 		neverallow_str = CIL_KEY_NEVERALLOWX;
4619 		allow_str = CIL_KEY_ALLOWX;
4620 		avrule_flavor = CIL_AVRULEX;
4621 	}
4622 	cil_tree_log(node, CIL_ERR, "%s check failed", neverallow_str);
4623 	__cil_print_rule("  ", neverallow_str, cil_rule);
4624 	cil_list_init(&matching, CIL_NODE);
4625 	rc = cil_find_matching_avrule_in_ast(db->ast->root, avrule_flavor, &target, matching, CIL_FALSE);
4626 	if (rc) {
4627 		cil_log(CIL_ERR, "Error occurred while checking %s rules\n", neverallow_str);
4628 		cil_list_destroy(&matching, CIL_FALSE);
4629 		goto exit;
4630 	}
4631 
4632 	cil_list_for_each(i2, matching) {
4633 		n2 = i2->data;
4634 		r2 = n2->data;
4635 		__cil_print_parents("    ", n2);
4636 		__cil_print_rule("      ", allow_str, r2);
4637 	}
4638 	cil_log(CIL_ERR,"\n");
4639 	cil_list_destroy(&matching, CIL_FALSE);
4640 
4641 exit:
4642 	return rc;
4643 }
4644 
cil_check_neverallow(const struct cil_db * db,policydb_t * pdb,struct cil_tree_node * node,int * violation)4645 static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node, int *violation)
4646 {
4647 	int rc = SEPOL_OK;
4648 	struct cil_avrule *cil_rule = node->data;
4649 	struct cil_symtab_datum *tgt = cil_rule->tgt;
4650 	uint32_t kind;
4651 	avrule_t *rule;
4652 	struct cil_list *xperms = NULL;
4653 	struct cil_list_item *item;
4654 
4655 	if (!cil_rule->is_extended) {
4656 		kind = AVRULE_NEVERALLOW;
4657 	} else {
4658 		kind = AVRULE_XPERMS_NEVERALLOW;
4659 	}
4660 
4661 	rule = __cil_init_sepol_avrule(kind, node);
4662 	rule->next = NULL;
4663 
4664 	rc = __cil_add_sepol_type(pdb, db, cil_rule->src, &rule->stypes.types);
4665 	if (rc != SEPOL_OK) {
4666 		goto exit;
4667 	}
4668 
4669 	if (tgt->fqn == CIL_KEY_SELF) {
4670 		rule->flags = RULE_SELF;
4671 	} else {
4672 		rc = __cil_add_sepol_type(pdb, db, cil_rule->tgt, &rule->ttypes.types);
4673 		if (rc != SEPOL_OK) {
4674 			goto exit;
4675 		}
4676 	}
4677 
4678 	if (!cil_rule->is_extended) {
4679 		rc = __cil_rule_to_sepol_class_perms(pdb, cil_rule->perms.classperms, &rule->perms);
4680 		if (rc != SEPOL_OK) {
4681 			goto exit;
4682 		}
4683 
4684 		rc = check_assertion(pdb, rule);
4685 		if (rc == CIL_TRUE) {
4686 			*violation = CIL_TRUE;
4687 			rc = __cil_print_neverallow_failure(db, node);
4688 			if (rc != SEPOL_OK) {
4689 				goto exit;
4690 			}
4691 		}
4692 
4693 	} else {
4694 		rc = __cil_permx_to_sepol_class_perms(pdb, cil_rule->perms.x.permx, &rule->perms);
4695 		if (rc != SEPOL_OK) {
4696 			goto exit;
4697 		}
4698 
4699 		rc = __cil_permx_bitmap_to_sepol_xperms_list(cil_rule->perms.x.permx->perms, &xperms);
4700 		if (rc != SEPOL_OK) {
4701 			goto exit;
4702 		}
4703 
4704 		cil_list_for_each(item, xperms) {
4705 			rule->xperms = item->data;
4706 			rc = check_assertion(pdb, rule);
4707 			if (rc == CIL_TRUE) {
4708 				*violation = CIL_TRUE;
4709 				rc = __cil_print_neverallow_failure(db, node);
4710 				if (rc != SEPOL_OK) {
4711 					goto exit;
4712 				}
4713 			}
4714 		}
4715 	}
4716 
4717 exit:
4718 	if (xperms != NULL) {
4719 		cil_list_for_each(item, xperms) {
4720 			free(item->data);
4721 			item->data = NULL;
4722 		}
4723 		cil_list_destroy(&xperms, CIL_FALSE);
4724 	}
4725 
4726 	rule->xperms = NULL;
4727 	__cil_destroy_sepol_avrules(rule);
4728 
4729 	return rc;
4730 }
4731 
cil_check_neverallows(const struct cil_db * db,policydb_t * pdb,struct cil_list * neverallows,int * violation)4732 static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows, int *violation)
4733 {
4734 	int rc = SEPOL_OK;
4735 	struct cil_list_item *item;
4736 
4737 	cil_list_for_each(item, neverallows) {
4738 		rc = cil_check_neverallow(db, pdb, item->data, violation);
4739 		if (rc != SEPOL_OK) {
4740 			goto exit;
4741 		}
4742 	}
4743 
4744 exit:
4745 	return rc;
4746 }
4747 
cil_classperms_from_sepol(policydb_t * pdb,uint16_t class,uint32_t data,struct cil_class * class_value_to_cil[],struct cil_perm ** perm_value_to_cil[])4748 static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t class, uint32_t data, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
4749 {
4750 	struct cil_classperms *cp;
4751 	struct cil_list *cp_list;
4752 	class_datum_t *sepol_class = pdb->class_val_to_struct[class - 1];
4753 	unsigned i;
4754 
4755 	cil_classperms_init(&cp);
4756 
4757 	cp->class = class_value_to_cil[class];
4758 	if (!cp->class) goto exit;
4759 
4760 	cil_list_init(&cp->perms, CIL_PERM);
4761 	for (i = 0; i < sepol_class->permissions.nprim; i++) {
4762 		struct cil_perm *perm;
4763 		if ((data & (UINT32_C(1) << i)) == 0) continue;
4764 		perm = perm_value_to_cil[class][i+1];
4765 		if (!perm) goto exit;
4766 		cil_list_append(cp->perms, CIL_PERM, perm);
4767 	}
4768 
4769 	cil_list_init(&cp_list, CIL_CLASSPERMS);
4770 	cil_list_append(cp_list, CIL_CLASSPERMS, cp);
4771 
4772 	return cp_list;
4773 
4774 exit:
4775 	cil_destroy_classperms(cp);
4776 	cil_log(CIL_ERR,"Failed to create CIL class-permissions from sepol values\n");
4777 	return NULL;
4778 }
4779 
cil_avrule_from_sepol(policydb_t * pdb,avtab_ptr_t sepol_rule,struct cil_avrule * cil_rule,void * type_value_to_cil[],struct cil_class * class_value_to_cil[],struct cil_perm ** perm_value_to_cil[])4780 static int cil_avrule_from_sepol(policydb_t *pdb, avtab_ptr_t sepol_rule, struct cil_avrule *cil_rule, void *type_value_to_cil[], struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
4781 {
4782 	int rc = SEPOL_ERR;
4783 	avtab_key_t *k = &sepol_rule->key;
4784 	avtab_datum_t *d = &sepol_rule->datum;
4785 	cil_rule->src = type_value_to_cil[k->source_type];
4786 	if (!cil_rule->src) goto exit;
4787 
4788 	cil_rule->tgt = type_value_to_cil[k->target_type];
4789 	if (!cil_rule->tgt) goto exit;
4790 
4791 	cil_rule->perms.classperms = cil_classperms_from_sepol(pdb, k->target_class, d->data, class_value_to_cil, perm_value_to_cil);
4792 	if (!cil_rule->perms.classperms) goto exit;
4793 
4794 	return SEPOL_OK;
4795 
4796 exit:
4797 	cil_log(CIL_ERR,"Failed to create CIL AV rule from sepol values\n");
4798 	return rc;
4799 }
4800 
cil_check_type_bounds(const struct cil_db * db,policydb_t * pdb,void * type_value_to_cil,struct cil_class * class_value_to_cil[],struct cil_perm ** perm_value_to_cil[],int * violation)4801 static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void *type_value_to_cil, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[], int *violation)
4802 {
4803 	int rc = SEPOL_OK;
4804 	int i;
4805 
4806 	for (i = 0; i < db->num_types; i++) {
4807 		type_datum_t *child;
4808 		type_datum_t *parent;
4809 		avtab_ptr_t bad = NULL;
4810 		int numbad = 0;
4811 		struct cil_type *t = db->val_to_type[i];
4812 
4813 		if (!t->bounds) continue;
4814 
4815 		rc = __cil_get_sepol_type_datum(pdb, DATUM(t), &child);
4816 		if (rc != SEPOL_OK) goto exit;
4817 
4818 		rc = __cil_get_sepol_type_datum(pdb, DATUM(t->bounds), &parent);
4819 		if (rc != SEPOL_OK) goto exit;
4820 
4821 		rc = bounds_check_type(NULL, pdb, child->s.value, parent->s.value, &bad, &numbad);
4822 		if (rc != SEPOL_OK) goto exit;
4823 
4824 		if (bad) {
4825 			avtab_ptr_t cur;
4826 			struct cil_avrule target;
4827 			struct cil_tree_node *n1 = NULL;
4828 			int count_bad = 0;
4829 
4830 			*violation = CIL_TRUE;
4831 
4832                         target.is_extended = 0;
4833 			target.rule_kind = CIL_AVRULE_ALLOWED;
4834 			target.src_str = NULL;
4835 			target.tgt_str = NULL;
4836 
4837 			cil_log(CIL_ERR, "Child type %s exceeds bounds of parent %s\n",
4838 				t->datum.fqn, t->bounds->datum.fqn);
4839 			for (cur = bad; cur; cur = cur->next) {
4840 				struct cil_list_item *i2;
4841 				struct cil_list *matching;
4842 				int num_matching = 0;
4843 				int count_matching = 0;
4844 
4845 				rc = cil_avrule_from_sepol(pdb, cur, &target, type_value_to_cil, class_value_to_cil, perm_value_to_cil);
4846 				if (rc != SEPOL_OK) {
4847 					cil_log(CIL_ERR, "Failed to convert sepol avrule to CIL\n");
4848 					bounds_destroy_bad(bad);
4849 					goto exit;
4850 				}
4851 				__cil_print_rule("  ", "allow", &target);
4852 				cil_list_init(&matching, CIL_NODE);
4853 				rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_TRUE);
4854 				if (rc) {
4855 					cil_log(CIL_ERR, "Error occurred while checking type bounds\n");
4856 					cil_list_destroy(&matching, CIL_FALSE);
4857 					cil_list_destroy(&target.perms.classperms, CIL_TRUE);
4858 					bounds_destroy_bad(bad);
4859 					goto exit;
4860 				}
4861 				cil_list_for_each(i2, matching) {
4862 					num_matching++;
4863 				}
4864 				cil_list_for_each(i2, matching) {
4865 					struct cil_tree_node *n2 = i2->data;
4866 					struct cil_avrule *r2 = n2->data;
4867 					if (n1 == n2) {
4868 						cil_log(CIL_ERR, "    <See previous>\n");
4869 					} else {
4870 						n1 = n2;
4871 						__cil_print_parents("    ", n2);
4872 						__cil_print_rule("      ", "allow", r2);
4873 					}
4874 					count_matching++;
4875 					if (count_matching >= 2) {
4876 						cil_log(CIL_ERR, "    Only first 2 of %d matching rules shown\n", num_matching);
4877 						break;
4878 					}
4879 				}
4880 				cil_list_destroy(&matching, CIL_FALSE);
4881 				cil_list_destroy(&target.perms.classperms, CIL_TRUE);
4882 				count_bad++;
4883 				if (count_bad >= 2) {
4884 					cil_log(CIL_ERR, "  Only first 2 of %d bad rules shown\n", numbad);
4885 					break;
4886 				}
4887 			}
4888 			bounds_destroy_bad(bad);
4889 		}
4890 	}
4891 
4892 exit:
4893 	return rc;
4894 }
4895 
4896 // assumes policydb is already allocated and initialized properly with things
4897 // like policy type set to kernel and version set appropriately
cil_binary_create_allocated_pdb(const struct cil_db * db,sepol_policydb_t * policydb)4898 int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *policydb)
4899 {
4900 	int rc = SEPOL_ERR;
4901 	int i;
4902 	struct cil_args_binary extra_args;
4903 	policydb_t *pdb = &policydb->p;
4904 	struct cil_list *neverallows = NULL;
4905 	hashtab_t role_trans_table = NULL;
4906 	hashtab_t avrulex_ioctl_table = NULL;
4907 	void **type_value_to_cil = NULL;
4908 	struct cil_class **class_value_to_cil = NULL;
4909 	struct cil_perm ***perm_value_to_cil = NULL;
4910 
4911 	if (db == NULL || policydb == NULL) {
4912 		if (db == NULL) {
4913 			cil_log(CIL_ERR,"db == NULL\n");
4914 		} else if (policydb == NULL) {
4915 			cil_log(CIL_ERR,"policydb == NULL\n");
4916 		}
4917 		return SEPOL_ERR;
4918 	}
4919 
4920 	/* libsepol values start at 1. Just allocate extra memory rather than
4921 	 * subtract 1 from the sepol value.
4922 	 */
4923 	type_value_to_cil = calloc(db->num_types_and_attrs+1, sizeof(*type_value_to_cil));
4924 	if (!type_value_to_cil) goto exit;
4925 
4926 	class_value_to_cil = calloc(db->num_classes+1, sizeof(*class_value_to_cil));
4927 	if (!class_value_to_cil) goto exit;
4928 
4929 	perm_value_to_cil = calloc(db->num_classes+1, sizeof(*perm_value_to_cil));
4930 	if (!perm_value_to_cil) goto exit;
4931 	for (i=1; i < db->num_classes+1; i++) {
4932 		perm_value_to_cil[i] = calloc(PERMS_PER_CLASS+1, sizeof(*perm_value_to_cil[i]));
4933 		if (!perm_value_to_cil[i]) goto exit;
4934 	}
4935 
4936 	rc = __cil_policydb_init(pdb, db, class_value_to_cil, perm_value_to_cil);
4937 	if (rc != SEPOL_OK) {
4938 		cil_log(CIL_ERR,"Problem in policydb_init\n");
4939 		goto exit;
4940 	}
4941 
4942 	role_trans_table = hashtab_create(role_trans_hash, role_trans_compare, ROLE_TRANS_TABLE_SIZE);
4943 	if (!role_trans_table) {
4944 		cil_log(CIL_INFO, "Failure to create hashtab for role_trans\n");
4945 		goto exit;
4946 	}
4947 
4948 	avrulex_ioctl_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE);
4949 	if (!avrulex_ioctl_table) {
4950 		cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n");
4951 		goto exit;
4952 	}
4953 
4954 	cil_list_init(&neverallows, CIL_LIST_ITEM);
4955 
4956 	extra_args.db = db;
4957 	extra_args.pdb = pdb;
4958 	extra_args.neverallows = neverallows;
4959 	extra_args.role_trans_table = role_trans_table;
4960 	extra_args.avrulex_ioctl_table = avrulex_ioctl_table;
4961 	extra_args.type_value_to_cil = type_value_to_cil;
4962 
4963 	for (i = 1; i <= 3; i++) {
4964 		extra_args.pass = i;
4965 
4966 		rc = cil_tree_walk(db->ast->root, __cil_binary_create_helper, NULL, NULL, &extra_args);
4967 		if (rc != SEPOL_OK) {
4968 			cil_log(CIL_INFO, "Failure while walking cil database\n");
4969 			goto exit;
4970 		}
4971 
4972 		if (i == 1) {
4973 			rc = __cil_policydb_val_arrays_create(pdb);
4974 			if (rc != SEPOL_OK) {
4975 				cil_log(CIL_INFO, "Failure creating val_to_{struct,name} arrays\n");
4976 				goto exit;
4977 			}
4978 		}
4979 
4980 		if (i == 3) {
4981 			rc = hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_to_policydb, pdb);
4982 			if (rc != SEPOL_OK) {
4983 				cil_log(CIL_INFO, "Failure creating avrulex rules\n");
4984 				goto exit;
4985 			}
4986 		}
4987 	}
4988 
4989 	rc = cil_sidorder_to_policydb(pdb, db);
4990 	if (rc != SEPOL_OK) {
4991 		goto exit;
4992 	}
4993 
4994 	rc = __cil_contexts_to_policydb(pdb, db);
4995 	if (rc != SEPOL_OK) {
4996 		cil_log(CIL_INFO, "Failure while inserting cil contexts into sepol policydb\n");
4997 		goto exit;
4998 	}
4999 
5000 	if (pdb->type_attr_map == NULL) {
5001 		rc = __cil_typeattr_bitmap_init(pdb);
5002 		if (rc != SEPOL_OK) {
5003 			cil_log(CIL_INFO, "Failure while initializing typeattribute bitmap\n");
5004 			goto exit;
5005 		}
5006 	}
5007 
5008 	cond_optimize_lists(pdb->cond_list);
5009 	__cil_set_conditional_state_and_flags(pdb);
5010 
5011 	if (db->disable_neverallow != CIL_TRUE) {
5012 		int violation = CIL_FALSE;
5013 		cil_log(CIL_INFO, "Checking Neverallows\n");
5014 		rc = cil_check_neverallows(db, pdb, neverallows, &violation);
5015 		if (rc != SEPOL_OK) goto exit;
5016 
5017 		cil_log(CIL_INFO, "Checking User Bounds\n");
5018 		rc = bounds_check_users(NULL, pdb);
5019 		if (rc) {
5020 			violation = CIL_TRUE;
5021 		}
5022 
5023 		cil_log(CIL_INFO, "Checking Role Bounds\n");
5024 		rc = bounds_check_roles(NULL, pdb);
5025 		if (rc) {
5026 			violation = CIL_TRUE;
5027 		}
5028 
5029 		cil_log(CIL_INFO, "Checking Type Bounds\n");
5030 		rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil, &violation);
5031 		if (rc != SEPOL_OK) goto exit;
5032 
5033 		if (violation == CIL_TRUE) {
5034 			rc = SEPOL_ERR;
5035 			goto exit;
5036 		}
5037 
5038 	}
5039 
5040 	/* This pre-expands the roles and users for context validity checking */
5041 	if (hashtab_map(pdb->p_roles.table, policydb_role_cache, pdb)) {
5042 		cil_log(CIL_INFO, "Failure creating roles cache");
5043 		rc = SEPOL_ERR;
5044 		goto exit;
5045     }
5046 
5047 	if (hashtab_map(pdb->p_users.table, policydb_user_cache, pdb)) {
5048 		cil_log(CIL_INFO, "Failure creating users cache");
5049 		rc = SEPOL_ERR;
5050 		goto exit;
5051 	}
5052 
5053 	rc = SEPOL_OK;
5054 
5055 exit:
5056 	hashtab_destroy(role_trans_table);
5057 	hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_destroy, NULL);
5058 	hashtab_destroy(avrulex_ioctl_table);
5059 	free(type_value_to_cil);
5060 	free(class_value_to_cil);
5061 	if (perm_value_to_cil != NULL) {
5062 		/* Range is because libsepol values start at 1. */
5063 		for (i=1; i < db->num_classes+1; i++) {
5064 			free(perm_value_to_cil[i]);
5065 		}
5066 		free(perm_value_to_cil);
5067 	}
5068 	cil_list_destroy(&neverallows, CIL_FALSE);
5069 
5070 	return rc;
5071 }
5072