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