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