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