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