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