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->used) {
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->used) {
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)\n", cil_rule->src_str, cil_rule->tgt_str, cil_rule->obj_str, cil_rule->result_str);
1022 rc = SEPOL_ERR;
1023 }
1024 goto exit;
1025 }
1026
1027 if (!cond_node) {
1028 rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum);
1029 } else {
1030 existing = avtab_search_node(&pdb->te_cond_avtab, &avtab_key);
1031 if (existing) {
1032 cond_av_list_t *this_list;
1033 cond_av_list_t *other_list;
1034 avtab_datum_t *search_datum;
1035
1036 if (cond_flavor == CIL_CONDTRUE) {
1037 this_list = cond_node->true_list;
1038 other_list = cond_node->false_list;
1039 } else {
1040 this_list = cond_node->false_list;
1041 other_list = cond_node->true_list;
1042 }
1043
1044 search_datum = cil_cond_av_list_search(&avtab_key, other_list);
1045 if (search_datum == NULL) {
1046 if (existing->datum.data != res) {
1047 cil_log(CIL_ERR, "Conflicting type rules (scontext=%s tcontext=%s tclass=%s result=%s)\n", cil_rule->src_str, cil_rule->tgt_str, cil_rule->obj_str, cil_rule->result_str);
1048 rc = SEPOL_ERR;
1049 goto exit;
1050 }
1051
1052 search_datum = cil_cond_av_list_search(&avtab_key, this_list);
1053 if (search_datum) {
1054 goto exit;
1055 }
1056 }
1057 }
1058 rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor);
1059 }
1060
1061 exit:
1062 return rc;
1063 }
1064
__cil_type_rule_to_avtab(policydb_t * pdb,const struct cil_db * db,struct cil_type_rule * cil_rule,cond_node_t * cond_node,enum cil_flavor cond_flavor)1065 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)
1066 {
1067 int rc = SEPOL_ERR;
1068 uint16_t kind = cil_rule->rule_kind;
1069 type_datum_t *sepol_src = NULL;
1070 type_datum_t *sepol_tgt = NULL;
1071 class_datum_t *sepol_obj = NULL;
1072 struct cil_list *class_list;
1073 type_datum_t *sepol_result = NULL;
1074 ebitmap_t src_bitmap, tgt_bitmap;
1075 ebitmap_node_t *node1, *node2;
1076 unsigned int i, j;
1077 struct cil_list_item *c;
1078
1079 rc = __cil_expand_type(cil_rule->src, &src_bitmap);
1080 if (rc != SEPOL_OK) goto exit;
1081
1082 rc = __cil_expand_type(cil_rule->tgt, &tgt_bitmap);
1083 if (rc != SEPOL_OK) goto exit;
1084
1085 class_list = cil_expand_class(cil_rule->obj);
1086
1087 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_rule->result), &sepol_result);
1088 if (rc != SEPOL_OK) goto exit;
1089
1090 ebitmap_for_each_bit(&src_bitmap, node1, i) {
1091 if (!ebitmap_get_bit(&src_bitmap, i)) continue;
1092
1093 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src);
1094 if (rc != SEPOL_OK) goto exit;
1095
1096 ebitmap_for_each_bit(&tgt_bitmap, node2, j) {
1097 if (!ebitmap_get_bit(&tgt_bitmap, j)) continue;
1098
1099 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
1100 if (rc != SEPOL_OK) goto exit;
1101
1102 cil_list_for_each(c, class_list) {
1103 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
1104 if (rc != SEPOL_OK) goto exit;
1105
1106 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);
1107 if (rc != SEPOL_OK) goto exit;
1108 }
1109 }
1110 }
1111
1112 rc = SEPOL_OK;
1113
1114 exit:
1115 ebitmap_destroy(&src_bitmap);
1116 ebitmap_destroy(&tgt_bitmap);
1117 cil_list_destroy(&class_list, CIL_FALSE);
1118 return rc;
1119 }
1120
cil_type_rule_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_type_rule * cil_rule)1121 int cil_type_rule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_type_rule *cil_rule)
1122 {
1123 return __cil_type_rule_to_avtab(pdb, db, cil_rule, NULL, CIL_FALSE);
1124 }
1125
__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)1126 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)
1127 {
1128 int rc = SEPOL_ERR;
1129 type_datum_t *sepol_src = NULL;
1130 type_datum_t *sepol_tgt = NULL;
1131 class_datum_t *sepol_obj = NULL;
1132 struct cil_list *class_list;
1133 type_datum_t *sepol_result = NULL;
1134 filename_trans_t *newkey = NULL;
1135 filename_trans_datum_t *newdatum = NULL, *otype = NULL;
1136 ebitmap_t src_bitmap, tgt_bitmap;
1137 ebitmap_node_t *node1, *node2;
1138 unsigned int i, j;
1139 struct cil_list_item *c;
1140 char *name = DATUM(typetrans->name)->name;
1141
1142 if (name == CIL_KEY_STAR) {
1143 struct cil_type_rule trans;
1144 trans.rule_kind = CIL_TYPE_TRANSITION;
1145 trans.src = typetrans->src;
1146 trans.tgt = typetrans->tgt;
1147 trans.obj = typetrans->obj;
1148 trans.result = typetrans->result;
1149 return __cil_type_rule_to_avtab(pdb, db, &trans, cond_node, cond_flavor);
1150 }
1151
1152 rc = __cil_expand_type(typetrans->src, &src_bitmap);
1153 if (rc != SEPOL_OK) goto exit;
1154
1155 rc = __cil_expand_type(typetrans->tgt, &tgt_bitmap);
1156 if (rc != SEPOL_OK) goto exit;
1157
1158 class_list = cil_expand_class(typetrans->obj);
1159
1160 rc = __cil_get_sepol_type_datum(pdb, DATUM(typetrans->result), &sepol_result);
1161 if (rc != SEPOL_OK) goto exit;
1162
1163 ebitmap_for_each_bit(&src_bitmap, node1, i) {
1164 if (!ebitmap_get_bit(&src_bitmap, i)) continue;
1165
1166 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src);
1167 if (rc != SEPOL_OK) goto exit;
1168
1169 ebitmap_for_each_bit(&tgt_bitmap, node2, j) {
1170 if (!ebitmap_get_bit(&tgt_bitmap, j)) continue;
1171
1172 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
1173 if (rc != SEPOL_OK) goto exit;
1174
1175 cil_list_for_each(c, class_list) {
1176 int add = CIL_TRUE;
1177 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
1178 if (rc != SEPOL_OK) goto exit;
1179
1180 newkey = cil_calloc(1, sizeof(*newkey));
1181 newdatum = cil_calloc(1, sizeof(*newdatum));
1182 newkey->stype = sepol_src->s.value;
1183 newkey->ttype = sepol_tgt->s.value;
1184 newkey->tclass = sepol_obj->s.value;
1185 newkey->name = cil_strdup(name);
1186 newdatum->otype = sepol_result->s.value;
1187
1188 rc = hashtab_insert(filename_trans_table, (hashtab_key_t)newkey, newdatum);
1189 if (rc != SEPOL_OK) {
1190 if (rc == SEPOL_EEXIST) {
1191 add = CIL_FALSE;
1192 otype = hashtab_search(filename_trans_table, (hashtab_key_t)newkey);
1193 if (newdatum->otype != otype->otype) {
1194 cil_log(CIL_ERR, "Conflicting name type transition rules\n");
1195 } else {
1196 rc = SEPOL_OK;
1197 }
1198 } else {
1199 cil_log(CIL_ERR, "Out of memory\n");
1200 }
1201 }
1202
1203 if (add == CIL_TRUE) {
1204 rc = hashtab_insert(pdb->filename_trans,
1205 (hashtab_key_t)newkey,
1206 newdatum);
1207 if (rc != SEPOL_OK) {
1208 cil_log(CIL_ERR, "Out of memory\n");
1209 goto exit;
1210 }
1211 } else {
1212 free(newkey->name);
1213 free(newkey);
1214 free(newdatum);
1215 if (rc != SEPOL_OK) {
1216 goto exit;
1217 }
1218 }
1219 }
1220 }
1221 }
1222
1223 rc = SEPOL_OK;
1224
1225 exit:
1226 ebitmap_destroy(&src_bitmap);
1227 ebitmap_destroy(&tgt_bitmap);
1228 cil_list_destroy(&class_list, CIL_FALSE);
1229 return rc;
1230 }
1231
cil_typetransition_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_nametypetransition * typetrans,hashtab_t filename_trans_table)1232 int cil_typetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, hashtab_t filename_trans_table)
1233 {
1234 return __cil_typetransition_to_avtab(pdb, db, typetrans, NULL, CIL_FALSE, filename_trans_table);
1235 }
1236
__perm_str_to_datum(char * perm_str,class_datum_t * sepol_class,uint32_t * datum)1237 int __perm_str_to_datum(char *perm_str, class_datum_t *sepol_class, uint32_t *datum)
1238 {
1239 int rc;
1240 perm_datum_t *sepol_perm;
1241 common_datum_t *sepol_common;
1242
1243 sepol_perm = hashtab_search(sepol_class->permissions.table, perm_str);
1244 if (sepol_perm == NULL) {
1245 sepol_common = sepol_class->comdatum;
1246 sepol_perm = hashtab_search(sepol_common->permissions.table, perm_str);
1247 if (sepol_perm == NULL) {
1248 cil_log(CIL_ERR, "Failed to find datum for perm %s\n", perm_str);
1249 rc = SEPOL_ERR;
1250 goto exit;
1251 }
1252 }
1253 *datum |= 1 << (sepol_perm->s.value - 1);
1254
1255 return SEPOL_OK;
1256
1257 exit:
1258 return rc;
1259 }
1260
__cil_perms_to_datum(struct cil_list * perms,class_datum_t * sepol_class,uint32_t * datum)1261 int __cil_perms_to_datum(struct cil_list *perms, class_datum_t *sepol_class, uint32_t *datum)
1262 {
1263 int rc = SEPOL_ERR;
1264 char *key = NULL;
1265 struct cil_list_item *curr_perm;
1266 struct cil_perm *cil_perm;
1267 uint32_t data = 0;
1268
1269 cil_list_for_each(curr_perm, perms) {
1270 cil_perm = curr_perm->data;
1271 key = cil_perm->datum.fqn;
1272
1273 rc = __perm_str_to_datum(key, sepol_class, &data);
1274 if (rc != SEPOL_OK) {
1275 goto exit;
1276 }
1277 }
1278
1279 *datum = data;
1280
1281 return SEPOL_OK;
1282
1283 exit:
1284 return rc;
1285 }
1286
__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)1287 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)
1288 {
1289 int rc = SEPOL_OK;
1290 avtab_key_t avtab_key;
1291 avtab_datum_t avtab_datum;
1292 avtab_datum_t *avtab_dup = NULL;
1293
1294 avtab_key.source_type = src;
1295 avtab_key.target_type = tgt;
1296 avtab_key.target_class = obj;
1297
1298 switch (kind) {
1299 case CIL_AVRULE_ALLOWED:
1300 avtab_key.specified = AVTAB_ALLOWED;
1301 break;
1302 case CIL_AVRULE_AUDITALLOW:
1303 avtab_key.specified = AVTAB_AUDITALLOW;
1304 break;
1305 case CIL_AVRULE_DONTAUDIT:
1306 avtab_key.specified = AVTAB_AUDITDENY;
1307 break;
1308 default:
1309 rc = SEPOL_ERR;
1310 goto exit;
1311 break;
1312 }
1313
1314 if (!cond_node) {
1315 avtab_dup = avtab_search(&pdb->te_avtab, &avtab_key);
1316 if (!avtab_dup) {
1317 avtab_datum.data = data;
1318 rc = avtab_insert(&pdb->te_avtab, &avtab_key, &avtab_datum);
1319 } else {
1320 if (kind == CIL_AVRULE_DONTAUDIT)
1321 avtab_dup->data &= data;
1322 else
1323 avtab_dup->data |= data;
1324 }
1325 } else {
1326 avtab_datum.data = data;
1327 rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, &avtab_key, &avtab_datum, cond_node, cond_flavor);
1328 }
1329
1330 exit:
1331 return rc;
1332 }
1333
__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)1334 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)
1335 {
1336 int rc = SEPOL_ERR;
1337 type_datum_t *sepol_src = NULL;
1338 type_datum_t *sepol_tgt = NULL;
1339 class_datum_t *sepol_class = NULL;
1340 uint32_t data = 0;
1341
1342 rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class);
1343 if (rc != SEPOL_OK) goto exit;
1344
1345 rc = __cil_perms_to_datum(cp->perms, sepol_class, &data);
1346 if (rc != SEPOL_OK) goto exit;
1347
1348 if (data == 0) {
1349 /* No permissions, so don't insert rule. Maybe should return an error? */
1350 return SEPOL_OK;
1351 }
1352
1353 if (kind == CIL_AVRULE_DONTAUDIT) {
1354 data = ~data;
1355 }
1356
1357 rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src);
1358 if (rc != SEPOL_OK) goto exit;
1359
1360 rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt);
1361 if (rc != SEPOL_OK) goto exit;
1362
1363 rc = __cil_insert_avrule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_class->s.value, data, cond_node, cond_flavor);
1364 if (rc != SEPOL_OK) {
1365 goto exit;
1366 }
1367
1368 return SEPOL_OK;
1369
1370 exit:
1371 return rc;
1372 }
1373
1374
__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)1375 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)
1376 {
1377 int rc = SEPOL_ERR;
1378 struct cil_list_item *curr;
1379
1380 cil_list_for_each(curr, classperms) {
1381 if (curr->flavor == CIL_CLASSPERMS) {
1382 struct cil_classperms *cp = curr->data;
1383 if (FLAVOR(cp->class) == CIL_CLASS) {
1384 rc = __cil_avrule_expand_helper(pdb, kind, src, tgt, cp, cond_node, cond_flavor);
1385 if (rc != SEPOL_OK) {
1386 goto exit;
1387 }
1388 } else { /* MAP */
1389 struct cil_list_item *i = NULL;
1390 cil_list_for_each(i, cp->perms) {
1391 struct cil_perm *cmp = i->data;
1392 rc = __cil_avrule_expand(pdb, kind, src, tgt, cmp->classperms, cond_node, cond_flavor);
1393 if (rc != SEPOL_OK) {
1394 goto exit;
1395 }
1396 }
1397 }
1398 } else { /* SET */
1399 struct cil_classperms_set *cp_set = curr->data;
1400 struct cil_classpermission *cp = cp_set->set;
1401 rc = __cil_avrule_expand(pdb, kind, src, tgt, cp->classperms, cond_node, cond_flavor);
1402 if (rc != SEPOL_OK) {
1403 goto exit;
1404 }
1405 }
1406 }
1407
1408 return SEPOL_OK;
1409
1410 exit:
1411 return rc;
1412 }
1413
__cil_should_expand_attribute(const struct cil_db * db,struct cil_symtab_datum * datum)1414 static int __cil_should_expand_attribute( const struct cil_db *db, struct cil_symtab_datum *datum)
1415 {
1416 struct cil_tree_node *node;
1417 struct cil_typeattribute *attr;
1418
1419 node = NODE(datum);
1420
1421 if (node->flavor != CIL_TYPEATTRIBUTE) {
1422 return CIL_FALSE;
1423 }
1424
1425 attr = (struct cil_typeattribute *)datum;
1426
1427 return !attr->used || (ebitmap_cardinality(attr->types) < db->attrs_expand_size);
1428 }
1429
__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)1430 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)
1431 {
1432 int rc = SEPOL_ERR;
1433 uint16_t kind = cil_avrule->rule_kind;
1434 struct cil_symtab_datum *src = NULL;
1435 struct cil_symtab_datum *tgt = NULL;
1436 struct cil_list *classperms = cil_avrule->perms.classperms;
1437 ebitmap_t src_bitmap, tgt_bitmap;
1438 ebitmap_node_t *snode, *tnode;
1439 unsigned int s,t;
1440
1441 if (cil_avrule->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) {
1442 // Do not add dontaudit rules to binary
1443 rc = SEPOL_OK;
1444 goto exit;
1445 }
1446
1447 src = cil_avrule->src;
1448 tgt = cil_avrule->tgt;
1449
1450 if (tgt->fqn == CIL_KEY_SELF) {
1451 rc = __cil_expand_type(src, &src_bitmap);
1452 if (rc != SEPOL_OK) {
1453 goto exit;
1454 }
1455
1456 ebitmap_for_each_bit(&src_bitmap, snode, s) {
1457 if (!ebitmap_get_bit(&src_bitmap, s)) continue;
1458
1459 src = DATUM(db->val_to_type[s]);
1460 rc = __cil_avrule_expand(pdb, kind, src, src, classperms, cond_node, cond_flavor);
1461 if (rc != SEPOL_OK) {
1462 ebitmap_destroy(&src_bitmap);
1463 goto exit;
1464 }
1465 }
1466 ebitmap_destroy(&src_bitmap);
1467 } else {
1468 int expand_src = __cil_should_expand_attribute(db, src);
1469 int expand_tgt = __cil_should_expand_attribute(db, tgt);
1470 if (!expand_src && !expand_tgt) {
1471 rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor);
1472 if (rc != SEPOL_OK) {
1473 goto exit;
1474 }
1475 } else if (expand_src && expand_tgt) {
1476 rc = __cil_expand_type(src, &src_bitmap);
1477 if (rc != SEPOL_OK) {
1478 goto exit;
1479 }
1480
1481 rc = __cil_expand_type(tgt, &tgt_bitmap);
1482 if (rc != SEPOL_OK) {
1483 ebitmap_destroy(&src_bitmap);
1484 goto exit;
1485 }
1486
1487 ebitmap_for_each_bit(&src_bitmap, snode, s) {
1488 if (!ebitmap_get_bit(&src_bitmap, s)) continue;
1489 src = DATUM(db->val_to_type[s]);
1490 ebitmap_for_each_bit(&tgt_bitmap, tnode, t) {
1491 if (!ebitmap_get_bit(&tgt_bitmap, t)) continue;
1492 tgt = DATUM(db->val_to_type[t]);
1493
1494 rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor);
1495 if (rc != SEPOL_OK) {
1496 ebitmap_destroy(&src_bitmap);
1497 ebitmap_destroy(&tgt_bitmap);
1498 goto exit;
1499 }
1500 }
1501 }
1502 ebitmap_destroy(&src_bitmap);
1503 ebitmap_destroy(&tgt_bitmap);
1504 } else if (expand_src) {
1505 rc = __cil_expand_type(src, &src_bitmap);
1506 if (rc != SEPOL_OK) {
1507 goto exit;
1508 }
1509
1510 ebitmap_for_each_bit(&src_bitmap, snode, s) {
1511 if (!ebitmap_get_bit(&src_bitmap, s)) continue;
1512 src = DATUM(db->val_to_type[s]);
1513
1514 rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor);
1515 if (rc != SEPOL_OK) {
1516 ebitmap_destroy(&src_bitmap);
1517 goto exit;
1518 }
1519 }
1520 ebitmap_destroy(&src_bitmap);
1521 } else { /* expand_tgt */
1522 rc = __cil_expand_type(tgt, &tgt_bitmap);
1523 if (rc != SEPOL_OK) {
1524 goto exit;
1525 }
1526
1527 ebitmap_for_each_bit(&tgt_bitmap, tnode, t) {
1528 if (!ebitmap_get_bit(&tgt_bitmap, t)) continue;
1529 tgt = DATUM(db->val_to_type[t]);
1530
1531 rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor);
1532 if (rc != SEPOL_OK) {
1533 ebitmap_destroy(&tgt_bitmap);
1534 goto exit;
1535 }
1536 }
1537 ebitmap_destroy(&tgt_bitmap);
1538 }
1539 }
1540
1541 return SEPOL_OK;
1542
1543 exit:
1544 return rc;
1545 }
1546
cil_avrule_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_avrule * cil_avrule)1547 int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule)
1548 {
1549 return __cil_avrule_to_avtab(pdb, db, cil_avrule, NULL, CIL_FALSE);
1550 }
1551
1552 // Copied from checkpolicy/policy_define.c
1553
1554 /* index of the u32 containing the permission */
1555 #define XPERM_IDX(x) (x >> 5)
1556 /* set bits 0 through x-1 within the u32 */
1557 #define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)
1558 /* low value for this u32 */
1559 #define XPERM_LOW(x) (x << 5)
1560 /* high value for this u32 */
1561 #define XPERM_HIGH(x) (((x + 1) << 5) - 1)
__avrule_xperm_setrangebits(uint16_t low,uint16_t high,struct avtab_extended_perms * xperms)1562 void __avrule_xperm_setrangebits(uint16_t low, uint16_t high, struct avtab_extended_perms *xperms)
1563 {
1564 unsigned int i;
1565 uint16_t h = high + 1;
1566 /* for each u32 that this low-high range touches, set driver permissions */
1567 for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) {
1568 /* set all bits in u32 */
1569 if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
1570 xperms->perms[i] |= ~0U;
1571 /* set low bits */
1572 else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i)))
1573 xperms->perms[i] |= XPERM_SETBITS(h);
1574 /* set high bits */
1575 else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
1576 xperms->perms[i] |= ~0U - XPERM_SETBITS(low);
1577 /* set middle bits */
1578 else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i)))
1579 xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low);
1580 }
1581 }
1582
1583
1584 #define IOC_DRIV(x) (x >> 8)
1585 #define IOC_FUNC(x) (x & 0xff)
1586
__cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t * xperms,struct cil_list ** xperms_list)1587 int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil_list **xperms_list)
1588 {
1589 ebitmap_node_t *node;
1590 unsigned int i;
1591 uint16_t low = 0, high = 0;
1592 struct avtab_extended_perms *partial = NULL;
1593 struct avtab_extended_perms *complete = NULL;
1594 int start_new_range;
1595
1596 cil_list_init(xperms_list, CIL_NONE);
1597
1598 start_new_range = 1;
1599
1600 ebitmap_for_each_bit(xperms, node, i) {
1601 if (!ebitmap_get_bit(xperms, i)) continue;
1602
1603 if (start_new_range) {
1604 low = i;
1605 start_new_range = 0;
1606 }
1607
1608 // continue if the current bit isn't the end of the driver function or the next bit is set
1609 if (IOC_FUNC(i) != 0xff && ebitmap_get_bit(xperms, i + 1)) {
1610 continue;
1611 }
1612
1613 // if we got here, i is the end of this range (either becuase the func
1614 // is 0xff or the next bit isn't set). The next time around we are
1615 // going to need a start a new range
1616 high = i;
1617 start_new_range = 1;
1618
1619 if (IOC_FUNC(low) == 0x00 && IOC_FUNC(high) == 0xff) {
1620 if (!complete) {
1621 complete = cil_calloc(1, sizeof(*complete));
1622 complete->driver = 0x0;
1623 complete->specified = AVTAB_XPERMS_IOCTLDRIVER;
1624 }
1625
1626 __avrule_xperm_setrangebits(IOC_DRIV(low), IOC_DRIV(low), complete);
1627 } else {
1628 if (partial && partial->driver != IOC_DRIV(low)) {
1629 cil_list_append(*xperms_list, CIL_NONE, partial);
1630 partial = NULL;
1631 }
1632
1633 if (!partial) {
1634 partial = cil_calloc(1, sizeof(*partial));
1635 partial->driver = IOC_DRIV(low);
1636 partial->specified = AVTAB_XPERMS_IOCTLFUNCTION;
1637 }
1638
1639 __avrule_xperm_setrangebits(IOC_FUNC(low), IOC_FUNC(high), partial);
1640 }
1641 }
1642
1643 if (partial) {
1644 cil_list_append(*xperms_list, CIL_NONE, partial);
1645 }
1646
1647 if (complete) {
1648 cil_list_append(*xperms_list, CIL_NONE, complete);
1649 }
1650
1651 return SEPOL_OK;
1652 }
1653
__cil_avrulex_ioctl_to_policydb(hashtab_key_t k,hashtab_datum_t datum,void * args)1654 int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args)
1655 {
1656 int rc = SEPOL_OK;
1657 struct policydb *pdb;
1658 avtab_key_t *avtab_key;
1659 avtab_datum_t avtab_datum;
1660 struct cil_list *xperms_list = NULL;
1661 struct cil_list_item *item;
1662 class_datum_t *sepol_obj;
1663 uint32_t data = 0;
1664
1665 avtab_key = (avtab_key_t *)k;
1666 pdb = args;
1667
1668 sepol_obj = pdb->class_val_to_struct[avtab_key->target_class - 1];
1669
1670 // setting the data for an extended avtab isn't really neccessary because
1671 // it is ignored by the kernel. However, neverallow checking requires that
1672 // the data value be set, so set it for that to work.
1673 rc = __perm_str_to_datum(CIL_KEY_IOCTL, sepol_obj, &data);
1674 if (rc != SEPOL_OK) {
1675 goto exit;
1676 }
1677 avtab_datum.data = data;
1678
1679 rc = __cil_permx_bitmap_to_sepol_xperms_list(datum, &xperms_list);
1680 if (rc != SEPOL_OK) {
1681 goto exit;
1682 }
1683
1684 cil_list_for_each(item, xperms_list) {
1685 avtab_datum.xperms = item->data;
1686 rc = avtab_insert(&pdb->te_avtab, avtab_key, &avtab_datum);
1687 if (rc != SEPOL_OK) {
1688 goto exit;
1689 }
1690 }
1691
1692 rc = SEPOL_OK;
1693
1694 exit:
1695 if (xperms_list != NULL) {
1696 cil_list_for_each(item, xperms_list) {
1697 free(item->data);
1698 }
1699 cil_list_destroy(&xperms_list, CIL_FALSE);
1700 }
1701
1702 // hashtab_t does not have a way to free keys or datum since it doesn't
1703 // know what they are. We won't need the keys/datum after this function, so
1704 // clean them up here.
1705 free(avtab_key);
1706 ebitmap_destroy(datum);
1707 free(datum);
1708
1709 return rc;
1710 }
1711
__cil_avrulex_ioctl_to_hashtable(hashtab_t h,uint16_t kind,uint32_t src,uint32_t tgt,uint32_t obj,ebitmap_t * xperms)1712 int __cil_avrulex_ioctl_to_hashtable(hashtab_t h, uint16_t kind, uint32_t src, uint32_t tgt, uint32_t obj, ebitmap_t *xperms)
1713 {
1714 uint16_t specified;
1715 avtab_key_t *avtab_key;
1716 ebitmap_t *hashtab_xperms;
1717 int rc = SEPOL_ERR;
1718
1719 switch (kind) {
1720 case CIL_AVRULE_ALLOWED:
1721 specified = AVTAB_XPERMS_ALLOWED;
1722 break;
1723 case CIL_AVRULE_AUDITALLOW:
1724 specified = AVTAB_XPERMS_AUDITALLOW;
1725 break;
1726 case CIL_AVRULE_DONTAUDIT:
1727 specified = AVTAB_XPERMS_DONTAUDIT;
1728 break;
1729 default:
1730 rc = SEPOL_ERR;
1731 goto exit;
1732 }
1733
1734 avtab_key = cil_malloc(sizeof(*avtab_key));
1735 avtab_key->source_type = src;
1736 avtab_key->target_type = tgt;
1737 avtab_key->target_class = obj;
1738 avtab_key->specified = specified;
1739
1740 hashtab_xperms = (ebitmap_t *)hashtab_search(h, (hashtab_key_t)avtab_key);
1741 if (!hashtab_xperms) {
1742 hashtab_xperms = cil_malloc(sizeof(*hashtab_xperms));
1743 rc = ebitmap_cpy(hashtab_xperms, xperms);
1744 if (rc != SEPOL_OK) {
1745 free(avtab_key);
1746 goto exit;
1747 }
1748 rc = hashtab_insert(h, (hashtab_key_t)avtab_key, hashtab_xperms);
1749 if (rc != SEPOL_OK) {
1750 free(avtab_key);
1751 goto exit;
1752 }
1753 } else {
1754 free(avtab_key);
1755 rc = ebitmap_union(hashtab_xperms, xperms);
1756 if (rc != SEPOL_OK) {
1757 goto exit;
1758 }
1759 }
1760
1761 return SEPOL_OK;
1762
1763 exit:
1764 return rc;
1765 }
1766
__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)1767 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)
1768 {
1769 int rc = SEPOL_ERR;
1770 type_datum_t *sepol_src = NULL;
1771 type_datum_t *sepol_tgt = NULL;
1772 class_datum_t *sepol_obj = NULL;
1773 struct cil_list *class_list = NULL;
1774 struct cil_list_item *c;
1775
1776 rc = __cil_get_sepol_type_datum(pdb, src, &sepol_src);
1777 if (rc != SEPOL_OK) goto exit;
1778
1779 rc = __cil_get_sepol_type_datum(pdb, tgt, &sepol_tgt);
1780 if (rc != SEPOL_OK) goto exit;
1781
1782 class_list = cil_expand_class(permx->obj);
1783
1784 cil_list_for_each(c, class_list) {
1785 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
1786 if (rc != SEPOL_OK) goto exit;
1787
1788 switch (permx->kind) {
1789 case CIL_PERMX_KIND_IOCTL:
1790 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);
1791 if (rc != SEPOL_OK) goto exit;
1792 break;
1793 default:
1794 rc = SEPOL_ERR;
1795 goto exit;
1796 }
1797 }
1798
1799 rc = SEPOL_OK;
1800
1801 exit:
1802 cil_list_destroy(&class_list, CIL_FALSE);
1803
1804 return rc;
1805 }
1806
cil_avrulex_to_hashtable(policydb_t * pdb,const struct cil_db * db,struct cil_avrule * cil_avrulex,struct cil_args_binary * args)1807 int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrulex, struct cil_args_binary *args)
1808 {
1809 int rc = SEPOL_ERR;
1810 uint16_t kind;
1811 struct cil_symtab_datum *src = NULL;
1812 struct cil_symtab_datum *tgt = NULL;
1813 ebitmap_t src_bitmap, tgt_bitmap;
1814 ebitmap_node_t *snode, *tnode;
1815 unsigned int s,t;
1816
1817 if (cil_avrulex->rule_kind == CIL_AVRULE_DONTAUDIT && db->disable_dontaudit == CIL_TRUE) {
1818 // Do not add dontaudit rules to binary
1819 rc = SEPOL_OK;
1820 goto exit;
1821 }
1822
1823 kind = cil_avrulex->rule_kind;
1824 src = cil_avrulex->src;
1825 tgt = cil_avrulex->tgt;
1826
1827 if (tgt->fqn == CIL_KEY_SELF) {
1828 rc = __cil_expand_type(src, &src_bitmap);
1829 if (rc != SEPOL_OK) goto exit;
1830
1831 ebitmap_for_each_bit(&src_bitmap, snode, s) {
1832 if (!ebitmap_get_bit(&src_bitmap, s)) continue;
1833
1834 src = DATUM(db->val_to_type[s]);
1835 rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, src, cil_avrulex->perms.x.permx, args);
1836 if (rc != SEPOL_OK) {
1837 goto exit;
1838 }
1839 }
1840 ebitmap_destroy(&src_bitmap);
1841 } else {
1842 int expand_src = __cil_should_expand_attribute(db, src);
1843 int expand_tgt = __cil_should_expand_attribute(db, tgt);
1844
1845 if (!expand_src && !expand_tgt) {
1846 rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args);
1847 if (rc != SEPOL_OK) {
1848 goto exit;
1849 }
1850 } else if (expand_src && expand_tgt) {
1851 rc = __cil_expand_type(src, &src_bitmap);
1852 if (rc != SEPOL_OK) {
1853 goto exit;
1854 }
1855
1856 rc = __cil_expand_type(tgt, &tgt_bitmap);
1857 if (rc != SEPOL_OK) {
1858 ebitmap_destroy(&src_bitmap);
1859 goto exit;
1860 }
1861
1862 ebitmap_for_each_bit(&src_bitmap, snode, s) {
1863 if (!ebitmap_get_bit(&src_bitmap, s)) continue;
1864 src = DATUM(db->val_to_type[s]);
1865 ebitmap_for_each_bit(&tgt_bitmap, tnode, t) {
1866 if (!ebitmap_get_bit(&tgt_bitmap, t)) continue;
1867 tgt = DATUM(db->val_to_type[t]);
1868
1869 rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args);
1870 if (rc != SEPOL_OK) {
1871 ebitmap_destroy(&src_bitmap);
1872 ebitmap_destroy(&tgt_bitmap);
1873 goto exit;
1874 }
1875 }
1876 }
1877 ebitmap_destroy(&src_bitmap);
1878 ebitmap_destroy(&tgt_bitmap);
1879 } else if (expand_src) {
1880 rc = __cil_expand_type(src, &src_bitmap);
1881 if (rc != SEPOL_OK) {
1882 goto exit;
1883 }
1884
1885 ebitmap_for_each_bit(&src_bitmap, snode, s) {
1886 if (!ebitmap_get_bit(&src_bitmap, s)) continue;
1887 src = DATUM(db->val_to_type[s]);
1888
1889 rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args);
1890 if (rc != SEPOL_OK) {
1891 ebitmap_destroy(&src_bitmap);
1892 goto exit;
1893 }
1894 }
1895 ebitmap_destroy(&src_bitmap);
1896 } else { /* expand_tgt */
1897 rc = __cil_expand_type(tgt, &tgt_bitmap);
1898 if (rc != SEPOL_OK) {
1899 goto exit;
1900 }
1901
1902 ebitmap_for_each_bit(&tgt_bitmap, tnode, t) {
1903 if (!ebitmap_get_bit(&tgt_bitmap, t)) continue;
1904 tgt = DATUM(db->val_to_type[t]);
1905
1906 rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args);
1907 if (rc != SEPOL_OK) {
1908 ebitmap_destroy(&tgt_bitmap);
1909 goto exit;
1910 }
1911 }
1912 ebitmap_destroy(&tgt_bitmap);
1913 }
1914 }
1915
1916 return SEPOL_OK;
1917
1918 exit:
1919 return rc;
1920 }
1921
__cil_cond_to_policydb_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1922 int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
1923 {
1924 int rc;
1925 enum cil_flavor flavor;
1926 struct cil_args_booleanif *args = extra_args;
1927 const struct cil_db *db = args->db;
1928 policydb_t *pdb = args->pdb;
1929 cond_node_t *cond_node = args->cond_node;
1930 enum cil_flavor cond_flavor = args->cond_flavor;
1931 struct cil_type_rule *cil_type_rule;
1932 struct cil_avrule *cil_avrule;
1933 struct cil_nametypetransition *cil_typetrans;
1934 hashtab_t filename_trans_table = args->filename_trans_table;
1935
1936 flavor = node->flavor;
1937 switch (flavor) {
1938 case CIL_NAMETYPETRANSITION:
1939 cil_typetrans = (struct cil_nametypetransition*)node->data;
1940 if (DATUM(cil_typetrans->name)->fqn != CIL_KEY_STAR) {
1941 cil_log(CIL_ERR, "typetransition with file name not allowed within a booleanif block.\n");
1942 cil_tree_log(node, CIL_ERR,"Invalid typetransition statement");
1943 goto exit;
1944 }
1945 rc = __cil_typetransition_to_avtab(pdb, db, cil_typetrans, cond_node, cond_flavor, filename_trans_table);
1946 if (rc != SEPOL_OK) {
1947 cil_tree_log(node, CIL_ERR, "Failed to insert type transition into avtab");
1948 goto exit;
1949 }
1950 break;
1951 case CIL_TYPE_RULE:
1952 cil_type_rule = node->data;
1953 rc = __cil_type_rule_to_avtab(pdb, db, cil_type_rule, cond_node, cond_flavor);
1954 if (rc != SEPOL_OK) {
1955 cil_tree_log(node, CIL_ERR, "Failed to insert typerule into avtab");
1956 goto exit;
1957 }
1958 break;
1959 case CIL_AVRULE:
1960 cil_avrule = node->data;
1961 rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, cond_node, cond_flavor);
1962 if (rc != SEPOL_OK) {
1963 cil_tree_log(node, CIL_ERR, "Failed to insert avrule into avtab");
1964 goto exit;
1965 }
1966 break;
1967 case CIL_CALL:
1968 case CIL_TUNABLEIF:
1969 break;
1970 default:
1971 cil_tree_log(node, CIL_ERR, "Invalid statement within booleanif");
1972 goto exit;
1973 }
1974
1975 return SEPOL_OK;
1976
1977 exit:
1978 return SEPOL_ERR;
1979 }
1980
1981 static void __cil_expr_to_string(struct cil_list *expr, enum cil_flavor flavor, char **out);
1982
__cil_expr_to_string_helper(struct cil_list_item * curr,enum cil_flavor flavor,char ** out)1983 static void __cil_expr_to_string_helper(struct cil_list_item *curr, enum cil_flavor flavor, char **out)
1984 {
1985 char *c;
1986
1987 if (curr->flavor == CIL_DATUM) {
1988 *out = cil_strdup(DATUM(curr->data)->fqn);
1989 } else if (curr->flavor == CIL_LIST) {
1990 __cil_expr_to_string(curr->data, flavor, &c);
1991 cil_asprintf(out, "(%s)", c);
1992 free(c);
1993 } else if (flavor == CIL_PERMISSIONX) {
1994 // permissionx expressions aren't resolved into anything, so curr->flavor
1995 // is just a CIL_STRING, not a CIL_DATUM, so just check on flavor for those
1996 *out = cil_strdup(curr->data);
1997 }
1998 }
1999
__cil_expr_to_string(struct cil_list * expr,enum cil_flavor flavor,char ** out)2000 static void __cil_expr_to_string(struct cil_list *expr, enum cil_flavor flavor, char **out)
2001 {
2002 struct cil_list_item *curr;
2003 char *s1 = NULL;
2004 char *s2 = NULL;
2005 enum cil_flavor op;
2006
2007 if (expr == NULL || expr->head == NULL) {
2008 *out = cil_strdup("");
2009 return;
2010 }
2011
2012 curr = expr->head;
2013
2014 if (curr->flavor == CIL_OP) {
2015 op = (enum cil_flavor)curr->data;
2016
2017 if (op == CIL_ALL) {
2018 *out = cil_strdup(CIL_KEY_ALL);
2019 } else if (op == CIL_RANGE) {
2020 __cil_expr_to_string_helper(curr->next, flavor, &s1);
2021 __cil_expr_to_string_helper(curr->next->next, flavor, &s2);
2022 cil_asprintf(out, "%s %s %s", CIL_KEY_RANGE, s1, s2);
2023 free(s1);
2024 free(s2);
2025 } else {
2026 __cil_expr_to_string_helper(curr->next, flavor, &s1);
2027
2028 if (op == CIL_NOT) {
2029 cil_asprintf(out, "%s %s", CIL_KEY_NOT, s1);
2030 free(s1);
2031 } else {
2032 const char *opstr = "";
2033
2034 __cil_expr_to_string_helper(curr->next->next, flavor, &s2);
2035
2036 if (op == CIL_OR) {
2037 opstr = CIL_KEY_OR;
2038 } else if (op == CIL_AND) {
2039 opstr = CIL_KEY_AND;
2040 } else if (op == CIL_XOR) {
2041 opstr = CIL_KEY_XOR;
2042 }
2043
2044 cil_asprintf(out, "%s %s %s", opstr, s1, s2);
2045 free(s1);
2046 free(s2);
2047 }
2048 }
2049 } else {
2050 char *c1 = NULL;
2051 char *c2 = NULL;
2052 __cil_expr_to_string_helper(curr, flavor, &c1);
2053 for (curr = curr->next; curr; curr = curr->next) {
2054 __cil_expr_to_string_helper(curr, flavor, &s1);
2055 cil_asprintf(&c2, "%s %s", c1, s1);
2056 free(c1);
2057 free(s1);
2058 c1 = c2;
2059 }
2060 *out = c1;
2061 }
2062 }
2063
2064 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);
2065
__cil_cond_item_to_sepol_expr(policydb_t * pdb,struct cil_list_item * item,cond_expr_t ** head,cond_expr_t ** tail)2066 static int __cil_cond_item_to_sepol_expr(policydb_t *pdb, struct cil_list_item *item, cond_expr_t **head, cond_expr_t **tail)
2067 {
2068 if (item == NULL) {
2069 goto exit;
2070 } else if (item->flavor == CIL_DATUM) {
2071 char *key = DATUM(item->data)->fqn;
2072 cond_bool_datum_t *sepol_bool = hashtab_search(pdb->p_bools.table, key);
2073 if (sepol_bool == NULL) {
2074 cil_log(CIL_INFO, "Failed to find boolean\n");
2075 goto exit;
2076 }
2077 *head = cil_malloc(sizeof(cond_expr_t));
2078 (*head)->next = NULL;
2079 (*head)->expr_type = COND_BOOL;
2080 (*head)->bool = sepol_bool->s.value;
2081 *tail = *head;
2082 } else if (item->flavor == CIL_LIST) {
2083 struct cil_list *l = item->data;
2084 int rc = __cil_cond_expr_to_sepol_expr_helper(pdb, l, head, tail);
2085 if (rc != SEPOL_OK) {
2086 goto exit;
2087 }
2088 } else {
2089 goto exit;
2090 }
2091
2092 return SEPOL_OK;
2093
2094 exit:
2095 return SEPOL_ERR;
2096 }
2097
__cil_cond_expr_to_sepol_expr_helper(policydb_t * pdb,struct cil_list * cil_expr,cond_expr_t ** head,cond_expr_t ** tail)2098 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)
2099 {
2100 int rc = SEPOL_ERR;
2101 struct cil_list_item *item = cil_expr->head;
2102 enum cil_flavor flavor = cil_expr->flavor;
2103 cond_expr_t *op, *h1, *h2, *t1, *t2;
2104
2105 if (flavor != CIL_BOOL) {
2106 cil_log(CIL_INFO, "Expected boolean expression\n");
2107 goto exit;
2108 }
2109
2110 if (item == NULL) {
2111 goto exit;
2112 } else if (item->flavor == CIL_OP) {
2113 enum cil_flavor cil_op = (enum cil_flavor)item->data;
2114
2115 op = cil_malloc(sizeof(*op));
2116 op->bool = 0;
2117 op->next = NULL;
2118
2119 switch (cil_op) {
2120 case CIL_NOT:
2121 op->expr_type = COND_NOT;
2122 break;
2123 case CIL_OR:
2124 op->expr_type = COND_OR;
2125 break;
2126 case CIL_AND:
2127 op->expr_type = COND_AND;
2128 break;
2129 case CIL_XOR:
2130 op->expr_type = COND_XOR;
2131 break;
2132 case CIL_EQ:
2133 op->expr_type = COND_EQ;
2134 break;
2135 case CIL_NEQ:
2136 op->expr_type = COND_NEQ;
2137 break;
2138 default:
2139 goto exit;
2140 }
2141
2142 rc = __cil_cond_item_to_sepol_expr(pdb, item->next, &h1, &t1);
2143 if (rc != SEPOL_OK) {
2144 cil_log(CIL_INFO, "Failed to get first operand of conditional expression\n");
2145 free(op);
2146 goto exit;
2147 }
2148
2149 if (cil_op == CIL_NOT) {
2150 *head = h1;
2151 t1->next = op;
2152 *tail = op;
2153 } else {
2154 rc = __cil_cond_item_to_sepol_expr(pdb, item->next->next, &h2, &t2);
2155 if (rc != SEPOL_OK) {
2156 cil_log(CIL_INFO, "Failed to get second operand of conditional expression\n");
2157 free(op);
2158 cond_expr_destroy(h1);
2159 goto exit;
2160 }
2161
2162 *head = h1;
2163 t1->next = h2;
2164 t2->next = op;
2165 *tail = op;
2166 }
2167 } else {
2168 rc = __cil_cond_item_to_sepol_expr(pdb, item, &h1, &t1);
2169 if (rc != SEPOL_OK) {
2170 cil_log(CIL_INFO, "Failed to get initial item in conditional list\n");
2171 goto exit;
2172 }
2173 *head = h1;
2174 for (item = item->next; item; item = item->next) {
2175 rc = __cil_cond_item_to_sepol_expr(pdb, item, &h2, &t2);
2176 if (rc != SEPOL_OK) {
2177 cil_log(CIL_INFO, "Failed to get item in conditional list\n");
2178 cond_expr_destroy(*head);
2179 goto exit;
2180 }
2181 op = cil_malloc(sizeof(*op));
2182 op->bool = 0;
2183 op->next = NULL;
2184 op->expr_type = COND_OR;
2185 t1->next = h2;
2186 t2->next = op;
2187 t1 = op;
2188 }
2189 *tail = t1;
2190 }
2191
2192 return SEPOL_OK;
2193
2194 exit:
2195 return SEPOL_ERR;
2196 }
2197
__cil_cond_expr_to_sepol_expr(policydb_t * pdb,struct cil_list * cil_expr,cond_expr_t ** sepol_expr)2198 static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_expr, cond_expr_t **sepol_expr)
2199 {
2200 int rc;
2201 cond_expr_t *head, *tail;
2202
2203 rc = __cil_cond_expr_to_sepol_expr_helper(pdb, cil_expr, &head, &tail);
2204 if (rc != SEPOL_OK) {
2205 return SEPOL_ERR;
2206 }
2207 *sepol_expr = head;
2208
2209 return SEPOL_OK;
2210 }
2211
cil_booleanif_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_tree_node * node,hashtab_t filename_trans_table)2212 int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, hashtab_t filename_trans_table)
2213 {
2214 int rc = SEPOL_ERR;
2215 struct cil_args_booleanif bool_args;
2216 struct cil_booleanif *cil_boolif = (struct cil_booleanif*)node->data;
2217 struct cil_tree_node *cb_node = node->cl_head;
2218 struct cil_tree_node *true_node = NULL;
2219 struct cil_tree_node *false_node = NULL;
2220 struct cil_tree_node *tmp_node = NULL;
2221 cond_node_t *tmp_cond = NULL;
2222 cond_node_t *cond_node = NULL;
2223 int was_created;
2224 int swapped = CIL_FALSE;
2225 cond_av_list_t tmp_cl;
2226
2227 tmp_cond = cond_node_create(pdb, NULL);
2228 if (tmp_cond == NULL) {
2229 rc = SEPOL_ERR;
2230 cil_tree_log(node, CIL_INFO, "Failed to create sepol conditional node");
2231 goto exit;
2232 }
2233
2234 rc = __cil_cond_expr_to_sepol_expr(pdb, cil_boolif->datum_expr, &tmp_cond->expr);
2235 if (rc != SEPOL_OK) {
2236 cil_tree_log(node, CIL_INFO, "Failed to convert CIL conditional expression to sepol expression");
2237 goto exit;
2238 }
2239
2240 tmp_cond->true_list = &tmp_cl;
2241
2242 rc = cond_normalize_expr(pdb, tmp_cond);
2243 if (rc != SEPOL_OK) {
2244 goto exit;
2245 }
2246
2247 if (tmp_cond->false_list != NULL) {
2248 tmp_cond->true_list = NULL;
2249 swapped = CIL_TRUE;
2250 }
2251
2252 cond_node = cond_node_find(pdb, tmp_cond, pdb->cond_list, &was_created);
2253 if (cond_node == NULL) {
2254 rc = SEPOL_ERR;
2255 goto exit;
2256 }
2257
2258 if (was_created) {
2259 cond_node->next = pdb->cond_list;
2260 pdb->cond_list = cond_node;
2261 }
2262
2263 cond_expr_destroy(tmp_cond->expr);
2264 free(tmp_cond);
2265
2266 for (cb_node = node->cl_head; cb_node != NULL; cb_node = cb_node->next) {
2267 if (cb_node->flavor == CIL_CONDBLOCK) {
2268 struct cil_condblock *cb = cb_node->data;
2269 if (cb->flavor == CIL_CONDTRUE) {
2270 true_node = cb_node;
2271 } else if (cb->flavor == CIL_CONDFALSE) {
2272 false_node = cb_node;
2273 }
2274 }
2275 }
2276
2277 if (swapped) {
2278 tmp_node = true_node;
2279 true_node = false_node;
2280 false_node = tmp_node;
2281 }
2282
2283 bool_args.db = db;
2284 bool_args.pdb = pdb;
2285 bool_args.cond_node = cond_node;
2286 bool_args.filename_trans_table = filename_trans_table;
2287
2288 if (true_node != NULL) {
2289 bool_args.cond_flavor = CIL_CONDTRUE;
2290 rc = cil_tree_walk(true_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args);
2291 if (rc != SEPOL_OK) {
2292 cil_tree_log(true_node, CIL_ERR, "Failure while walking true conditional block");
2293 goto exit;
2294 }
2295 }
2296
2297 if (false_node != NULL) {
2298 bool_args.cond_flavor = CIL_CONDFALSE;
2299 rc = cil_tree_walk(false_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args);
2300 if (rc != SEPOL_OK) {
2301 cil_tree_log(false_node, CIL_ERR, "Failure while walking false conditional block");
2302 goto exit;
2303 }
2304 }
2305
2306 return SEPOL_OK;
2307
2308 exit:
2309 return rc;
2310 }
2311
cil_roletrans_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_roletransition * roletrans,hashtab_t role_trans_table)2312 int cil_roletrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roletransition *roletrans, hashtab_t role_trans_table)
2313 {
2314 int rc = SEPOL_ERR;
2315 role_datum_t *sepol_src = NULL;
2316 type_datum_t *sepol_tgt = NULL;
2317 class_datum_t *sepol_obj = NULL;
2318 struct cil_list *class_list;
2319 role_datum_t *sepol_result = NULL;
2320 role_trans_t *new = NULL;
2321 uint32_t *new_role = NULL;
2322 ebitmap_t role_bitmap, type_bitmap;
2323 ebitmap_node_t *rnode, *tnode;
2324 unsigned int i, j;
2325 struct cil_list_item *c;
2326
2327 rc = __cil_expand_role(DATUM(roletrans->src), &role_bitmap);
2328 if (rc != SEPOL_OK) goto exit;
2329
2330 rc = __cil_expand_type(roletrans->tgt, &type_bitmap);
2331 if (rc != SEPOL_OK) goto exit;
2332
2333 class_list = cil_expand_class(roletrans->obj);
2334
2335 rc = __cil_get_sepol_role_datum(pdb, DATUM(roletrans->result), &sepol_result);
2336 if (rc != SEPOL_OK) goto exit;
2337
2338 ebitmap_for_each_bit(&role_bitmap, rnode, i) {
2339 if (!ebitmap_get_bit(&role_bitmap, i)) continue;
2340
2341 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src);
2342 if (rc != SEPOL_OK) goto exit;
2343
2344 ebitmap_for_each_bit(&type_bitmap, tnode, j) {
2345 if (!ebitmap_get_bit(&type_bitmap, j)) continue;
2346
2347 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
2348 if (rc != SEPOL_OK) goto exit;
2349
2350 cil_list_for_each(c, class_list) {
2351 int add = CIL_TRUE;
2352 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
2353 if (rc != SEPOL_OK) goto exit;
2354
2355 new = cil_malloc(sizeof(*new));
2356 memset(new, 0, sizeof(*new));
2357 new->role = sepol_src->s.value;
2358 new->type = sepol_tgt->s.value;
2359 new->tclass = sepol_obj->s.value;
2360 new->new_role = sepol_result->s.value;
2361
2362 rc = hashtab_insert(role_trans_table, (hashtab_key_t)new, &(new->new_role));
2363 if (rc != SEPOL_OK) {
2364 if (rc == SEPOL_EEXIST) {
2365 add = CIL_FALSE;
2366 new_role = hashtab_search(role_trans_table, (hashtab_key_t)new);
2367 if (new->new_role != *new_role) {
2368 cil_log(CIL_ERR, "Conflicting role transition rules\n");
2369 } else {
2370 rc = SEPOL_OK;
2371 }
2372 } else {
2373 cil_log(CIL_ERR, "Out of memory\n");
2374 }
2375 }
2376
2377 if (add == CIL_TRUE) {
2378 new->next = pdb->role_tr;
2379 pdb->role_tr = new;
2380 } else {
2381 free(new);
2382 if (rc != SEPOL_OK) {
2383 goto exit;
2384 }
2385 }
2386 }
2387 }
2388 }
2389
2390 rc = SEPOL_OK;
2391
2392 exit:
2393 ebitmap_destroy(&role_bitmap);
2394 ebitmap_destroy(&type_bitmap);
2395 cil_list_destroy(&class_list, CIL_FALSE);
2396 return rc;
2397 }
2398
cil_roleallow_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_roleallow * roleallow)2399 int cil_roleallow_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_roleallow *roleallow)
2400 {
2401 int rc = SEPOL_ERR;
2402 role_datum_t *sepol_src = NULL;
2403 role_datum_t *sepol_tgt = NULL;
2404 role_allow_t *sepol_roleallow = NULL;
2405 ebitmap_t src_bitmap, tgt_bitmap;
2406 ebitmap_node_t *node1, *node2;
2407 unsigned int i, j;
2408
2409 rc = __cil_expand_role(roleallow->src, &src_bitmap);
2410 if (rc != SEPOL_OK) goto exit;
2411
2412 rc = __cil_expand_role(roleallow->tgt, &tgt_bitmap);
2413 if (rc != SEPOL_OK) goto exit;
2414
2415 ebitmap_for_each_bit(&src_bitmap, node1, i) {
2416 if (!ebitmap_get_bit(&src_bitmap, i)) continue;
2417
2418 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_src);
2419 if (rc != SEPOL_OK) goto exit;
2420
2421 ebitmap_for_each_bit(&tgt_bitmap, node2, j) {
2422 if (!ebitmap_get_bit(&tgt_bitmap, j)) continue;
2423
2424 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[j]), &sepol_tgt);
2425 if (rc != SEPOL_OK) goto exit;
2426
2427 sepol_roleallow = cil_malloc(sizeof(*sepol_roleallow));
2428 memset(sepol_roleallow, 0, sizeof(role_allow_t));
2429 sepol_roleallow->role = sepol_src->s.value;
2430 sepol_roleallow->new_role = sepol_tgt->s.value;
2431
2432 sepol_roleallow->next = pdb->role_allow;
2433 pdb->role_allow = sepol_roleallow;
2434 }
2435 }
2436
2437 rc = SEPOL_OK;
2438
2439 exit:
2440 ebitmap_destroy(&src_bitmap);
2441 ebitmap_destroy(&tgt_bitmap);
2442 return rc;
2443 }
2444
__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)2445 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)
2446 {
2447 int rc = SEPOL_ERR;
2448
2449 if (expr_flavor == CIL_USER) {
2450 user_datum_t *sepol_user = NULL;
2451 ebitmap_t user_bitmap;
2452 ebitmap_node_t *unode;
2453 unsigned int i;
2454
2455 rc = __cil_expand_user(item->data, &user_bitmap);
2456 if (rc != SEPOL_OK) goto exit;
2457
2458 ebitmap_for_each_bit(&user_bitmap, unode, i) {
2459 if (!ebitmap_get_bit(&user_bitmap, i)) {
2460 continue;
2461 }
2462
2463 rc = __cil_get_sepol_user_datum(pdb, DATUM(db->val_to_user[i]), &sepol_user);
2464 if (rc != SEPOL_OK) {
2465 ebitmap_destroy(&user_bitmap);
2466 goto exit;
2467 }
2468
2469 if (ebitmap_set_bit(&expr->names, sepol_user->s.value - 1, 1)) {
2470 ebitmap_destroy(&user_bitmap);
2471 goto exit;
2472 }
2473 }
2474 ebitmap_destroy(&user_bitmap);
2475 } else if (expr_flavor == CIL_ROLE) {
2476 role_datum_t *sepol_role = NULL;
2477 ebitmap_t role_bitmap;
2478 ebitmap_node_t *rnode;
2479 unsigned int i;
2480
2481 rc = __cil_expand_role(item->data, &role_bitmap);
2482 if (rc != SEPOL_OK) goto exit;
2483
2484 ebitmap_for_each_bit(&role_bitmap, rnode, i) {
2485 if (!ebitmap_get_bit(&role_bitmap, i)) continue;
2486
2487 rc = __cil_get_sepol_role_datum(pdb, DATUM(db->val_to_role[i]), &sepol_role);
2488 if (rc != SEPOL_OK) {
2489 ebitmap_destroy(&role_bitmap);
2490 goto exit;
2491 }
2492
2493 if (ebitmap_set_bit(&expr->names, sepol_role->s.value - 1, 1)) {
2494 ebitmap_destroy(&role_bitmap);
2495 goto exit;
2496 }
2497 }
2498 ebitmap_destroy(&role_bitmap);
2499 } else if (expr_flavor == CIL_TYPE) {
2500 type_datum_t *sepol_type = NULL;
2501 ebitmap_t type_bitmap;
2502 ebitmap_node_t *tnode;
2503 unsigned int i;
2504
2505 if (pdb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) {
2506 rc = __cil_get_sepol_type_datum(pdb, item->data, &sepol_type);
2507 if (rc != SEPOL_OK) {
2508 if (FLAVOR(item->data) == CIL_TYPEATTRIBUTE) {
2509 struct cil_typeattribute *attr = item->data;
2510 if (!attr->used) {
2511 rc = 0;
2512 }
2513 }
2514 }
2515
2516 if (sepol_type) {
2517 rc = ebitmap_set_bit(&expr->type_names->types, sepol_type->s.value - 1, 1);
2518 }
2519
2520 if (rc != SEPOL_OK) {
2521 goto exit;
2522 }
2523 }
2524
2525 rc = __cil_expand_type(item->data, &type_bitmap);
2526 if (rc != SEPOL_OK) goto exit;
2527
2528 ebitmap_for_each_bit(&type_bitmap, tnode, i) {
2529 if (!ebitmap_get_bit(&type_bitmap, i)) continue;
2530
2531 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_type);
2532 if (rc != SEPOL_OK) {
2533 ebitmap_destroy(&type_bitmap);
2534 goto exit;
2535 }
2536
2537 if (ebitmap_set_bit(&expr->names, sepol_type->s.value - 1, 1)) {
2538 ebitmap_destroy(&type_bitmap);
2539 goto exit;
2540 }
2541 }
2542 ebitmap_destroy(&type_bitmap);
2543 } else {
2544 goto exit;
2545 }
2546
2547 return SEPOL_OK;
2548
2549 exit:
2550 return SEPOL_ERR;
2551 }
2552
__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)2553 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)
2554 {
2555 int rc = SEPOL_ERR;
2556 struct cil_list_item *l_item = op_item->next;
2557 struct cil_list_item *r_item = op_item->next->next;
2558
2559 enum cil_flavor l_operand = (enum cil_flavor)l_item->data;
2560
2561 switch (l_operand) {
2562 case CIL_CONS_U1:
2563 expr->attr = CEXPR_USER;
2564 break;
2565 case CIL_CONS_U2:
2566 expr->attr = CEXPR_USER | CEXPR_TARGET;
2567 break;
2568 case CIL_CONS_U3:
2569 expr->attr = CEXPR_USER | CEXPR_XTARGET;
2570 break;
2571 case CIL_CONS_R1:
2572 expr->attr = CEXPR_ROLE;
2573 break;
2574 case CIL_CONS_R2:
2575 expr->attr = CEXPR_ROLE | CEXPR_TARGET;
2576 break;
2577 case CIL_CONS_R3:
2578 expr->attr = CEXPR_ROLE | CEXPR_XTARGET;
2579 break;
2580 case CIL_CONS_T1:
2581 expr->attr = CEXPR_TYPE;
2582 break;
2583 case CIL_CONS_T2:
2584 expr->attr = CEXPR_TYPE | CEXPR_TARGET;
2585 break;
2586 case CIL_CONS_T3:
2587 expr->attr = CEXPR_TYPE | CEXPR_XTARGET;
2588 break;
2589 case CIL_CONS_L1: {
2590 enum cil_flavor r_operand = (enum cil_flavor)r_item->data;
2591
2592 if (r_operand == CIL_CONS_L2) {
2593 expr->attr = CEXPR_L1L2;
2594 } else if (r_operand == CIL_CONS_H1) {
2595 expr->attr = CEXPR_L1H1;
2596 } else {
2597 expr->attr = CEXPR_L1H2;
2598 }
2599 break;
2600 }
2601 case CIL_CONS_L2:
2602 expr->attr = CEXPR_L2H2;
2603 break;
2604 case CIL_CONS_H1: {
2605 enum cil_flavor r_operand = (enum cil_flavor)r_item->data;
2606 if (r_operand == CIL_CONS_L2) {
2607 expr->attr = CEXPR_H1L2;
2608 } else {
2609 expr->attr = CEXPR_H1H2;
2610 }
2611 break;
2612 }
2613 default:
2614 goto exit;
2615 break;
2616 }
2617
2618 if (r_item->flavor == CIL_CONS_OPERAND) {
2619 expr->expr_type = CEXPR_ATTR;
2620 } else {
2621 expr->expr_type = CEXPR_NAMES;
2622 if (r_item->flavor == CIL_DATUM) {
2623 rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, r_item, expr_flavor, expr);
2624 if (rc != SEPOL_OK) {
2625 goto exit;
2626 }
2627 } else if (r_item->flavor == CIL_LIST) {
2628 struct cil_list *r_expr = r_item->data;
2629 struct cil_list_item *curr;
2630 cil_list_for_each(curr, r_expr) {
2631 rc = __cil_constrain_expr_datum_to_sepol_expr(pdb, db, curr, expr_flavor, expr);
2632 if (rc != SEPOL_OK) {
2633 goto exit;
2634 }
2635 }
2636 } else {
2637 rc = SEPOL_ERR;
2638 goto exit;
2639 }
2640 }
2641
2642 return SEPOL_OK;
2643
2644 exit:
2645 return rc;
2646 }
2647
__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)2648 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)
2649 {
2650 int rc = SEPOL_ERR;
2651 struct cil_list_item *item;
2652 enum cil_flavor flavor;
2653 constraint_expr_t *op, *h1, *h2, *t1, *t2;
2654 int is_leaf = CIL_FALSE;
2655
2656 if (cil_expr == NULL) {
2657 return SEPOL_ERR;
2658 }
2659
2660 item = cil_expr->head;
2661 flavor = cil_expr->flavor;
2662
2663 op = cil_malloc(sizeof(constraint_expr_t));
2664 rc = constraint_expr_init(op);
2665 if (rc != SEPOL_OK) {
2666 goto exit;
2667 }
2668
2669 enum cil_flavor cil_op = (enum cil_flavor)item->data;
2670 switch (cil_op) {
2671 case CIL_NOT:
2672 op->expr_type = CEXPR_NOT;
2673 break;
2674 case CIL_AND:
2675 op->expr_type = CEXPR_AND;
2676 break;
2677 case CIL_OR:
2678 op->expr_type = CEXPR_OR;
2679 break;
2680 case CIL_EQ:
2681 op->op = CEXPR_EQ;
2682 is_leaf = CIL_TRUE;
2683 break;
2684 case CIL_NEQ:
2685 op->op = CEXPR_NEQ;
2686 is_leaf = CIL_TRUE;
2687 break;
2688 case CIL_CONS_DOM:
2689 op->op = CEXPR_DOM;
2690 is_leaf = CIL_TRUE;
2691 break;
2692 case CIL_CONS_DOMBY:
2693 op->op = CEXPR_DOMBY;
2694 is_leaf = CIL_TRUE;
2695 break;
2696 case CIL_CONS_INCOMP:
2697 op->op = CEXPR_INCOMP;
2698 is_leaf = CIL_TRUE;
2699 break;
2700 default:
2701 goto exit;
2702 }
2703
2704 if (is_leaf == CIL_TRUE) {
2705 rc = __cil_constrain_expr_leaf_to_sepol_expr(pdb, db, item, flavor, op);
2706 if (rc != SEPOL_OK) {
2707 goto exit;
2708 }
2709 *head = op;
2710 *tail = op;
2711 } else if (cil_op == CIL_NOT) {
2712 struct cil_list *l_expr = item->next->data;
2713 rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1);
2714 if (rc != SEPOL_OK) {
2715 goto exit;
2716 }
2717 t1->next = op;
2718 *head = h1;
2719 *tail = op;
2720 } else {
2721 struct cil_list *l_expr = item->next->data;
2722 struct cil_list *r_expr = item->next->next->data;
2723 rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, l_expr, &h1, &t1);
2724 if (rc != SEPOL_OK) {
2725 goto exit;
2726 }
2727 rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, r_expr, &h2, &t2);
2728 if (rc != SEPOL_OK) {
2729 constraint_expr_destroy(h1);
2730 goto exit;
2731 }
2732 t1->next = h2;
2733 t2->next = op;
2734 *head = h1;
2735 *tail = op;
2736 }
2737
2738 return SEPOL_OK;
2739
2740 exit:
2741 constraint_expr_destroy(op);
2742 return SEPOL_ERR;
2743 }
2744
__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)2745 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)
2746 {
2747 int rc;
2748 constraint_expr_t *head, *tail;
2749
2750 rc = __cil_constrain_expr_to_sepol_expr_helper(pdb, db, cil_expr, &head, &tail);
2751 if (rc != SEPOL_OK) {
2752 return SEPOL_ERR;
2753 }
2754
2755 *sepol_expr = head;
2756
2757 return SEPOL_OK;
2758 }
2759
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)2760 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)
2761 {
2762 int rc = SEPOL_ERR;
2763 constraint_node_t *sepol_constrain = NULL;
2764 constraint_expr_t *sepol_expr = NULL;
2765 class_datum_t *sepol_class = NULL;
2766
2767 sepol_constrain = cil_malloc(sizeof(*sepol_constrain));
2768 memset(sepol_constrain, 0, sizeof(constraint_node_t));
2769
2770 rc = __cil_get_sepol_class_datum(pdb, class, &sepol_class);
2771 if (rc != SEPOL_OK) goto exit;
2772
2773 rc = __cil_perms_to_datum(perms, sepol_class, &sepol_constrain->permissions);
2774 if (rc != SEPOL_OK) {
2775 goto exit;
2776 }
2777
2778 rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr);
2779 if (rc != SEPOL_OK) {
2780 goto exit;
2781 }
2782
2783 sepol_constrain->expr = sepol_expr;
2784 sepol_constrain->next = sepol_class->constraints;
2785 sepol_class->constraints = sepol_constrain;
2786
2787 return SEPOL_OK;
2788
2789 exit:
2790 free(sepol_constrain);
2791 return rc;
2792 }
2793
cil_constrain_expand(policydb_t * pdb,const struct cil_db * db,struct cil_list * classperms,struct cil_list * expr)2794 int cil_constrain_expand(policydb_t *pdb, const struct cil_db *db, struct cil_list *classperms, struct cil_list *expr)
2795 {
2796 int rc = SEPOL_ERR;
2797 struct cil_list_item *curr;
2798
2799 cil_list_for_each(curr, classperms) {
2800 if (curr->flavor == CIL_CLASSPERMS) {
2801 struct cil_classperms *cp = curr->data;
2802 if (FLAVOR(cp->class) == CIL_CLASS) {
2803 rc = cil_constrain_to_policydb_helper(pdb, db, DATUM(cp->class), cp->perms, expr);
2804 if (rc != SEPOL_OK) {
2805 goto exit;
2806 }
2807 } else { /* MAP */
2808 struct cil_list_item *i = NULL;
2809 cil_list_for_each(i, cp->perms) {
2810 struct cil_perm *cmp = i->data;
2811 rc = cil_constrain_expand(pdb, db, cmp->classperms, expr);
2812 if (rc != SEPOL_OK) {
2813 goto exit;
2814 }
2815 }
2816 }
2817 } else { /* SET */
2818 struct cil_classperms_set *cp_set = curr->data;
2819 struct cil_classpermission *cp = cp_set->set;
2820 rc = cil_constrain_expand(pdb, db, cp->classperms, expr);
2821 if (rc != SEPOL_OK) {
2822 goto exit;
2823 }
2824 }
2825 }
2826
2827 return SEPOL_OK;
2828
2829 exit:
2830 return rc;
2831 }
2832
cil_constrain_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_constrain * cil_constrain)2833 int cil_constrain_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_constrain *cil_constrain)
2834 {
2835 int rc = SEPOL_ERR;
2836 rc = cil_constrain_expand(pdb, db, cil_constrain->classperms, cil_constrain->datum_expr);
2837 if (rc != SEPOL_OK) {
2838 goto exit;
2839 }
2840
2841 return SEPOL_OK;
2842
2843 exit:
2844 cil_log(CIL_ERR, "Failed to insert constraint into policydb\n");
2845 return rc;
2846 }
2847
cil_validatetrans_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_validatetrans * cil_validatetrans)2848 int cil_validatetrans_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_validatetrans *cil_validatetrans)
2849 {
2850 int rc = SEPOL_ERR;
2851 struct cil_list *expr = cil_validatetrans->datum_expr;
2852 class_datum_t *sepol_class = NULL;
2853 struct cil_list *class_list;
2854 constraint_node_t *sepol_validatetrans = NULL;
2855 constraint_expr_t *sepol_expr = NULL;
2856 struct cil_list_item *c;
2857
2858 class_list = cil_expand_class(cil_validatetrans->class);
2859
2860 cil_list_for_each(c, class_list) {
2861 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
2862 if (rc != SEPOL_OK) goto exit;
2863
2864 sepol_validatetrans = cil_malloc(sizeof(*sepol_validatetrans));
2865 memset(sepol_validatetrans, 0, sizeof(constraint_node_t));
2866
2867 rc = __cil_constrain_expr_to_sepol_expr(pdb, db, expr, &sepol_expr);
2868 if (rc != SEPOL_OK) {
2869 free(sepol_validatetrans);
2870 goto exit;
2871 }
2872 sepol_validatetrans->expr = sepol_expr;
2873
2874 sepol_validatetrans->next = sepol_class->validatetrans;
2875 sepol_class->validatetrans = sepol_validatetrans;
2876 }
2877
2878 rc = SEPOL_OK;
2879
2880 exit:
2881 cil_list_destroy(&class_list, CIL_FALSE);
2882 return rc;
2883 }
2884
__cil_cats_to_mls_level(policydb_t * pdb,struct cil_cats * cats,mls_level_t * mls_level)2885 int __cil_cats_to_mls_level(policydb_t *pdb, struct cil_cats *cats, mls_level_t *mls_level)
2886 {
2887 int rc = SEPOL_ERR;
2888 struct cil_list_item *i;
2889 cat_datum_t *sepol_cat = NULL;
2890
2891 cil_list_for_each(i, cats->datum_expr) {
2892 struct cil_tree_node *node = DATUM(i->data)->nodes->head->data;
2893 if (node->flavor == CIL_CATSET) {
2894 struct cil_list_item *j;
2895 struct cil_catset *cs = i->data;
2896 cil_list_for_each(j, cs->cats->datum_expr) {
2897 rc = __cil_get_sepol_cat_datum(pdb, j->data, &sepol_cat);
2898 if (rc != SEPOL_OK) goto exit;
2899
2900 rc = ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1);
2901 if (rc != SEPOL_OK) goto exit;
2902 }
2903 } else {
2904 rc = __cil_get_sepol_cat_datum(pdb, i->data, &sepol_cat);
2905 if (rc != SEPOL_OK) goto exit;
2906
2907 rc = ebitmap_set_bit(&mls_level->cat, sepol_cat->s.value - 1, 1);
2908 if (rc != SEPOL_OK) goto exit;
2909 }
2910 }
2911
2912 return SEPOL_OK;
2913
2914 exit:
2915 return SEPOL_ERR;
2916 }
2917
cil_sepol_level_define(policydb_t * pdb,struct cil_sens * cil_sens)2918 int cil_sepol_level_define(policydb_t *pdb, struct cil_sens *cil_sens)
2919 {
2920 int rc = SEPOL_ERR;
2921 struct cil_list_item *curr;
2922 level_datum_t *sepol_level = NULL;
2923 mls_level_t *mls_level = NULL;
2924
2925 rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level);
2926 if (rc != SEPOL_OK) goto exit;
2927
2928 mls_level = sepol_level->level;
2929
2930 ebitmap_init(&mls_level->cat);
2931
2932 if (cil_sens->cats_list) {
2933 cil_list_for_each(curr, cil_sens->cats_list) {
2934 struct cil_cats *cats = curr->data;
2935 rc = __cil_cats_to_mls_level(pdb, cats, mls_level);
2936 if (rc != SEPOL_OK) {
2937 cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n");
2938 goto exit;
2939 }
2940 }
2941 }
2942
2943 sepol_level->defined = 1;
2944
2945 return SEPOL_OK;
2946
2947 exit:
2948 return rc;
2949 }
2950
cil_level_to_mls_level(policydb_t * pdb,struct cil_level * cil_level,mls_level_t * mls_level)2951 int cil_level_to_mls_level(policydb_t *pdb, struct cil_level *cil_level, mls_level_t *mls_level)
2952 {
2953 int rc = SEPOL_ERR;
2954 struct cil_sens *cil_sens = cil_level->sens;
2955 struct cil_cats *cats = cil_level->cats;
2956 level_datum_t *sepol_level = NULL;
2957
2958 rc = __cil_get_sepol_level_datum(pdb, DATUM(cil_sens), &sepol_level);
2959 if (rc != SEPOL_OK) goto exit;
2960
2961 mls_level->sens = sepol_level->level->sens;
2962
2963 ebitmap_init(&mls_level->cat);
2964
2965 if (cats != NULL) {
2966 rc = __cil_cats_to_mls_level(pdb, cats, mls_level);
2967 if (rc != SEPOL_OK) {
2968 cil_log(CIL_INFO, "Failed to insert category set into sepol mls level\n");
2969 goto exit;
2970 }
2971 }
2972
2973 rc = SEPOL_OK;
2974 exit:
2975 return rc;
2976 }
2977
__cil_levelrange_to_mls_range(policydb_t * pdb,struct cil_levelrange * cil_lvlrange,mls_range_t * mls_range)2978 int __cil_levelrange_to_mls_range(policydb_t *pdb, struct cil_levelrange *cil_lvlrange, mls_range_t *mls_range)
2979 {
2980 int rc = SEPOL_ERR;
2981 struct cil_level *low = cil_lvlrange->low;
2982 struct cil_level *high = cil_lvlrange->high;
2983 mls_level_t *mls_level = NULL;
2984
2985 mls_level = &mls_range->level[0];
2986
2987 rc = cil_level_to_mls_level(pdb, low, mls_level);
2988 if (rc != SEPOL_OK) {
2989 goto exit;
2990 }
2991
2992 mls_level = &mls_range->level[1];
2993
2994 rc = cil_level_to_mls_level(pdb, high, mls_level);
2995 if (rc != SEPOL_OK) {
2996 goto exit;
2997 }
2998
2999 return SEPOL_OK;
3000
3001 exit:
3002 return rc;
3003 }
3004
cil_userlevel_userrange_to_policydb(policydb_t * pdb,struct cil_user * cil_user)3005 int cil_userlevel_userrange_to_policydb(policydb_t *pdb, struct cil_user *cil_user)
3006 {
3007 int rc = SEPOL_ERR;
3008 struct cil_level *cil_level = cil_user->dftlevel;
3009 struct cil_levelrange *cil_levelrange = cil_user->range;
3010 user_datum_t *sepol_user = NULL;
3011
3012 rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_user), &sepol_user);
3013 if (rc != SEPOL_OK) goto exit;
3014
3015 rc = cil_level_to_mls_level(pdb, cil_level, &sepol_user->exp_dfltlevel);
3016 if (rc != SEPOL_OK) {
3017 goto exit;
3018 }
3019
3020 rc = __cil_levelrange_to_mls_range(pdb, cil_levelrange, &sepol_user->exp_range);
3021 if (rc != SEPOL_OK) {
3022 goto exit;
3023 }
3024
3025 return SEPOL_OK;
3026
3027 exit:
3028 return rc;
3029 }
3030
__cil_context_to_sepol_context(policydb_t * pdb,struct cil_context * cil_context,context_struct_t * sepol_context)3031 int __cil_context_to_sepol_context(policydb_t *pdb, struct cil_context *cil_context, context_struct_t *sepol_context)
3032 {
3033 int rc = SEPOL_ERR;
3034 struct cil_levelrange *cil_lvlrange = cil_context->range;
3035 user_datum_t *sepol_user = NULL;
3036 role_datum_t *sepol_role = NULL;
3037 type_datum_t *sepol_type = NULL;
3038
3039 rc = __cil_get_sepol_user_datum(pdb, DATUM(cil_context->user), &sepol_user);
3040 if (rc != SEPOL_OK) goto exit;
3041
3042 rc = __cil_get_sepol_role_datum(pdb, DATUM(cil_context->role), &sepol_role);
3043 if (rc != SEPOL_OK) goto exit;
3044
3045 rc = __cil_get_sepol_type_datum(pdb, DATUM(cil_context->type), &sepol_type);
3046 if (rc != SEPOL_OK) goto exit;
3047
3048 sepol_context->user = sepol_user->s.value;
3049 sepol_context->role = sepol_role->s.value;
3050 sepol_context->type = sepol_type->s.value;
3051
3052 if (pdb->mls == CIL_TRUE) {
3053 mls_context_init(sepol_context);
3054
3055 rc = __cil_levelrange_to_mls_range(pdb, cil_lvlrange, &sepol_context->range);
3056 if (rc != SEPOL_OK) {
3057 cil_log(CIL_ERR,"Problem with MLS\n");
3058 mls_context_destroy(sepol_context);
3059 goto exit;
3060 }
3061 }
3062
3063 return SEPOL_OK;
3064
3065 exit:
3066 return rc;
3067 }
3068
cil_sidorder_to_policydb(policydb_t * pdb,const struct cil_db * db)3069 int cil_sidorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
3070 {
3071 int rc = SEPOL_ERR;
3072 struct cil_list_item *curr;
3073 unsigned count = 0;
3074 ocontext_t *tail = NULL;
3075
3076 if (db->sidorder == NULL || db->sidorder->head == NULL) {
3077 cil_log(CIL_WARN, "No sidorder statement in policy\n");
3078 return SEPOL_OK;
3079 }
3080
3081 cil_list_for_each(curr, db->sidorder) {
3082 struct cil_sid *cil_sid = (struct cil_sid*)curr->data;
3083 struct cil_context *cil_context = cil_sid->context;
3084
3085 if (cil_context != NULL) {
3086 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_ISID], &tail);
3087 count++;
3088 new_ocon->sid[0] = count;
3089 new_ocon->u.name = cil_strdup(cil_sid->datum.fqn);
3090 rc = __cil_context_to_sepol_context(pdb, cil_context, &new_ocon->context[0]);
3091 if (rc != SEPOL_OK) {
3092 cil_log(CIL_ERR,"Problem with context for SID %s\n",cil_sid->datum.fqn);
3093 goto exit;
3094 }
3095 }
3096 }
3097
3098 return SEPOL_OK;
3099
3100 exit:
3101 return rc;
3102 }
3103
cil_rangetransition_to_policydb(policydb_t * pdb,const struct cil_db * db,struct cil_rangetransition * rangetrans,hashtab_t range_trans_table)3104 int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans, hashtab_t range_trans_table)
3105 {
3106 int rc = SEPOL_ERR;
3107 type_datum_t *sepol_src = NULL;
3108 type_datum_t *sepol_tgt = NULL;
3109 class_datum_t *sepol_class = NULL;
3110 struct cil_list *class_list;
3111 range_trans_t *newkey = NULL;
3112 struct mls_range *newdatum = NULL;
3113 ebitmap_t src_bitmap, tgt_bitmap;
3114 ebitmap_node_t *node1, *node2;
3115 unsigned int i, j;
3116 struct cil_list_item *c;
3117 struct mls_range *o_range = NULL;
3118
3119 rc = __cil_expand_type(rangetrans->src, &src_bitmap);
3120 if (rc != SEPOL_OK) goto exit;
3121
3122 rc = __cil_expand_type(rangetrans->exec, &tgt_bitmap);
3123 if (rc != SEPOL_OK) goto exit;
3124
3125 class_list = cil_expand_class(rangetrans->obj);
3126
3127 ebitmap_for_each_bit(&src_bitmap, node1, i) {
3128 if (!ebitmap_get_bit(&src_bitmap, i)) continue;
3129
3130 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[i]), &sepol_src);
3131 if (rc != SEPOL_OK) goto exit;
3132
3133 ebitmap_for_each_bit(&tgt_bitmap, node2, j) {
3134 if (!ebitmap_get_bit(&tgt_bitmap, j)) continue;
3135
3136 rc = __cil_get_sepol_type_datum(pdb, DATUM(db->val_to_type[j]), &sepol_tgt);
3137 if (rc != SEPOL_OK) goto exit;
3138
3139 cil_list_for_each(c, class_list) {
3140 int add = CIL_TRUE;
3141 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
3142 if (rc != SEPOL_OK) goto exit;
3143
3144 newkey = cil_calloc(1, sizeof(*newkey));
3145 newdatum = cil_calloc(1, sizeof(*newdatum));
3146 newkey->source_type = sepol_src->s.value;
3147 newkey->target_type = sepol_tgt->s.value;
3148 newkey->target_class = sepol_class->s.value;
3149 rc = __cil_levelrange_to_mls_range(pdb, rangetrans->range, newdatum);
3150 if (rc != SEPOL_OK) {
3151 free(newkey);
3152 free(newdatum);
3153 goto exit;
3154 }
3155
3156 rc = hashtab_insert(range_trans_table, (hashtab_key_t)newkey, newdatum);
3157 if (rc != SEPOL_OK) {
3158 if (rc == SEPOL_EEXIST) {
3159 add = CIL_FALSE;
3160 o_range = hashtab_search(range_trans_table, (hashtab_key_t)newkey);
3161 if (!mls_range_eq(newdatum, o_range)) {
3162 cil_log(CIL_ERR, "Conflicting Range transition rules\n");
3163 } else {
3164 rc = SEPOL_OK;
3165 }
3166 } else {
3167 cil_log(CIL_ERR, "Out of memory\n");
3168 }
3169 }
3170
3171 if (add == CIL_TRUE) {
3172 rc = hashtab_insert(pdb->range_tr,
3173 (hashtab_key_t)newkey,
3174 newdatum);
3175 if (rc != SEPOL_OK) {
3176 mls_range_destroy(newdatum);
3177 free(newdatum);
3178 free(newkey);
3179 cil_log(CIL_ERR, "Out of memory\n");
3180 goto exit;
3181 }
3182 } else {
3183 mls_range_destroy(newdatum);
3184 free(newdatum);
3185 free(newkey);
3186 if (rc != SEPOL_OK) {
3187 goto exit;
3188 }
3189 }
3190 }
3191 }
3192 }
3193
3194 rc = SEPOL_OK;
3195
3196 exit:
3197 ebitmap_destroy(&src_bitmap);
3198 ebitmap_destroy(&tgt_bitmap);
3199 cil_list_destroy(&class_list, CIL_FALSE);
3200 return rc;
3201 }
3202
cil_portcon_to_policydb(policydb_t * pdb,struct cil_sort * portcons)3203 int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons)
3204 {
3205 int rc = SEPOL_ERR;
3206 uint32_t i = 0;
3207 ocontext_t *tail = NULL;
3208
3209 for (i = 0; i < portcons->count; i++) {
3210 struct cil_portcon *cil_portcon = portcons->array[i];
3211 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_PORT], &tail);
3212
3213 switch (cil_portcon->proto) {
3214 case CIL_PROTOCOL_UDP:
3215 new_ocon->u.port.protocol = IPPROTO_UDP;
3216 break;
3217 case CIL_PROTOCOL_TCP:
3218 new_ocon->u.port.protocol = IPPROTO_TCP;
3219 break;
3220 case CIL_PROTOCOL_DCCP:
3221 new_ocon->u.port.protocol = IPPROTO_DCCP;
3222 break;
3223 default:
3224 /* should not get here */
3225 rc = SEPOL_ERR;
3226 goto exit;
3227 }
3228
3229 new_ocon->u.port.low_port = cil_portcon->port_low;
3230 new_ocon->u.port.high_port = cil_portcon->port_high;
3231
3232 rc = __cil_context_to_sepol_context(pdb, cil_portcon->context, &new_ocon->context[0]);
3233 if (rc != SEPOL_OK) {
3234 goto exit;
3235 }
3236 }
3237
3238 return SEPOL_OK;
3239
3240 exit:
3241 return rc;
3242 }
3243
cil_netifcon_to_policydb(policydb_t * pdb,struct cil_sort * netifcons)3244 int cil_netifcon_to_policydb(policydb_t *pdb, struct cil_sort *netifcons)
3245 {
3246 int rc = SEPOL_ERR;
3247 uint32_t i = 0;
3248 ocontext_t *tail = NULL;
3249
3250 for (i = 0; i < netifcons->count; i++) {
3251 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NETIF], &tail);
3252 struct cil_netifcon *cil_netifcon = netifcons->array[i];
3253
3254 new_ocon->u.name = cil_strdup(cil_netifcon->interface_str);
3255
3256 rc = __cil_context_to_sepol_context(pdb, cil_netifcon->if_context, &new_ocon->context[0]);
3257 if (rc != SEPOL_OK) {
3258 goto exit;
3259 }
3260
3261 rc = __cil_context_to_sepol_context(pdb, cil_netifcon->packet_context, &new_ocon->context[1]);
3262 if (rc != SEPOL_OK) {
3263 context_destroy(&new_ocon->context[0]);
3264 goto exit;
3265 }
3266 }
3267
3268 return SEPOL_OK;
3269
3270 exit:
3271 return rc;
3272 }
3273
cil_nodecon_to_policydb(policydb_t * pdb,struct cil_sort * nodecons)3274 int cil_nodecon_to_policydb(policydb_t *pdb, struct cil_sort *nodecons)
3275 {
3276 int rc = SEPOL_ERR;
3277 uint32_t i = 0;
3278 ocontext_t *tail = NULL;
3279 ocontext_t *tail6 = NULL;
3280
3281 for (i = 0; i < nodecons->count; i++) {
3282 ocontext_t *new_ocon = NULL;
3283 struct cil_nodecon *cil_nodecon = nodecons->array[i];
3284
3285 if (cil_nodecon->addr->family == AF_INET) {
3286 new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE], &tail);
3287 new_ocon->u.node.addr = cil_nodecon->addr->ip.v4.s_addr;
3288 new_ocon->u.node.mask = cil_nodecon->mask->ip.v4.s_addr;
3289 } else if (cil_nodecon->addr->family == AF_INET6) {
3290 new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_NODE6], &tail6);
3291 memcpy(new_ocon->u.node6.addr, &cil_nodecon->addr->ip.v6.s6_addr[0], 16);
3292 memcpy(new_ocon->u.node6.mask, &cil_nodecon->mask->ip.v6.s6_addr[0], 16);
3293 } else {
3294 /* should not get here */
3295 rc = SEPOL_ERR;
3296 goto exit;
3297 }
3298
3299 rc = __cil_context_to_sepol_context(pdb, cil_nodecon->context, &new_ocon->context[0]);
3300 if (rc != SEPOL_OK) {
3301 goto exit;
3302 }
3303 }
3304
3305 return SEPOL_OK;
3306
3307 exit:
3308 return rc;
3309 }
3310
cil_fsuse_to_policydb(policydb_t * pdb,struct cil_sort * fsuses)3311 int cil_fsuse_to_policydb(policydb_t *pdb, struct cil_sort *fsuses)
3312 {
3313 int rc = SEPOL_ERR;
3314 uint32_t i = 0;
3315 ocontext_t *tail = NULL;
3316
3317 for (i = 0; i < fsuses->count; i++) {
3318 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_FSUSE], &tail);
3319 struct cil_fsuse *cil_fsuse = fsuses->array[i];
3320
3321 new_ocon->u.name = cil_strdup(cil_fsuse->fs_str);
3322 new_ocon->v.behavior = cil_fsuse->type;
3323
3324 rc = __cil_context_to_sepol_context(pdb, cil_fsuse->context, &new_ocon->context[0]);
3325 if (rc != SEPOL_OK) {
3326 goto exit;
3327 }
3328 }
3329
3330 return SEPOL_OK;
3331
3332 exit:
3333 return rc;
3334 }
3335
cil_genfscon_to_policydb(policydb_t * pdb,struct cil_sort * genfscons)3336 int cil_genfscon_to_policydb(policydb_t *pdb, struct cil_sort *genfscons)
3337 {
3338 int rc = SEPOL_ERR;
3339 uint32_t i = 0;
3340 genfs_t *genfs_tail = NULL;
3341 ocontext_t *ocon_tail = NULL;
3342
3343 for (i = 0; i < genfscons->count; i++) {
3344 struct cil_genfscon *cil_genfscon = genfscons->array[i];
3345 ocontext_t *new_ocon = cil_malloc(sizeof(ocontext_t));
3346 memset(new_ocon, 0, sizeof(ocontext_t));
3347
3348 if (genfs_tail && strcmp(genfs_tail->fstype, cil_genfscon->fs_str) == 0) {
3349 ocon_tail->next = new_ocon;
3350 } else {
3351 genfs_t *new_genfs = cil_malloc(sizeof(genfs_t));
3352 memset(new_genfs, 0, sizeof(genfs_t));
3353 new_genfs->fstype = cil_strdup(cil_genfscon->fs_str);
3354 new_genfs->head = new_ocon;
3355
3356 if (genfs_tail) {
3357 genfs_tail->next = new_genfs;
3358 } else {
3359 pdb->genfs = new_genfs;
3360 }
3361 genfs_tail = new_genfs;
3362 }
3363
3364 ocon_tail = new_ocon;
3365
3366 new_ocon->u.name = cil_strdup(cil_genfscon->path_str);
3367
3368 rc = __cil_context_to_sepol_context(pdb, cil_genfscon->context, &new_ocon->context[0]);
3369 if (rc != SEPOL_OK) {
3370 goto exit;
3371 }
3372 }
3373
3374 return SEPOL_OK;
3375
3376 exit:
3377 return rc;
3378 }
3379
cil_pirqcon_to_policydb(policydb_t * pdb,struct cil_sort * pirqcons)3380 int cil_pirqcon_to_policydb(policydb_t *pdb, struct cil_sort *pirqcons)
3381 {
3382 int rc = SEPOL_ERR;
3383 uint32_t i = 0;
3384 ocontext_t *tail = NULL;
3385
3386 for (i = 0; i < pirqcons->count; i++) {
3387 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PIRQ], &tail);
3388 struct cil_pirqcon *cil_pirqcon = pirqcons->array[i];
3389
3390 new_ocon->u.pirq = cil_pirqcon->pirq;
3391
3392 rc = __cil_context_to_sepol_context(pdb, cil_pirqcon->context, &new_ocon->context[0]);
3393 if (rc != SEPOL_OK) {
3394 goto exit;
3395 }
3396 }
3397
3398 return SEPOL_OK;
3399
3400 exit:
3401 return rc;
3402 }
3403
cil_iomemcon_to_policydb(policydb_t * pdb,struct cil_sort * iomemcons)3404 int cil_iomemcon_to_policydb(policydb_t *pdb, struct cil_sort *iomemcons)
3405 {
3406 int rc = SEPOL_ERR;
3407 uint32_t i = 0;
3408 ocontext_t *tail = NULL;
3409
3410 for (i = 0; i < iomemcons->count; i++) {
3411 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOMEM], &tail);
3412 struct cil_iomemcon *cil_iomemcon = iomemcons->array[i];
3413
3414 new_ocon->u.iomem.low_iomem = cil_iomemcon->iomem_low;
3415 new_ocon->u.iomem.high_iomem = cil_iomemcon->iomem_high;
3416
3417 rc = __cil_context_to_sepol_context(pdb, cil_iomemcon->context, &new_ocon->context[0]);
3418 if (rc != SEPOL_OK) {
3419 goto exit;
3420 }
3421 }
3422
3423 return SEPOL_OK;
3424
3425 exit:
3426 return rc;
3427 }
3428
cil_ioportcon_to_policydb(policydb_t * pdb,struct cil_sort * ioportcons)3429 int cil_ioportcon_to_policydb(policydb_t *pdb, struct cil_sort *ioportcons)
3430 {
3431 int rc = SEPOL_ERR;
3432 uint32_t i = 0;
3433 ocontext_t *tail = NULL;
3434
3435 for (i = 0; i < ioportcons->count; i++) {
3436 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_IOPORT], &tail);
3437 struct cil_ioportcon *cil_ioportcon = ioportcons->array[i];
3438
3439 new_ocon->u.ioport.low_ioport = cil_ioportcon->ioport_low;
3440 new_ocon->u.ioport.high_ioport = cil_ioportcon->ioport_high;
3441
3442 rc = __cil_context_to_sepol_context(pdb, cil_ioportcon->context, &new_ocon->context[0]);
3443 if (rc != SEPOL_OK) {
3444 goto exit;
3445 }
3446 }
3447
3448 return SEPOL_OK;
3449
3450 exit:
3451 return rc;
3452 }
3453
cil_pcidevicecon_to_policydb(policydb_t * pdb,struct cil_sort * pcidevicecons)3454 int cil_pcidevicecon_to_policydb(policydb_t *pdb, struct cil_sort *pcidevicecons)
3455 {
3456 int rc = SEPOL_ERR;
3457 uint32_t i = 0;
3458 ocontext_t *tail = NULL;
3459
3460 for (i = 0; i < pcidevicecons->count; i++) {
3461 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_PCIDEVICE], &tail);
3462 struct cil_pcidevicecon *cil_pcidevicecon = pcidevicecons->array[i];
3463
3464 new_ocon->u.device = cil_pcidevicecon->dev;
3465
3466 rc = __cil_context_to_sepol_context(pdb, cil_pcidevicecon->context, &new_ocon->context[0]);
3467 if (rc != SEPOL_OK) {
3468 goto exit;
3469 }
3470 }
3471
3472 return SEPOL_OK;
3473
3474 exit:
3475 return rc;
3476 }
3477
cil_devicetreecon_to_policydb(policydb_t * pdb,struct cil_sort * devicetreecons)3478 int cil_devicetreecon_to_policydb(policydb_t *pdb, struct cil_sort *devicetreecons)
3479 {
3480 int rc = SEPOL_ERR;
3481 uint32_t i = 0;
3482 ocontext_t *tail = NULL;
3483
3484 for (i = 0; i < devicetreecons->count; i++) {
3485 ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_DEVICETREE], &tail);
3486 struct cil_devicetreecon *cil_devicetreecon = devicetreecons->array[i];
3487
3488 new_ocon->u.name = cil_strdup(cil_devicetreecon->path);
3489
3490 rc = __cil_context_to_sepol_context(pdb, cil_devicetreecon->context, &new_ocon->context[0]);
3491 if (rc != SEPOL_OK) {
3492 goto exit;
3493 }
3494 }
3495
3496 return SEPOL_OK;
3497
3498 exit:
3499 return rc;
3500 }
3501
cil_default_to_policydb(policydb_t * pdb,struct cil_default * def)3502 int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def)
3503 {
3504 struct cil_list_item *curr;
3505 class_datum_t *sepol_class;
3506 struct cil_list *class_list;
3507
3508 cil_list_for_each(curr, def->class_datums) {
3509 struct cil_list_item *c;
3510
3511 class_list = cil_expand_class(curr->data);
3512
3513 cil_list_for_each(c, class_list) {
3514 int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
3515 if (rc != SEPOL_OK) goto exit;
3516
3517 switch (def->flavor) {
3518 case CIL_DEFAULTUSER:
3519 if (!sepol_class->default_user) {
3520 sepol_class->default_user = def->object;
3521 } else if (sepol_class->default_user != (char)def->object) {
3522 cil_log(CIL_ERR,"User default labeling for class %s already specified\n",DATUM(c->data)->fqn);
3523 goto exit;
3524 }
3525 break;
3526 case CIL_DEFAULTROLE:
3527 if (!sepol_class->default_role) {
3528 sepol_class->default_role = def->object;
3529 } else if (sepol_class->default_role != (char)def->object) {
3530 cil_log(CIL_ERR,"Role default labeling for class %s already specified\n",DATUM(c->data)->fqn);
3531 goto exit;
3532 }
3533 break;
3534 case CIL_DEFAULTTYPE:
3535 if (!sepol_class->default_type) {
3536 sepol_class->default_type = def->object;
3537 } else if (sepol_class->default_type != (char)def->object) {
3538 cil_log(CIL_ERR,"Type default labeling for class %s already specified\n",DATUM(c->data)->fqn);
3539 goto exit;
3540 }
3541 break;
3542 default:
3543 goto exit;
3544 }
3545 }
3546
3547 cil_list_destroy(&class_list, CIL_FALSE);
3548 }
3549
3550 return SEPOL_OK;
3551
3552 exit:
3553 cil_list_destroy(&class_list, CIL_FALSE);
3554 return SEPOL_ERR;
3555 }
3556
cil_defaultrange_to_policydb(policydb_t * pdb,struct cil_defaultrange * def)3557 int cil_defaultrange_to_policydb(policydb_t *pdb, struct cil_defaultrange *def)
3558 {
3559 struct cil_list_item *curr;
3560 class_datum_t *sepol_class;
3561 struct cil_list *class_list;
3562
3563 cil_list_for_each(curr, def->class_datums) {
3564 struct cil_list_item *c;
3565
3566 class_list = cil_expand_class(curr->data);
3567
3568 cil_list_for_each(c, class_list) {
3569 int rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class);
3570 if (rc != SEPOL_OK) goto exit;
3571
3572 if (!sepol_class->default_range) {
3573 sepol_class->default_range = def->object_range;
3574 } else if (sepol_class->default_range != (char)def->object_range) {
3575 cil_log(CIL_ERR,"Range default labeling for class %s already specified\n", DATUM(curr->data)->fqn);
3576 goto exit;
3577 }
3578 }
3579
3580 cil_list_destroy(&class_list, CIL_FALSE);
3581 }
3582
3583 return SEPOL_OK;
3584
3585 exit:
3586 cil_list_destroy(&class_list, CIL_FALSE);
3587 return SEPOL_ERR;
3588 }
3589
__cil_node_to_policydb(struct cil_tree_node * node,void * extra_args)3590 int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
3591 {
3592 int rc = SEPOL_OK;
3593 int pass;
3594 struct cil_args_binary *args = extra_args;
3595 const struct cil_db *db;
3596 policydb_t *pdb;
3597 hashtab_t filename_trans_table;
3598 hashtab_t range_trans_table;
3599 hashtab_t role_trans_table;
3600 void **type_value_to_cil;
3601
3602 db = args->db;
3603 pdb = args->pdb;
3604 pass = args->pass;
3605 filename_trans_table = args->filename_trans_table;
3606 range_trans_table = args->range_trans_table;
3607 role_trans_table = args->role_trans_table;
3608 type_value_to_cil = args->type_value_to_cil;
3609
3610 if (node->flavor >= CIL_MIN_DECLARATIVE) {
3611 if (node != DATUM(node->data)->nodes->head->data) {
3612 goto exit;
3613 }
3614 }
3615
3616 switch (pass) {
3617 case 1:
3618 switch (node->flavor) {
3619 case CIL_ROLE:
3620 rc = cil_role_to_policydb(pdb, node->data);
3621 break;
3622 case CIL_TYPE:
3623 rc = cil_type_to_policydb(pdb, node->data, type_value_to_cil);
3624 break;
3625 case CIL_TYPEATTRIBUTE:
3626 rc = cil_typeattribute_to_policydb(pdb, node->data, type_value_to_cil);
3627 break;
3628 case CIL_POLICYCAP:
3629 rc = cil_policycap_to_policydb(pdb, node->data);
3630 break;
3631 case CIL_USER:
3632 rc = cil_user_to_policydb(pdb, node->data);
3633 break;
3634 case CIL_BOOL:
3635 rc = cil_bool_to_policydb(pdb, node->data);
3636 break;
3637 case CIL_CATALIAS:
3638 if (pdb->mls == CIL_TRUE) {
3639 rc = cil_catalias_to_policydb(pdb, node->data);
3640 }
3641 break;
3642 case CIL_SENS:
3643 if (pdb->mls == CIL_TRUE) {
3644 rc = cil_sepol_level_define(pdb, node->data);
3645 }
3646 break;
3647 default:
3648 break;
3649 }
3650 break;
3651 case 2:
3652 switch (node->flavor) {
3653 case CIL_TYPE:
3654 rc = cil_type_bounds_to_policydb(pdb, node->data);
3655 break;
3656 case CIL_TYPEALIAS:
3657 rc = cil_typealias_to_policydb(pdb, node->data);
3658 break;
3659 case CIL_TYPEPERMISSIVE:
3660 rc = cil_typepermissive_to_policydb(pdb, node->data);
3661 break;
3662 case CIL_TYPEATTRIBUTE:
3663 rc = cil_typeattribute_to_bitmap(pdb, db, node->data);
3664 break;
3665 case CIL_SENSALIAS:
3666 if (pdb->mls == CIL_TRUE) {
3667 rc = cil_sensalias_to_policydb(pdb, node->data);
3668 }
3669 break;
3670 case CIL_ROLE:
3671 rc = cil_role_bounds_to_policydb(pdb, node->data);
3672 if (rc != SEPOL_OK) goto exit;
3673 rc = cil_roletype_to_policydb(pdb, db, node->data);
3674 break;
3675 case CIL_USER:
3676 rc = cil_user_bounds_to_policydb(pdb, node->data);
3677 if (rc != SEPOL_OK) goto exit;
3678 if (pdb->mls == CIL_TRUE) {
3679 rc = cil_userlevel_userrange_to_policydb(pdb, node->data);
3680 if (rc != SEPOL_OK) {
3681 goto exit;
3682 }
3683 }
3684 rc = cil_userrole_to_policydb(pdb, db, node->data);
3685 break;
3686 case CIL_TYPE_RULE:
3687 rc = cil_type_rule_to_policydb(pdb, db, node->data);
3688 break;
3689 case CIL_AVRULE:
3690 case CIL_AVRULEX: {
3691 struct cil_avrule *rule = node->data;
3692 if (db->disable_neverallow != CIL_TRUE && rule->rule_kind == CIL_AVRULE_NEVERALLOW) {
3693 struct cil_list *neverallows = args->neverallows;
3694 cil_list_prepend(neverallows, CIL_LIST_ITEM, node);
3695 }
3696 break;
3697 }
3698 case CIL_ROLETRANSITION:
3699 rc = cil_roletrans_to_policydb(pdb, db, node->data, role_trans_table);
3700 break;
3701 case CIL_ROLEATTRIBUTESET:
3702 /*rc = cil_roleattributeset_to_policydb(pdb, node->data);*/
3703 break;
3704 case CIL_NAMETYPETRANSITION:
3705 rc = cil_typetransition_to_policydb(pdb, db, node->data, filename_trans_table);
3706 break;
3707 case CIL_CONSTRAIN:
3708 rc = cil_constrain_to_policydb(pdb, db, node->data);
3709 break;
3710 case CIL_MLSCONSTRAIN:
3711 if (pdb->mls == CIL_TRUE) {
3712 rc = cil_constrain_to_policydb(pdb, db, node->data);
3713 }
3714 break;
3715 case CIL_VALIDATETRANS:
3716 rc = cil_validatetrans_to_policydb(pdb, db, node->data);
3717 break;
3718 case CIL_MLSVALIDATETRANS:
3719 if (pdb->mls == CIL_TRUE) {
3720 rc = cil_validatetrans_to_policydb(pdb, db, node->data);
3721 }
3722 break;
3723 case CIL_RANGETRANSITION:
3724 if (pdb->mls == CIL_TRUE) {
3725 rc = cil_rangetransition_to_policydb(pdb, db, node->data, range_trans_table);
3726 }
3727 break;
3728 case CIL_DEFAULTUSER:
3729 case CIL_DEFAULTROLE:
3730 case CIL_DEFAULTTYPE:
3731 rc = cil_default_to_policydb(pdb, node->data);
3732 break;
3733 case CIL_DEFAULTRANGE:
3734 rc = cil_defaultrange_to_policydb(pdb, node->data);
3735 break;
3736 default:
3737 break;
3738 }
3739 break;
3740 case 3:
3741 switch (node->flavor) {
3742 case CIL_BOOLEANIF:
3743 rc = cil_booleanif_to_policydb(pdb, db, node, filename_trans_table);
3744 break;
3745 case CIL_AVRULE: {
3746 struct cil_avrule *rule = node->data;
3747 if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) {
3748 rc = cil_avrule_to_policydb(pdb, db, node->data);
3749 }
3750 }
3751 break;
3752 case CIL_AVRULEX: {
3753 struct cil_avrule *rule = node->data;
3754 if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) {
3755 rc = cil_avrulex_to_hashtable(pdb, db, node->data, args);
3756 }
3757 }
3758 break;
3759 case CIL_ROLEALLOW:
3760 rc = cil_roleallow_to_policydb(pdb, db, node->data);
3761 break;
3762 default:
3763 break;
3764 }
3765 default:
3766 break;
3767 }
3768
3769 exit:
3770 if (rc != SEPOL_OK) {
3771 cil_tree_log(node, CIL_ERR, "Binary policy creation failed");
3772 }
3773 return rc;
3774 }
3775
__cil_binary_create_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)3776 int __cil_binary_create_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
3777 {
3778 int rc = SEPOL_ERR;
3779
3780 if (node->flavor == CIL_BLOCK) {
3781 struct cil_block *blk = node->data;
3782 if (blk->is_abstract == CIL_TRUE) {
3783 *finished = CIL_TREE_SKIP_HEAD;
3784 rc = SEPOL_OK;
3785 goto exit;
3786 }
3787 } else if (node->flavor == CIL_MACRO) {
3788 *finished = CIL_TREE_SKIP_HEAD;
3789 rc = SEPOL_OK;
3790 goto exit;
3791 } else if (node->flavor == CIL_BOOLEANIF) {
3792 *finished = CIL_TREE_SKIP_HEAD;
3793 }
3794
3795 rc = __cil_node_to_policydb(node, extra_args);
3796 if (rc != SEPOL_OK) {
3797 goto exit;
3798 }
3799
3800 exit:
3801 return rc;
3802 }
3803
__cil_contexts_to_policydb(policydb_t * pdb,const struct cil_db * db)3804 int __cil_contexts_to_policydb(policydb_t *pdb, const struct cil_db *db)
3805 {
3806 int rc = SEPOL_ERR;
3807
3808 rc = cil_portcon_to_policydb(pdb, db->portcon);
3809 if (rc != SEPOL_OK) {
3810 goto exit;
3811 }
3812
3813 rc = cil_netifcon_to_policydb(pdb, db->netifcon);
3814 if (rc != SEPOL_OK) {
3815 goto exit;
3816 }
3817
3818 rc = cil_nodecon_to_policydb(pdb, db->nodecon);
3819 if (rc != SEPOL_OK) {
3820 goto exit;
3821 }
3822
3823 rc = cil_fsuse_to_policydb(pdb, db->fsuse);
3824 if (rc != SEPOL_OK) {
3825 goto exit;
3826 }
3827
3828 rc = cil_genfscon_to_policydb(pdb, db->genfscon);
3829 if (rc != SEPOL_OK) {
3830 goto exit;
3831 }
3832
3833 if (db->target_platform == SEPOL_TARGET_XEN) {
3834 rc = cil_pirqcon_to_policydb(pdb, db->pirqcon);
3835 if (rc != SEPOL_OK) {
3836 goto exit;
3837 }
3838
3839 rc = cil_iomemcon_to_policydb(pdb, db->iomemcon);
3840 if (rc != SEPOL_OK) {
3841 goto exit;
3842 }
3843
3844 rc = cil_ioportcon_to_policydb(pdb, db->ioportcon);
3845 if (rc != SEPOL_OK) {
3846 goto exit;
3847 }
3848
3849 rc = cil_pcidevicecon_to_policydb(pdb, db->pcidevicecon);
3850 if (rc != SEPOL_OK) {
3851 goto exit;
3852 }
3853
3854 rc = cil_devicetreecon_to_policydb(pdb, db->devicetreecon);
3855 if (rc != SEPOL_OK) {
3856 goto exit;
3857 }
3858 }
3859 return SEPOL_OK;
3860 exit:
3861 return rc;
3862 }
3863
__cil_common_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3864 int __cil_common_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3865 {
3866 policydb_t *pdb = data;
3867 common_datum_t *common = (common_datum_t *)datum;
3868
3869 if (common->s.value < 1 || common->s.value > pdb->p_commons.nprim) {
3870 return -EINVAL;
3871 }
3872 pdb->p_common_val_to_name[common->s.value - 1] = (char *)key;
3873
3874 return 0;
3875 }
3876
__cil_class_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3877 int __cil_class_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3878 {
3879 policydb_t *pdb = data;
3880 class_datum_t *class = (class_datum_t *)datum;
3881
3882 if (class->s.value < 1 || class->s.value > pdb->p_classes.nprim) {
3883 return -EINVAL;
3884 }
3885 pdb->p_class_val_to_name[class->s.value - 1] = (char *)key;
3886 pdb->class_val_to_struct[class->s.value - 1] = class;
3887
3888 return 0;
3889 }
3890
__cil_role_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3891 int __cil_role_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3892 {
3893 policydb_t *pdb = data;
3894 role_datum_t *role = (role_datum_t *)datum;
3895
3896 if (role->s.value < 1 || role->s.value > pdb->p_roles.nprim) {
3897 return -EINVAL;
3898 }
3899 pdb->p_role_val_to_name[role->s.value - 1] = (char *)key;
3900 pdb->role_val_to_struct[role->s.value - 1] = role;
3901
3902 return 0;
3903 }
3904
__cil_type_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3905 int __cil_type_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3906 {
3907 policydb_t *pdb = data;
3908 type_datum_t *type = (type_datum_t *)datum;
3909
3910 if (type->s.value < 1 || type->s.value > pdb->p_types.nprim) {
3911 return -EINVAL;
3912 }
3913 pdb->p_type_val_to_name[type->s.value - 1] = (char *)key;
3914 pdb->type_val_to_struct[type->s.value - 1] = type;
3915
3916 return 0;
3917 }
3918
__cil_user_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3919 int __cil_user_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3920 {
3921 policydb_t *pdb = data;
3922 user_datum_t *user = (user_datum_t *)datum;
3923
3924 if (user->s.value < 1 || user->s.value > pdb->p_users.nprim) {
3925 return -EINVAL;
3926 }
3927 pdb->p_user_val_to_name[user->s.value - 1] = (char *)key;
3928 pdb->user_val_to_struct[user->s.value - 1] = user;
3929
3930 return 0;
3931 }
3932
__cil_bool_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3933 int __cil_bool_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3934 {
3935 policydb_t *pdb = data;
3936 cond_bool_datum_t *bool = (cond_bool_datum_t *)datum;
3937
3938 if (bool->s.value < 1 || bool->s.value > pdb->p_bools.nprim) {
3939 return -EINVAL;
3940 }
3941 pdb->p_bool_val_to_name[bool->s.value - 1] = (char *)key;
3942 pdb->bool_val_to_struct[bool->s.value - 1] = bool;
3943
3944 return 0;
3945 }
3946
__cil_level_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3947 int __cil_level_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3948 {
3949 policydb_t *pdb = data;
3950 level_datum_t *level = (level_datum_t *)datum;
3951
3952 if (level->level->sens < 1 || level->level->sens > pdb->p_levels.nprim) {
3953 return -EINVAL;
3954 }
3955 pdb->p_sens_val_to_name[level->level->sens - 1] = (char *)key;
3956
3957 return 0;
3958 }
3959
__cil_cat_val_array_insert(hashtab_key_t key,hashtab_datum_t datum,void * data)3960 int __cil_cat_val_array_insert(hashtab_key_t key, hashtab_datum_t datum, void *data)
3961 {
3962 policydb_t *pdb = data;
3963 cat_datum_t *cat = (cat_datum_t *)datum;
3964
3965 if (cat->s.value < 1 || cat->s.value > pdb->p_cats.nprim) {
3966 return -EINVAL;
3967 }
3968 pdb->p_cat_val_to_name[cat->s.value - 1] = (char *)key;
3969
3970 return 0;
3971 }
3972
__cil_policydb_val_arrays_create(policydb_t * policydb)3973 int __cil_policydb_val_arrays_create(policydb_t *policydb)
3974 {
3975 int rc = SEPOL_ERR;
3976
3977 policydb->p_common_val_to_name = cil_malloc(sizeof(char *) * policydb->p_commons.nprim);
3978 rc = hashtab_map(policydb->p_commons.table, &__cil_common_val_array_insert, policydb);
3979 if (rc != SEPOL_OK) {
3980 goto exit;
3981 }
3982
3983 policydb->p_class_val_to_name = cil_malloc(sizeof(char *) * policydb->p_classes.nprim);
3984 policydb->class_val_to_struct = cil_malloc(sizeof(class_datum_t *) * policydb->p_classes.nprim);
3985 rc = hashtab_map(policydb->p_classes.table, &__cil_class_val_array_insert, policydb);
3986 if (rc != SEPOL_OK) {
3987 goto exit;
3988 }
3989
3990 policydb->p_role_val_to_name = cil_malloc(sizeof(char *) * policydb->p_roles.nprim);
3991 policydb->role_val_to_struct = cil_malloc(sizeof(role_datum_t *) * policydb->p_roles.nprim);
3992 rc = hashtab_map(policydb->p_roles.table, &__cil_role_val_array_insert, policydb);
3993 if (rc != SEPOL_OK) {
3994 goto exit;
3995 }
3996
3997 policydb->p_type_val_to_name = cil_malloc(sizeof(char *) * policydb->p_types.nprim);
3998 policydb->type_val_to_struct = cil_malloc(sizeof(type_datum_t *) * policydb->p_types.nprim);
3999 rc = hashtab_map(policydb->p_types.table, &__cil_type_val_array_insert, policydb);
4000 if (rc != SEPOL_OK) {
4001 goto exit;
4002 }
4003
4004 policydb->p_user_val_to_name = cil_malloc(sizeof(char *) * policydb->p_users.nprim);
4005 policydb->user_val_to_struct = cil_malloc(sizeof(user_datum_t *) * policydb->p_users.nprim);
4006 rc = hashtab_map(policydb->p_users.table, &__cil_user_val_array_insert, policydb);
4007 if (rc != SEPOL_OK) {
4008 goto exit;
4009 }
4010
4011 policydb->p_bool_val_to_name = cil_malloc(sizeof(char *) * policydb->p_bools.nprim);
4012 policydb->bool_val_to_struct = cil_malloc(sizeof(cond_bool_datum_t *) * policydb->p_bools.nprim);
4013 rc = hashtab_map(policydb->p_bools.table, &__cil_bool_val_array_insert, policydb);
4014 if (rc != SEPOL_OK) {
4015 goto exit;
4016 }
4017
4018 policydb->p_sens_val_to_name = cil_malloc(sizeof(char *) * policydb->p_levels.nprim);
4019 rc = hashtab_map(policydb->p_levels.table, &__cil_level_val_array_insert, policydb);
4020 if (rc != SEPOL_OK) {
4021 goto exit;
4022 }
4023
4024 policydb->p_cat_val_to_name = cil_malloc(sizeof(char *) * policydb->p_cats.nprim);
4025 rc = hashtab_map(policydb->p_cats.table, &__cil_cat_val_array_insert, policydb);
4026 if (rc != SEPOL_OK) {
4027 goto exit;
4028 }
4029
4030 exit:
4031 return rc;
4032 }
4033
__cil_set_conditional_state_and_flags(policydb_t * pdb)4034 static void __cil_set_conditional_state_and_flags(policydb_t *pdb)
4035 {
4036 cond_node_t *cur;
4037
4038 for (cur = pdb->cond_list; cur != NULL; cur = cur->next) {
4039 int new_state;
4040 cond_av_list_t *c;
4041
4042 new_state = cond_evaluate_expr(pdb, cur->expr);
4043
4044 cur->cur_state = new_state;
4045
4046 if (new_state == -1) {
4047 cil_log(CIL_WARN, "Expression result was undefined - disabling all rules\n");
4048 }
4049
4050 for (c = cur->true_list; c != NULL; c = c->next) {
4051 if (new_state <= 0) {
4052 c->node->key.specified &= ~AVTAB_ENABLED;
4053 } else {
4054 c->node->key.specified |= AVTAB_ENABLED;
4055 }
4056 }
4057
4058 for (c = cur->false_list; c != NULL; c = c->next) {
4059 if (new_state) { /* -1 or 1 */
4060 c->node->key.specified &= ~AVTAB_ENABLED;
4061 } else {
4062 c->node->key.specified |= AVTAB_ENABLED;
4063 }
4064 }
4065 }
4066 }
4067
__cil_policydb_create(const struct cil_db * db,struct sepol_policydb ** spdb)4068 int __cil_policydb_create(const struct cil_db *db, struct sepol_policydb **spdb)
4069 {
4070 int rc;
4071 struct policydb *pdb = NULL;
4072
4073 rc = sepol_policydb_create(spdb);
4074 if (rc < 0) {
4075 cil_log(CIL_ERR, "Failed to create policy db\n");
4076 // spdb could be a dangling pointer at this point, so reset it so
4077 // callers of this function don't need to worry about freeing garbage
4078 *spdb = NULL;
4079 goto exit;
4080 }
4081
4082 pdb = &(*spdb)->p;
4083
4084 pdb->policy_type = POLICY_KERN;
4085 pdb->target_platform = db->target_platform;
4086 pdb->policyvers = db->policy_version;
4087 pdb->handle_unknown = db->handle_unknown;
4088 pdb->mls = db->mls;
4089
4090 return SEPOL_OK;
4091
4092 exit:
4093 return rc;
4094 }
4095
4096
__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[])4097 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[])
4098 {
4099 int rc = SEPOL_ERR;
4100
4101 // these flags should get set in __cil_policydb_create. However, for
4102 // backwards compatability, it is possible that __cil_policydb_create is
4103 // never called. So, they must also be set here.
4104 pdb->handle_unknown = db->handle_unknown;
4105 pdb->mls = db->mls;
4106
4107 rc = cil_classorder_to_policydb(pdb, db, class_value_to_cil, perm_value_to_cil);
4108 if (rc != SEPOL_OK) {
4109 goto exit;
4110 }
4111
4112 if (pdb->mls == CIL_TRUE) {
4113 rc = cil_catorder_to_policydb(pdb, db);
4114 if (rc != SEPOL_OK) {
4115 goto exit;
4116 }
4117
4118 rc = cil_sensitivityorder_to_policydb(pdb, db);
4119 if (rc != SEPOL_OK) {
4120 goto exit;
4121 }
4122 }
4123
4124 rc = avtab_alloc(&pdb->te_avtab, MAX_AVTAB_SIZE);
4125 if (rc != SEPOL_OK) {
4126 goto exit;
4127 }
4128
4129 rc = avtab_alloc(&pdb->te_cond_avtab, MAX_AVTAB_SIZE);
4130 if (rc != SEPOL_OK) {
4131 goto exit;
4132 }
4133
4134 return SEPOL_OK;
4135
4136 exit:
4137
4138 return rc;
4139 }
4140
filename_trans_hash(hashtab_t h,const_hashtab_key_t key)4141 static unsigned int filename_trans_hash(hashtab_t h, const_hashtab_key_t key)
4142 {
4143 const filename_trans_t *k = (const filename_trans_t *)key;
4144 return ((k->tclass + (k->ttype << 2) +
4145 (k->stype << 9)) & (h->size - 1));
4146 }
4147
filename_trans_compare(hashtab_t h,const_hashtab_key_t key1,const_hashtab_key_t key2)4148 static int filename_trans_compare(hashtab_t h
4149 __attribute__ ((unused)), const_hashtab_key_t key1,
4150 const_hashtab_key_t key2)
4151 {
4152 const filename_trans_t *a = (const filename_trans_t *)key1;
4153 const filename_trans_t *b = (const filename_trans_t *)key2;
4154
4155 return a->stype != b->stype || a->ttype != b->ttype || a->tclass != b->tclass || strcmp(a->name, b->name);
4156 }
4157
range_trans_hash(hashtab_t h,const_hashtab_key_t key)4158 static unsigned int range_trans_hash(hashtab_t h, const_hashtab_key_t key)
4159 {
4160 const range_trans_t *k = (const range_trans_t *)key;
4161 return ((k->target_class + (k->target_type << 2) +
4162 (k->source_type << 5)) & (h->size - 1));
4163 }
4164
range_trans_compare(hashtab_t h,const_hashtab_key_t key1,const_hashtab_key_t key2)4165 static int range_trans_compare(hashtab_t h
4166 __attribute__ ((unused)), const_hashtab_key_t key1,
4167 const_hashtab_key_t key2)
4168 {
4169 const range_trans_t *a = (const range_trans_t *)key1;
4170 const range_trans_t *b = (const range_trans_t *)key2;
4171
4172 return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class;
4173 }
4174
role_trans_hash(hashtab_t h,const_hashtab_key_t key)4175 static unsigned int role_trans_hash(hashtab_t h, const_hashtab_key_t key)
4176 {
4177 const role_trans_t *k = (const role_trans_t *)key;
4178 return ((k->role + (k->type << 2) +
4179 (k->tclass << 5)) & (h->size - 1));
4180 }
4181
role_trans_compare(hashtab_t h,const_hashtab_key_t key1,const_hashtab_key_t key2)4182 static int role_trans_compare(hashtab_t h
4183 __attribute__ ((unused)), const_hashtab_key_t key1,
4184 const_hashtab_key_t key2)
4185 {
4186 const role_trans_t *a = (const role_trans_t *)key1;
4187 const role_trans_t *b = (const role_trans_t *)key2;
4188
4189 return a->role != b->role || a->type != b->type || a->tclass != b->tclass;
4190 }
4191
4192 /* Based on MurmurHash3, written by Austin Appleby and placed in the
4193 * public domain.
4194 */
avrulex_hash(hashtab_t h,const_hashtab_key_t key)4195 static unsigned int avrulex_hash(__attribute__((unused)) hashtab_t h, const_hashtab_key_t key)
4196 {
4197 const avtab_key_t *k = (const avtab_key_t *)key;
4198
4199 static const uint32_t c1 = 0xcc9e2d51;
4200 static const uint32_t c2 = 0x1b873593;
4201 static const uint32_t r1 = 15;
4202 static const uint32_t r2 = 13;
4203 static const uint32_t m = 5;
4204 static const uint32_t n = 0xe6546b64;
4205
4206 uint32_t hash = 0;
4207
4208 #define mix(input) { \
4209 uint32_t v = input; \
4210 v *= c1; \
4211 v = (v << r1) | (v >> (32 - r1)); \
4212 v *= c2; \
4213 hash ^= v; \
4214 hash = (hash << r2) | (hash >> (32 - r2)); \
4215 hash = hash * m + n; \
4216 }
4217
4218 mix(k->target_class);
4219 mix(k->target_type);
4220 mix(k->source_type);
4221 mix(k->specified);
4222
4223 #undef mix
4224
4225 hash ^= hash >> 16;
4226 hash *= 0x85ebca6b;
4227 hash ^= hash >> 13;
4228 hash *= 0xc2b2ae35;
4229 hash ^= hash >> 16;
4230
4231 return hash & (AVRULEX_TABLE_SIZE - 1);
4232 }
4233
avrulex_compare(hashtab_t h,const_hashtab_key_t key1,const_hashtab_key_t key2)4234 static int avrulex_compare(hashtab_t h
4235 __attribute__ ((unused)), const_hashtab_key_t key1,
4236 const_hashtab_key_t key2)
4237 {
4238 const avtab_key_t *a = (const avtab_key_t *)key1;
4239 const avtab_key_t *b = (const avtab_key_t *)key2;
4240
4241 return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class || a->specified != b->specified;
4242 }
4243
cil_binary_create(const struct cil_db * db,sepol_policydb_t ** policydb)4244 int cil_binary_create(const struct cil_db *db, sepol_policydb_t **policydb)
4245 {
4246 int rc = SEPOL_ERR;
4247 struct sepol_policydb *pdb = NULL;
4248
4249 rc = __cil_policydb_create(db, &pdb);
4250 if (rc != SEPOL_OK) {
4251 goto exit;
4252 }
4253
4254 rc = cil_binary_create_allocated_pdb(db, pdb);
4255 if (rc != SEPOL_OK) {
4256 goto exit;
4257 }
4258
4259 *policydb = pdb;
4260
4261 return SEPOL_OK;
4262
4263 exit:
4264 sepol_policydb_free(pdb);
4265
4266 return rc;
4267 }
4268
__cil_destroy_sepol_class_perms(class_perm_node_t * curr)4269 static void __cil_destroy_sepol_class_perms(class_perm_node_t *curr)
4270 {
4271 class_perm_node_t *next;
4272
4273 while (curr) {
4274 next = curr->next;
4275 free(curr);
4276 curr = next;
4277 }
4278 }
4279
__cil_rule_to_sepol_class_perms(policydb_t * pdb,struct cil_list * classperms,class_perm_node_t ** sepol_class_perms)4280 static int __cil_rule_to_sepol_class_perms(policydb_t *pdb, struct cil_list *classperms, class_perm_node_t **sepol_class_perms)
4281 {
4282 int rc = SEPOL_ERR;
4283 struct cil_list_item *i;
4284 cil_list_for_each(i, classperms) {
4285 if (i->flavor == CIL_CLASSPERMS) {
4286 struct cil_classperms *cp = i->data;
4287 if (FLAVOR(cp->class) == CIL_CLASS) {
4288 class_perm_node_t *cpn = NULL;
4289 class_datum_t *sepol_class = NULL;
4290 uint32_t data = 0;
4291
4292 rc = __cil_get_sepol_class_datum(pdb, DATUM(cp->class), &sepol_class);
4293 if (rc != SEPOL_OK) goto exit;
4294
4295 rc = __cil_perms_to_datum(cp->perms, sepol_class, &data);
4296 if (rc != SEPOL_OK) goto exit;
4297 if (data == 0) {
4298 /* No permissions */
4299 return SEPOL_OK;
4300 }
4301 cpn = cil_malloc(sizeof(class_perm_node_t));
4302 cpn->tclass = sepol_class->s.value;
4303 cpn->data = data;
4304 cpn->next = *sepol_class_perms;
4305 *sepol_class_perms = cpn;
4306 } else { /* MAP */
4307 struct cil_list_item *j = NULL;
4308 cil_list_for_each(j, cp->perms) {
4309 struct cil_perm *cmp = j->data;
4310 rc = __cil_rule_to_sepol_class_perms(pdb, cmp->classperms, sepol_class_perms);
4311 if (rc != SEPOL_OK) {
4312 goto exit;
4313 }
4314 }
4315 }
4316 } else { /* SET */
4317 struct cil_classperms_set *cp_set = i->data;
4318 struct cil_classpermission *cp = cp_set->set;
4319 rc = __cil_rule_to_sepol_class_perms(pdb, cp->classperms, sepol_class_perms);
4320 if (rc != SEPOL_OK) {
4321 goto exit;
4322 }
4323 }
4324 }
4325 return SEPOL_OK;
4326
4327 exit:
4328 return rc;
4329 }
4330
__cil_permx_to_sepol_class_perms(policydb_t * pdb,struct cil_permissionx * permx,class_perm_node_t ** sepol_class_perms)4331 static int __cil_permx_to_sepol_class_perms(policydb_t *pdb, struct cil_permissionx *permx, class_perm_node_t **sepol_class_perms)
4332 {
4333 int rc = SEPOL_OK;
4334 struct cil_list *class_list = NULL;
4335 struct cil_list_item *c;
4336 class_datum_t *sepol_obj = NULL;
4337 class_perm_node_t *cpn;
4338 uint32_t data = 0;
4339 char *perm_str = NULL;
4340
4341 class_list = cil_expand_class(permx->obj);
4342
4343 cil_list_for_each(c, class_list) {
4344 rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);
4345 if (rc != SEPOL_OK) {
4346 goto exit;
4347 }
4348
4349 switch (permx->kind) {
4350 case CIL_PERMX_KIND_IOCTL:
4351 perm_str = CIL_KEY_IOCTL;
4352 break;
4353 default:
4354 rc = SEPOL_ERR;
4355 goto exit;
4356 }
4357
4358 rc = __perm_str_to_datum(perm_str, sepol_obj, &data);
4359 if (rc != SEPOL_OK) {
4360 goto exit;
4361 }
4362
4363 cpn = cil_malloc(sizeof(*cpn));
4364 cpn->tclass = sepol_obj->s.value;
4365 cpn->data = data;
4366 cpn->next = *sepol_class_perms;
4367 *sepol_class_perms = cpn;
4368 }
4369
4370 exit:
4371 cil_list_destroy(&class_list, CIL_FALSE);
4372
4373 return rc;
4374 }
4375
__cil_init_sepol_type_set(type_set_t * t)4376 static void __cil_init_sepol_type_set(type_set_t *t)
4377 {
4378 ebitmap_init(&t->types);
4379 ebitmap_init(&t->negset);
4380 t->flags = 0;
4381 }
4382
__cil_add_sepol_type(policydb_t * pdb,const struct cil_db * db,struct cil_symtab_datum * datum,ebitmap_t * map)4383 static int __cil_add_sepol_type(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *datum, ebitmap_t *map)
4384 {
4385 int rc = SEPOL_ERR;
4386 struct cil_tree_node *n = datum->nodes->head->data;
4387 type_datum_t *sepol_datum = NULL;
4388
4389 if (n->flavor == CIL_TYPEATTRIBUTE) {
4390 ebitmap_node_t *tnode;
4391 unsigned int i;
4392 struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
4393 ebitmap_for_each_bit(attr->types, tnode, i) {
4394 if (!ebitmap_get_bit(attr->types, i)) continue;
4395 datum = DATUM(db->val_to_type[i]);
4396 rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum);
4397 if (rc != SEPOL_OK) goto exit;
4398 ebitmap_set_bit(map, sepol_datum->s.value - 1, 1);
4399 }
4400 } else {
4401 rc = __cil_get_sepol_type_datum(pdb, datum, &sepol_datum);
4402 if (rc != SEPOL_OK) goto exit;
4403 ebitmap_set_bit(map, sepol_datum->s.value - 1, 1);
4404 }
4405
4406 return SEPOL_OK;
4407
4408 exit:
4409 return rc;
4410 }
4411
__cil_init_sepol_avrule(uint32_t kind,struct cil_tree_node * node)4412 static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *node)
4413 {
4414 avrule_t *avrule;
4415 struct cil_tree_node *source_node;
4416 char *source_path;
4417 int is_cil;
4418
4419 avrule = cil_malloc(sizeof(avrule_t));
4420 avrule->specified = kind;
4421 avrule->flags = 0;
4422 __cil_init_sepol_type_set(&avrule->stypes);
4423 __cil_init_sepol_type_set(&avrule->ttypes);
4424 avrule->perms = NULL;
4425 avrule->line = node->line;
4426
4427 avrule->source_filename = NULL;
4428 avrule->source_line = node->line;
4429 source_node = cil_tree_get_next_path(node, &source_path, &is_cil);
4430 if (source_node) {
4431 avrule->source_filename = source_path;
4432 if (!is_cil) {
4433 avrule->source_line = node->hll_line;
4434 }
4435 }
4436
4437 avrule->next = NULL;
4438 return avrule;
4439 }
4440
__cil_destroy_sepol_avrules(avrule_t * curr)4441 static void __cil_destroy_sepol_avrules(avrule_t *curr)
4442 {
4443 avrule_t *next;
4444
4445 while (curr) {
4446 next = curr->next;
4447 ebitmap_destroy(&curr->stypes.types);
4448 ebitmap_destroy(&curr->stypes.negset);
4449 ebitmap_destroy(&curr->ttypes.types);
4450 ebitmap_destroy(&curr->ttypes.negset);
4451 __cil_destroy_sepol_class_perms(curr->perms);
4452 free(curr);
4453 curr = next;
4454 }
4455 }
4456
__cil_print_parents(const char * pad,struct cil_tree_node * n)4457 static void __cil_print_parents(const char *pad, struct cil_tree_node *n)
4458 {
4459 if (!n) return;
4460
4461 __cil_print_parents(pad, n->parent);
4462
4463 if (n->flavor != CIL_SRC_INFO) {
4464 cil_tree_log(n, CIL_ERR,"%s%s", pad, cil_node_to_string(n));
4465 }
4466 }
4467
__cil_print_classperm(struct cil_list * cp_list)4468 static void __cil_print_classperm(struct cil_list *cp_list)
4469 {
4470 struct cil_list_item *i1, *i2;
4471
4472 i1 = cp_list->head;
4473 if (i1->flavor == CIL_CLASSPERMS) {
4474 struct cil_classperms *cp = i1->data;
4475 cil_log(CIL_ERR,"(%s (", DATUM(cp->class)->fqn);
4476 cil_list_for_each(i2, cp->perms) {
4477 cil_log(CIL_ERR,"%s",DATUM(i2->data)->fqn);
4478 if (i2 != cp->perms->tail) {
4479 cil_log(CIL_ERR," ");
4480 } else {
4481 cil_log(CIL_ERR,"))");
4482 }
4483 }
4484 } else {
4485 struct cil_classperms_set *cp_set = i1->data;
4486 cil_log(CIL_ERR,"%s", DATUM(cp_set->set)->fqn);
4487 }
4488 }
4489
__cil_print_permissionx(struct cil_permissionx * px)4490 static void __cil_print_permissionx(struct cil_permissionx *px)
4491 {
4492 const char *kind_str = "";
4493 char *expr_str;
4494
4495 switch (px->kind) {
4496 case CIL_PERMX_KIND_IOCTL:
4497 kind_str = CIL_KEY_IOCTL;
4498 break;
4499 default:
4500 kind_str = "unknown";
4501 break;
4502 }
4503
4504 __cil_expr_to_string(px->expr_str, CIL_PERMISSIONX, &expr_str);
4505
4506 cil_log(CIL_ERR, "%s %s (%s)", kind_str, DATUM(px->obj)->fqn, expr_str);
4507
4508 free(expr_str);
4509 }
4510
__cil_print_rule(const char * pad,const char * kind,struct cil_avrule * avrule)4511 static void __cil_print_rule(const char *pad, const char *kind, struct cil_avrule *avrule)
4512 {
4513 cil_log(CIL_ERR,"%s(%s ", pad, kind);
4514 cil_log(CIL_ERR,"%s %s ", DATUM(avrule->src)->fqn, DATUM(avrule->tgt)->fqn);
4515
4516 if (!avrule->is_extended) {
4517 __cil_print_classperm(avrule->perms.classperms);
4518 } else {
4519 cil_log(CIL_ERR, "(");
4520 __cil_print_permissionx(avrule->perms.x.permx);
4521 cil_log(CIL_ERR, ")");
4522 }
4523
4524 cil_log(CIL_ERR,")\n");
4525 }
4526
__cil_print_neverallow_failure(const struct cil_db * db,struct cil_tree_node * node)4527 static int __cil_print_neverallow_failure(const struct cil_db *db, struct cil_tree_node *node)
4528 {
4529 int rc;
4530 struct cil_list_item *i2;
4531 struct cil_list *matching;
4532 struct cil_avrule *cil_rule = node->data;
4533 struct cil_avrule target;
4534 struct cil_tree_node *n2;
4535 struct cil_avrule *r2;
4536 char *neverallow_str;
4537 char *allow_str;
4538 enum cil_flavor avrule_flavor;
4539
4540 target.rule_kind = CIL_AVRULE_ALLOWED;
4541 target.is_extended = cil_rule->is_extended;
4542 target.src = cil_rule->src;
4543 target.tgt = cil_rule->tgt;
4544 target.perms = cil_rule->perms;
4545
4546 if (!cil_rule->is_extended) {
4547 neverallow_str = CIL_KEY_NEVERALLOW;
4548 allow_str = CIL_KEY_ALLOW;
4549 avrule_flavor = CIL_AVRULE;
4550 } else {
4551 neverallow_str = CIL_KEY_NEVERALLOWX;
4552 allow_str = CIL_KEY_ALLOWX;
4553 avrule_flavor = CIL_AVRULEX;
4554 }
4555 cil_tree_log(node, CIL_ERR, "%s check failed", neverallow_str);
4556 __cil_print_rule(" ", neverallow_str, cil_rule);
4557 cil_list_init(&matching, CIL_NODE);
4558 rc = cil_find_matching_avrule_in_ast(db->ast->root, avrule_flavor, &target, matching, CIL_FALSE);
4559 if (rc) {
4560 cil_log(CIL_ERR, "Error occurred while checking %s rules\n", neverallow_str);
4561 cil_list_destroy(&matching, CIL_FALSE);
4562 goto exit;
4563 }
4564
4565 cil_list_for_each(i2, matching) {
4566 n2 = i2->data;
4567 r2 = n2->data;
4568 __cil_print_parents(" ", n2);
4569 __cil_print_rule(" ", allow_str, r2);
4570 }
4571 cil_log(CIL_ERR,"\n");
4572 cil_list_destroy(&matching, CIL_FALSE);
4573
4574 exit:
4575 return rc;
4576 }
4577
cil_check_neverallow(const struct cil_db * db,policydb_t * pdb,struct cil_tree_node * node,int * violation)4578 static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node, int *violation)
4579 {
4580 int rc = SEPOL_OK;
4581 struct cil_avrule *cil_rule = node->data;
4582 struct cil_symtab_datum *tgt = cil_rule->tgt;
4583 uint32_t kind;
4584 avrule_t *rule;
4585 struct cil_list *xperms = NULL;
4586 struct cil_list_item *item;
4587
4588 if (!cil_rule->is_extended) {
4589 kind = AVRULE_NEVERALLOW;
4590 } else {
4591 kind = AVRULE_XPERMS_NEVERALLOW;
4592 }
4593
4594 rule = __cil_init_sepol_avrule(kind, node);
4595 rule->next = NULL;
4596
4597 rc = __cil_add_sepol_type(pdb, db, cil_rule->src, &rule->stypes.types);
4598 if (rc != SEPOL_OK) {
4599 goto exit;
4600 }
4601
4602 if (tgt->fqn == CIL_KEY_SELF) {
4603 rule->flags = RULE_SELF;
4604 } else {
4605 rc = __cil_add_sepol_type(pdb, db, cil_rule->tgt, &rule->ttypes.types);
4606 if (rc != SEPOL_OK) {
4607 goto exit;
4608 }
4609 }
4610
4611 if (!cil_rule->is_extended) {
4612 rc = __cil_rule_to_sepol_class_perms(pdb, cil_rule->perms.classperms, &rule->perms);
4613 if (rc != SEPOL_OK) {
4614 goto exit;
4615 }
4616
4617 rc = check_assertion(pdb, rule);
4618 if (rc == CIL_TRUE) {
4619 *violation = CIL_TRUE;
4620 rc = __cil_print_neverallow_failure(db, node);
4621 if (rc != SEPOL_OK) {
4622 goto exit;
4623 }
4624 }
4625
4626 } else {
4627 rc = __cil_permx_to_sepol_class_perms(pdb, cil_rule->perms.x.permx, &rule->perms);
4628 if (rc != SEPOL_OK) {
4629 goto exit;
4630 }
4631
4632 rc = __cil_permx_bitmap_to_sepol_xperms_list(cil_rule->perms.x.permx->perms, &xperms);
4633 if (rc != SEPOL_OK) {
4634 goto exit;
4635 }
4636
4637 cil_list_for_each(item, xperms) {
4638 rule->xperms = item->data;
4639 rc = check_assertion(pdb, rule);
4640 if (rc == CIL_TRUE) {
4641 *violation = CIL_TRUE;
4642 rc = __cil_print_neverallow_failure(db, node);
4643 if (rc != SEPOL_OK) {
4644 goto exit;
4645 }
4646 }
4647 }
4648 }
4649
4650 exit:
4651 if (xperms != NULL) {
4652 cil_list_for_each(item, xperms) {
4653 free(item->data);
4654 item->data = NULL;
4655 }
4656 cil_list_destroy(&xperms, CIL_FALSE);
4657 }
4658
4659 rule->xperms = NULL;
4660 __cil_destroy_sepol_avrules(rule);
4661
4662 return rc;
4663 }
4664
cil_check_neverallows(const struct cil_db * db,policydb_t * pdb,struct cil_list * neverallows,int * violation)4665 static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows, int *violation)
4666 {
4667 int rc = SEPOL_OK;
4668 struct cil_list_item *item;
4669
4670 cil_list_for_each(item, neverallows) {
4671 rc = cil_check_neverallow(db, pdb, item->data, violation);
4672 if (rc != SEPOL_OK) {
4673 goto exit;
4674 }
4675 }
4676
4677 exit:
4678 return rc;
4679 }
4680
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[])4681 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[])
4682 {
4683 struct cil_classperms *cp;
4684 struct cil_list *cp_list;
4685 class_datum_t *sepol_class = pdb->class_val_to_struct[class - 1];
4686 unsigned i;
4687
4688 cil_classperms_init(&cp);
4689
4690 cp->class = class_value_to_cil[class];
4691 if (!cp->class) goto exit;
4692
4693 cil_list_init(&cp->perms, CIL_PERM);
4694 for (i = 0; i < sepol_class->permissions.nprim; i++) {
4695 struct cil_perm *perm;
4696 if ((data & (1 << i)) == 0) continue;
4697 perm = perm_value_to_cil[class][i+1];
4698 if (!perm) goto exit;
4699 cil_list_append(cp->perms, CIL_PERM, perm);
4700 }
4701
4702 cil_list_init(&cp_list, CIL_CLASSPERMS);
4703 cil_list_append(cp_list, CIL_CLASSPERMS, cp);
4704
4705 return cp_list;
4706
4707 exit:
4708 cil_log(CIL_ERR,"Failed to create CIL class-permissions from sepol values\n");
4709 return NULL;
4710 }
4711
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[])4712 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[])
4713 {
4714 int rc = SEPOL_ERR;
4715 avtab_key_t *k = &sepol_rule->key;
4716 avtab_datum_t *d = &sepol_rule->datum;
4717 cil_rule->src = type_value_to_cil[k->source_type];
4718 if (!cil_rule->src) goto exit;
4719
4720 cil_rule->tgt = type_value_to_cil[k->target_type];
4721 if (!cil_rule->tgt) goto exit;
4722
4723 cil_rule->perms.classperms = cil_classperms_from_sepol(pdb, k->target_class, d->data, class_value_to_cil, perm_value_to_cil);
4724 if (!cil_rule->perms.classperms) goto exit;
4725
4726 return SEPOL_OK;
4727
4728 exit:
4729 cil_log(CIL_ERR,"Failed to create CIL AV rule from sepol values\n");
4730 return rc;
4731 }
4732
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)4733 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)
4734 {
4735 int rc = SEPOL_OK;
4736 int i;
4737
4738 for (i = 0; i < db->num_types; i++) {
4739 type_datum_t *child;
4740 type_datum_t *parent;
4741 avtab_ptr_t bad = NULL;
4742 int numbad = 0;
4743 struct cil_type *t = db->val_to_type[i];
4744
4745 if (!t->bounds) continue;
4746
4747 rc = __cil_get_sepol_type_datum(pdb, DATUM(t), &child);
4748 if (rc != SEPOL_OK) goto exit;
4749
4750 rc = __cil_get_sepol_type_datum(pdb, DATUM(t->bounds), &parent);
4751 if (rc != SEPOL_OK) goto exit;
4752
4753 rc = bounds_check_type(NULL, pdb, child->s.value, parent->s.value, &bad, &numbad);
4754 if (rc != SEPOL_OK) goto exit;
4755
4756 if (bad) {
4757 avtab_ptr_t cur;
4758 struct cil_avrule target;
4759 struct cil_tree_node *n1 = NULL;
4760
4761 *violation = CIL_TRUE;
4762
4763 target.is_extended = 0;
4764 target.rule_kind = CIL_AVRULE_ALLOWED;
4765 target.src_str = NULL;
4766 target.tgt_str = NULL;
4767
4768 cil_log(CIL_ERR, "Child type %s exceeds bounds of parent %s\n",
4769 t->datum.fqn, t->bounds->datum.fqn);
4770 for (cur = bad; cur; cur = cur->next) {
4771 struct cil_list_item *i2;
4772 struct cil_list *matching;
4773
4774 rc = cil_avrule_from_sepol(pdb, cur, &target, type_value_to_cil, class_value_to_cil, perm_value_to_cil);
4775 if (rc != SEPOL_OK) {
4776 cil_log(CIL_ERR, "Failed to convert sepol avrule to CIL\n");
4777 goto exit;
4778 }
4779 __cil_print_rule(" ", "allow", &target);
4780 cil_list_init(&matching, CIL_NODE);
4781 rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_TRUE);
4782 if (rc) {
4783 cil_log(CIL_ERR, "Error occurred while checking type bounds\n");
4784 cil_list_destroy(&matching, CIL_FALSE);
4785 cil_list_destroy(&target.perms.classperms, CIL_TRUE);
4786 bounds_destroy_bad(bad);
4787 goto exit;
4788 }
4789 cil_list_for_each(i2, matching) {
4790 struct cil_tree_node *n2 = i2->data;
4791 struct cil_avrule *r2 = n2->data;
4792 if (n1 == n2) {
4793 cil_log(CIL_ERR, " <See previous>\n");
4794 } else {
4795 n1 = n2;
4796 __cil_print_parents(" ", n2);
4797 __cil_print_rule(" ", "allow", r2);
4798 }
4799 }
4800 cil_list_destroy(&matching, CIL_FALSE);
4801 cil_list_destroy(&target.perms.classperms, CIL_TRUE);
4802 }
4803 bounds_destroy_bad(bad);
4804 }
4805 }
4806
4807 exit:
4808 return rc;
4809 }
4810
4811 // assumes policydb is already allocated and initialized properly with things
4812 // like policy type set to kernel and version set appropriately
cil_binary_create_allocated_pdb(const struct cil_db * db,sepol_policydb_t * policydb)4813 int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *policydb)
4814 {
4815 int rc = SEPOL_ERR;
4816 int i;
4817 struct cil_args_binary extra_args;
4818 policydb_t *pdb = &policydb->p;
4819 struct cil_list *neverallows = NULL;
4820 hashtab_t filename_trans_table = NULL;
4821 hashtab_t range_trans_table = NULL;
4822 hashtab_t role_trans_table = NULL;
4823 hashtab_t avrulex_ioctl_table = NULL;
4824 void **type_value_to_cil = NULL;
4825 struct cil_class **class_value_to_cil = NULL;
4826 struct cil_perm ***perm_value_to_cil = NULL;
4827
4828 if (db == NULL || policydb == NULL) {
4829 if (db == NULL) {
4830 cil_log(CIL_ERR,"db == NULL\n");
4831 } else if (policydb == NULL) {
4832 cil_log(CIL_ERR,"policydb == NULL\n");
4833 }
4834 return SEPOL_ERR;
4835 }
4836
4837 /* libsepol values start at 1. Just allocate extra memory rather than
4838 * subtract 1 from the sepol value.
4839 */
4840 type_value_to_cil = calloc(db->num_types_and_attrs+1, sizeof(*type_value_to_cil));
4841 if (!type_value_to_cil) goto exit;
4842
4843 class_value_to_cil = calloc(db->num_classes+1, sizeof(*class_value_to_cil));
4844 if (!class_value_to_cil) goto exit;
4845
4846 perm_value_to_cil = calloc(db->num_classes+1, sizeof(*perm_value_to_cil));
4847 if (!perm_value_to_cil) goto exit;
4848 for (i=1; i < db->num_classes+1; i++) {
4849 perm_value_to_cil[i] = calloc(PERMS_PER_CLASS+1, sizeof(*perm_value_to_cil[i]));
4850 if (!perm_value_to_cil[i]) goto exit;
4851 }
4852
4853 rc = __cil_policydb_init(pdb, db, class_value_to_cil, perm_value_to_cil);
4854 if (rc != SEPOL_OK) {
4855 cil_log(CIL_ERR,"Problem in policydb_init\n");
4856 goto exit;
4857 }
4858
4859 filename_trans_table = hashtab_create(filename_trans_hash, filename_trans_compare, FILENAME_TRANS_TABLE_SIZE);
4860 if (!filename_trans_table) {
4861 cil_log(CIL_INFO, "Failure to create hashtab for filename_trans\n");
4862 goto exit;
4863 }
4864
4865 range_trans_table = hashtab_create(range_trans_hash, range_trans_compare, RANGE_TRANS_TABLE_SIZE);
4866 if (!range_trans_table) {
4867 cil_log(CIL_INFO, "Failure to create hashtab for range_trans\n");
4868 goto exit;
4869 }
4870
4871 role_trans_table = hashtab_create(role_trans_hash, role_trans_compare, ROLE_TRANS_TABLE_SIZE);
4872 if (!role_trans_table) {
4873 cil_log(CIL_INFO, "Failure to create hashtab for role_trans\n");
4874 goto exit;
4875 }
4876
4877 avrulex_ioctl_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE);
4878 if (!avrulex_ioctl_table) {
4879 cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n");
4880 goto exit;
4881 }
4882
4883 cil_list_init(&neverallows, CIL_LIST_ITEM);
4884
4885 extra_args.db = db;
4886 extra_args.pdb = pdb;
4887 extra_args.neverallows = neverallows;
4888 extra_args.filename_trans_table = filename_trans_table;
4889 extra_args.range_trans_table = range_trans_table;
4890 extra_args.role_trans_table = role_trans_table;
4891 extra_args.avrulex_ioctl_table = avrulex_ioctl_table;
4892 extra_args.type_value_to_cil = type_value_to_cil;
4893
4894 for (i = 1; i <= 3; i++) {
4895 extra_args.pass = i;
4896
4897 rc = cil_tree_walk(db->ast->root, __cil_binary_create_helper, NULL, NULL, &extra_args);
4898 if (rc != SEPOL_OK) {
4899 cil_log(CIL_INFO, "Failure while walking cil database\n");
4900 goto exit;
4901 }
4902
4903 if (i == 1) {
4904 rc = __cil_policydb_val_arrays_create(pdb);
4905 if (rc != SEPOL_OK) {
4906 cil_log(CIL_INFO, "Failure creating val_to_{struct,name} arrays\n");
4907 goto exit;
4908 }
4909 }
4910
4911 if (i == 3) {
4912 rc = hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_to_policydb, pdb);
4913 if (rc != SEPOL_OK) {
4914 cil_log(CIL_INFO, "Failure creating avrulex rules\n");
4915 goto exit;
4916 }
4917 }
4918 }
4919
4920 rc = cil_sidorder_to_policydb(pdb, db);
4921 if (rc != SEPOL_OK) {
4922 goto exit;
4923 }
4924
4925 rc = __cil_contexts_to_policydb(pdb, db);
4926 if (rc != SEPOL_OK) {
4927 cil_log(CIL_INFO, "Failure while inserting cil contexts into sepol policydb\n");
4928 goto exit;
4929 }
4930
4931 if (pdb->type_attr_map == NULL) {
4932 rc = __cil_typeattr_bitmap_init(pdb);
4933 if (rc != SEPOL_OK) {
4934 cil_log(CIL_INFO, "Failure while initializing typeattribute bitmap\n");
4935 goto exit;
4936 }
4937 }
4938
4939 cond_optimize_lists(pdb->cond_list);
4940 __cil_set_conditional_state_and_flags(pdb);
4941
4942 if (db->disable_neverallow != CIL_TRUE) {
4943 int violation = CIL_FALSE;
4944 cil_log(CIL_INFO, "Checking Neverallows\n");
4945 rc = cil_check_neverallows(db, pdb, neverallows, &violation);
4946 if (rc != SEPOL_OK) goto exit;
4947
4948 cil_log(CIL_INFO, "Checking User Bounds\n");
4949 rc = bounds_check_users(NULL, pdb);
4950 if (rc) {
4951 violation = CIL_TRUE;
4952 }
4953
4954 cil_log(CIL_INFO, "Checking Role Bounds\n");
4955 rc = bounds_check_roles(NULL, pdb);
4956 if (rc) {
4957 violation = CIL_TRUE;
4958 }
4959
4960 cil_log(CIL_INFO, "Checking Type Bounds\n");
4961 rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil, &violation);
4962 if (rc != SEPOL_OK) goto exit;
4963
4964 if (violation == CIL_TRUE) {
4965 rc = SEPOL_ERR;
4966 goto exit;
4967 }
4968
4969 }
4970
4971 /* This pre-expands the roles and users for context validity checking */
4972 if (hashtab_map(pdb->p_roles.table, policydb_role_cache, pdb)) {
4973 cil_log(CIL_INFO, "Failure creating roles cache");
4974 rc = SEPOL_ERR;
4975 goto exit;
4976 }
4977
4978 if (hashtab_map(pdb->p_users.table, policydb_user_cache, pdb)) {
4979 cil_log(CIL_INFO, "Failure creating users cache");
4980 rc = SEPOL_ERR;
4981 goto exit;
4982 }
4983
4984 rc = SEPOL_OK;
4985
4986 exit:
4987 hashtab_destroy(filename_trans_table);
4988 hashtab_destroy(range_trans_table);
4989 hashtab_destroy(role_trans_table);
4990 hashtab_destroy(avrulex_ioctl_table);
4991 free(type_value_to_cil);
4992 free(class_value_to_cil);
4993 /* Range is because libsepol values start at 1. */
4994 for (i=1; i < db->num_classes+1; i++) {
4995 free(perm_value_to_cil[i]);
4996 }
4997 free(perm_value_to_cil);
4998 cil_list_destroy(&neverallows, CIL_FALSE);
4999
5000 return rc;
5001 }
5002