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