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