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