Bug Summary

File:project/libsepol/src/../cil/src/cil_binary.c
Warning:line 5048, column 8
Array access (from variable 'perm_value_to_cil') results in a null pointer dereference

Annotated Source Code

Press '?' to see keyboard shortcuts

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