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