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