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