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 <string.h>
33*2d543d20SAndroid Build Coastguard Worker #include <stdint.h>
34*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
35*2d543d20SAndroid Build Coastguard Worker #include <ctype.h>
36*2d543d20SAndroid Build Coastguard Worker
37*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/polcaps.h>
38*2d543d20SAndroid Build Coastguard Worker #include <sepol/errcodes.h>
39*2d543d20SAndroid Build Coastguard Worker
40*2d543d20SAndroid Build Coastguard Worker #include "cil_internal.h"
41*2d543d20SAndroid Build Coastguard Worker #include "cil_flavor.h"
42*2d543d20SAndroid Build Coastguard Worker #include "cil_log.h"
43*2d543d20SAndroid Build Coastguard Worker #include "cil_mem.h"
44*2d543d20SAndroid Build Coastguard Worker #include "cil_tree.h"
45*2d543d20SAndroid Build Coastguard Worker #include "cil_list.h"
46*2d543d20SAndroid Build Coastguard Worker #include "cil_find.h"
47*2d543d20SAndroid Build Coastguard Worker #include "cil_stack.h"
48*2d543d20SAndroid Build Coastguard Worker
49*2d543d20SAndroid Build Coastguard Worker #include "cil_verify.h"
50*2d543d20SAndroid Build Coastguard Worker
__cil_is_reserved_name(const char * name,enum cil_flavor flavor)51*2d543d20SAndroid Build Coastguard Worker static int __cil_is_reserved_name(const char *name, enum cil_flavor flavor)
52*2d543d20SAndroid Build Coastguard Worker {
53*2d543d20SAndroid Build Coastguard Worker switch (flavor) {
54*2d543d20SAndroid Build Coastguard Worker case CIL_BOOL:
55*2d543d20SAndroid Build Coastguard Worker case CIL_TUNABLE:
56*2d543d20SAndroid Build Coastguard Worker if ((name == CIL_KEY_EQ) || (name == CIL_KEY_NEQ))
57*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
58*2d543d20SAndroid Build Coastguard Worker break;
59*2d543d20SAndroid Build Coastguard Worker case CIL_PERM:
60*2d543d20SAndroid Build Coastguard Worker case CIL_MAP_PERM:
61*2d543d20SAndroid Build Coastguard Worker case CIL_USER:
62*2d543d20SAndroid Build Coastguard Worker case CIL_USERATTRIBUTE:
63*2d543d20SAndroid Build Coastguard Worker case CIL_ROLE:
64*2d543d20SAndroid Build Coastguard Worker case CIL_ROLEATTRIBUTE:
65*2d543d20SAndroid Build Coastguard Worker if (name == CIL_KEY_ALL)
66*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
67*2d543d20SAndroid Build Coastguard Worker break;
68*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE:
69*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEATTRIBUTE:
70*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEALIAS:
71*2d543d20SAndroid Build Coastguard Worker if ((name == CIL_KEY_ALL) || (name == CIL_KEY_SELF) || (name == CIL_KEY_NOTSELF)
72*2d543d20SAndroid Build Coastguard Worker || (name == CIL_KEY_OTHER))
73*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
74*2d543d20SAndroid Build Coastguard Worker break;
75*2d543d20SAndroid Build Coastguard Worker case CIL_CAT:
76*2d543d20SAndroid Build Coastguard Worker case CIL_CATSET:
77*2d543d20SAndroid Build Coastguard Worker case CIL_CATALIAS:
78*2d543d20SAndroid Build Coastguard Worker case CIL_PERMISSIONX:
79*2d543d20SAndroid Build Coastguard Worker if ((name == CIL_KEY_ALL) || (name == CIL_KEY_RANGE))
80*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
81*2d543d20SAndroid Build Coastguard Worker break;
82*2d543d20SAndroid Build Coastguard Worker default:
83*2d543d20SAndroid Build Coastguard Worker /* All of these are not used in expressions */
84*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
85*2d543d20SAndroid Build Coastguard Worker break;
86*2d543d20SAndroid Build Coastguard Worker }
87*2d543d20SAndroid Build Coastguard Worker
88*2d543d20SAndroid Build Coastguard Worker /* Everything not under the default case is also checked for these */
89*2d543d20SAndroid Build Coastguard Worker if ((name == CIL_KEY_AND) || (name == CIL_KEY_OR) || (name == CIL_KEY_NOT) || (name == CIL_KEY_XOR)) {
90*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
91*2d543d20SAndroid Build Coastguard Worker }
92*2d543d20SAndroid Build Coastguard Worker
93*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
94*2d543d20SAndroid Build Coastguard Worker }
95*2d543d20SAndroid Build Coastguard Worker
cil_verify_name(const struct cil_db * db,const char * name,enum cil_flavor flavor)96*2d543d20SAndroid Build Coastguard Worker int cil_verify_name(const struct cil_db *db, const char *name, enum cil_flavor flavor)
97*2d543d20SAndroid Build Coastguard Worker {
98*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
99*2d543d20SAndroid Build Coastguard Worker int len;
100*2d543d20SAndroid Build Coastguard Worker int i = 0;
101*2d543d20SAndroid Build Coastguard Worker
102*2d543d20SAndroid Build Coastguard Worker if (name == NULL) {
103*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Name is NULL\n");
104*2d543d20SAndroid Build Coastguard Worker goto exit;
105*2d543d20SAndroid Build Coastguard Worker }
106*2d543d20SAndroid Build Coastguard Worker
107*2d543d20SAndroid Build Coastguard Worker len = strlen(name);
108*2d543d20SAndroid Build Coastguard Worker if (len >= CIL_MAX_NAME_LENGTH) {
109*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Name length greater than max name length of %d",
110*2d543d20SAndroid Build Coastguard Worker CIL_MAX_NAME_LENGTH);
111*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
112*2d543d20SAndroid Build Coastguard Worker goto exit;
113*2d543d20SAndroid Build Coastguard Worker }
114*2d543d20SAndroid Build Coastguard Worker
115*2d543d20SAndroid Build Coastguard Worker if (!isalpha(name[0])) {
116*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "First character in %s is not a letter\n", name);
117*2d543d20SAndroid Build Coastguard Worker goto exit;
118*2d543d20SAndroid Build Coastguard Worker }
119*2d543d20SAndroid Build Coastguard Worker
120*2d543d20SAndroid Build Coastguard Worker if (db->qualified_names == CIL_FALSE) {
121*2d543d20SAndroid Build Coastguard Worker for (i = 1; i < len; i++) {
122*2d543d20SAndroid Build Coastguard Worker if (!isalnum(name[i]) && name[i] != '_' && name[i] != '-') {
123*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Invalid character \"%c\" in %s\n", name[i], name);
124*2d543d20SAndroid Build Coastguard Worker goto exit;
125*2d543d20SAndroid Build Coastguard Worker }
126*2d543d20SAndroid Build Coastguard Worker }
127*2d543d20SAndroid Build Coastguard Worker } else {
128*2d543d20SAndroid Build Coastguard Worker for (i = 1; i < len; i++) {
129*2d543d20SAndroid Build Coastguard Worker if (!isalnum(name[i]) && name[i] != '_' && name[i] != '-' && name[i] != '.') {
130*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Invalid character \"%c\" in %s\n", name[i], name);
131*2d543d20SAndroid Build Coastguard Worker goto exit;
132*2d543d20SAndroid Build Coastguard Worker }
133*2d543d20SAndroid Build Coastguard Worker }
134*2d543d20SAndroid Build Coastguard Worker }
135*2d543d20SAndroid Build Coastguard Worker
136*2d543d20SAndroid Build Coastguard Worker if (__cil_is_reserved_name(name, flavor)) {
137*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Name %s is a reserved word\n", name);
138*2d543d20SAndroid Build Coastguard Worker goto exit;
139*2d543d20SAndroid Build Coastguard Worker }
140*2d543d20SAndroid Build Coastguard Worker
141*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
142*2d543d20SAndroid Build Coastguard Worker
143*2d543d20SAndroid Build Coastguard Worker exit:
144*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Invalid name\n");
145*2d543d20SAndroid Build Coastguard Worker return rc;
146*2d543d20SAndroid Build Coastguard Worker }
147*2d543d20SAndroid Build Coastguard Worker
__cil_verify_syntax(struct cil_tree_node * parse_current,enum cil_syntax s[],size_t len)148*2d543d20SAndroid Build Coastguard Worker int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[], size_t len)
149*2d543d20SAndroid Build Coastguard Worker {
150*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *c = parse_current;
151*2d543d20SAndroid Build Coastguard Worker size_t i = 0;
152*2d543d20SAndroid Build Coastguard Worker
153*2d543d20SAndroid Build Coastguard Worker while (i < len && c != NULL) {
154*2d543d20SAndroid Build Coastguard Worker if ((s[i] & CIL_SYN_STRING) && c->data != NULL && c->cl_head == NULL) {
155*2d543d20SAndroid Build Coastguard Worker c = c->next;
156*2d543d20SAndroid Build Coastguard Worker i++;
157*2d543d20SAndroid Build Coastguard Worker } else if ((s[i] & CIL_SYN_LIST) && c->data == NULL && c->cl_head != NULL) {
158*2d543d20SAndroid Build Coastguard Worker c = c->next;
159*2d543d20SAndroid Build Coastguard Worker i++;
160*2d543d20SAndroid Build Coastguard Worker } else if ((s[i] & CIL_SYN_EMPTY_LIST) && c->data == NULL && c->cl_head == NULL) {
161*2d543d20SAndroid Build Coastguard Worker c = c->next;
162*2d543d20SAndroid Build Coastguard Worker i++;
163*2d543d20SAndroid Build Coastguard Worker } else if ((s[i] & CIL_SYN_N_LISTS) || (s[i] & CIL_SYN_N_STRINGS)) {
164*2d543d20SAndroid Build Coastguard Worker while (c != NULL) {
165*2d543d20SAndroid Build Coastguard Worker if ((s[i] & CIL_SYN_N_LISTS) && c->data == NULL && c->cl_head != NULL) {
166*2d543d20SAndroid Build Coastguard Worker c = c->next;
167*2d543d20SAndroid Build Coastguard Worker } else if ((s[i] & CIL_SYN_N_STRINGS) && c->data != NULL && c->cl_head == NULL) {
168*2d543d20SAndroid Build Coastguard Worker c = c->next;
169*2d543d20SAndroid Build Coastguard Worker } else {
170*2d543d20SAndroid Build Coastguard Worker goto exit;
171*2d543d20SAndroid Build Coastguard Worker }
172*2d543d20SAndroid Build Coastguard Worker }
173*2d543d20SAndroid Build Coastguard Worker i++;
174*2d543d20SAndroid Build Coastguard Worker break; /* Only CIL_SYN_END allowed after these */
175*2d543d20SAndroid Build Coastguard Worker } else {
176*2d543d20SAndroid Build Coastguard Worker goto exit;
177*2d543d20SAndroid Build Coastguard Worker }
178*2d543d20SAndroid Build Coastguard Worker }
179*2d543d20SAndroid Build Coastguard Worker
180*2d543d20SAndroid Build Coastguard Worker if (i < len && (s[i] & CIL_SYN_END) && c == NULL) {
181*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
182*2d543d20SAndroid Build Coastguard Worker }
183*2d543d20SAndroid Build Coastguard Worker
184*2d543d20SAndroid Build Coastguard Worker exit:
185*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Invalid syntax\n");
186*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
187*2d543d20SAndroid Build Coastguard Worker }
188*2d543d20SAndroid Build Coastguard Worker
cil_verify_expr_syntax(struct cil_tree_node * current,enum cil_flavor op,enum cil_flavor expr_flavor)189*2d543d20SAndroid Build Coastguard Worker int cil_verify_expr_syntax(struct cil_tree_node *current, enum cil_flavor op, enum cil_flavor expr_flavor)
190*2d543d20SAndroid Build Coastguard Worker {
191*2d543d20SAndroid Build Coastguard Worker int rc;
192*2d543d20SAndroid Build Coastguard Worker enum cil_syntax syntax[] = {
193*2d543d20SAndroid Build Coastguard Worker CIL_SYN_STRING,
194*2d543d20SAndroid Build Coastguard Worker CIL_SYN_STRING | CIL_SYN_LIST,
195*2d543d20SAndroid Build Coastguard Worker CIL_SYN_STRING | CIL_SYN_LIST,
196*2d543d20SAndroid Build Coastguard Worker CIL_SYN_END
197*2d543d20SAndroid Build Coastguard Worker };
198*2d543d20SAndroid Build Coastguard Worker int syntax_len = sizeof(syntax)/sizeof(*syntax);
199*2d543d20SAndroid Build Coastguard Worker
200*2d543d20SAndroid Build Coastguard Worker switch (op) {
201*2d543d20SAndroid Build Coastguard Worker case CIL_NOT:
202*2d543d20SAndroid Build Coastguard Worker syntax[2] = CIL_SYN_END;
203*2d543d20SAndroid Build Coastguard Worker syntax_len = 3;
204*2d543d20SAndroid Build Coastguard Worker break;
205*2d543d20SAndroid Build Coastguard Worker case CIL_AND:
206*2d543d20SAndroid Build Coastguard Worker case CIL_OR:
207*2d543d20SAndroid Build Coastguard Worker case CIL_XOR:
208*2d543d20SAndroid Build Coastguard Worker break;
209*2d543d20SAndroid Build Coastguard Worker case CIL_EQ:
210*2d543d20SAndroid Build Coastguard Worker case CIL_NEQ:
211*2d543d20SAndroid Build Coastguard Worker if (expr_flavor != CIL_BOOL && expr_flavor != CIL_TUNABLE ) {
212*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR,"Invalid operator (%s) for set expression\n", (char*)current->data);
213*2d543d20SAndroid Build Coastguard Worker goto exit;
214*2d543d20SAndroid Build Coastguard Worker }
215*2d543d20SAndroid Build Coastguard Worker break;
216*2d543d20SAndroid Build Coastguard Worker case CIL_ALL:
217*2d543d20SAndroid Build Coastguard Worker if (expr_flavor == CIL_BOOL || expr_flavor == CIL_TUNABLE) {
218*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR,"Invalid operator (%s) for boolean or tunable expression\n", (char*)current->data);
219*2d543d20SAndroid Build Coastguard Worker goto exit;
220*2d543d20SAndroid Build Coastguard Worker }
221*2d543d20SAndroid Build Coastguard Worker syntax[1] = CIL_SYN_END;
222*2d543d20SAndroid Build Coastguard Worker syntax_len = 2;
223*2d543d20SAndroid Build Coastguard Worker break;
224*2d543d20SAndroid Build Coastguard Worker case CIL_RANGE:
225*2d543d20SAndroid Build Coastguard Worker if (expr_flavor != CIL_CAT && expr_flavor != CIL_PERMISSIONX) {
226*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR,"Operator (%s) only valid for catset and permissionx expression\n", (char*)current->data);
227*2d543d20SAndroid Build Coastguard Worker goto exit;
228*2d543d20SAndroid Build Coastguard Worker }
229*2d543d20SAndroid Build Coastguard Worker syntax[1] = CIL_SYN_STRING;
230*2d543d20SAndroid Build Coastguard Worker syntax[2] = CIL_SYN_STRING;
231*2d543d20SAndroid Build Coastguard Worker break;
232*2d543d20SAndroid Build Coastguard Worker case CIL_NONE: /* String or List */
233*2d543d20SAndroid Build Coastguard Worker syntax[0] = CIL_SYN_N_STRINGS | CIL_SYN_N_LISTS;
234*2d543d20SAndroid Build Coastguard Worker syntax[1] = CIL_SYN_END;
235*2d543d20SAndroid Build Coastguard Worker syntax_len = 2;
236*2d543d20SAndroid Build Coastguard Worker break;
237*2d543d20SAndroid Build Coastguard Worker default:
238*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR,"Unexpected value (%s) for expression operator\n", (char*)current->data);
239*2d543d20SAndroid Build Coastguard Worker goto exit;
240*2d543d20SAndroid Build Coastguard Worker }
241*2d543d20SAndroid Build Coastguard Worker
242*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_syntax(current, syntax, syntax_len);
243*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
244*2d543d20SAndroid Build Coastguard Worker goto exit;
245*2d543d20SAndroid Build Coastguard Worker }
246*2d543d20SAndroid Build Coastguard Worker
247*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
248*2d543d20SAndroid Build Coastguard Worker
249*2d543d20SAndroid Build Coastguard Worker exit:
250*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
251*2d543d20SAndroid Build Coastguard Worker }
252*2d543d20SAndroid Build Coastguard Worker
cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor,enum cil_flavor r_flavor,enum cil_flavor op,enum cil_flavor expr_flavor)253*2d543d20SAndroid Build Coastguard Worker int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_flavor r_flavor, enum cil_flavor op, enum cil_flavor expr_flavor)
254*2d543d20SAndroid Build Coastguard Worker {
255*2d543d20SAndroid Build Coastguard Worker if (r_flavor == CIL_STRING || r_flavor == CIL_LIST) {
256*2d543d20SAndroid Build Coastguard Worker if (l_flavor == CIL_CONS_L1 || l_flavor == CIL_CONS_L2 || l_flavor == CIL_CONS_H1 || l_flavor == CIL_CONS_H2 ) {
257*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "l1, l2, h1, and h2 cannot be used on the left side with a string or list on the right side\n");
258*2d543d20SAndroid Build Coastguard Worker goto exit;
259*2d543d20SAndroid Build Coastguard Worker } else if (l_flavor == CIL_CONS_U3 || l_flavor == CIL_CONS_R3 || l_flavor == CIL_CONS_T3) {
260*2d543d20SAndroid Build Coastguard Worker if (expr_flavor != CIL_VALIDATETRANS && expr_flavor != CIL_MLSVALIDATETRANS) {
261*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "u3, r3, and t3 can only be used with (mls)validatetrans rules\n");
262*2d543d20SAndroid Build Coastguard Worker goto exit;
263*2d543d20SAndroid Build Coastguard Worker }
264*2d543d20SAndroid Build Coastguard Worker }
265*2d543d20SAndroid Build Coastguard Worker } else {
266*2d543d20SAndroid Build Coastguard Worker if (r_flavor == CIL_CONS_U1 || r_flavor == CIL_CONS_R1 || r_flavor == CIL_CONS_T1) {
267*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "u1, r1, and t1 are not allowed on the right side\n");
268*2d543d20SAndroid Build Coastguard Worker goto exit;
269*2d543d20SAndroid Build Coastguard Worker } else if (r_flavor == CIL_CONS_U3 || r_flavor == CIL_CONS_R3 || r_flavor == CIL_CONS_T3) {
270*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "u3, r3, and t3 are not allowed on the right side\n");
271*2d543d20SAndroid Build Coastguard Worker goto exit;
272*2d543d20SAndroid Build Coastguard Worker } else if (r_flavor == CIL_CONS_U2) {
273*2d543d20SAndroid Build Coastguard Worker if (op != CIL_EQ && op != CIL_NEQ) {
274*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "u2 on the right side must be used with eq or neq as the operator\n");
275*2d543d20SAndroid Build Coastguard Worker goto exit;
276*2d543d20SAndroid Build Coastguard Worker } else if (l_flavor != CIL_CONS_U1) {
277*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "u2 on the right side must be used with u1 on the left\n");
278*2d543d20SAndroid Build Coastguard Worker goto exit;
279*2d543d20SAndroid Build Coastguard Worker }
280*2d543d20SAndroid Build Coastguard Worker } else if (r_flavor == CIL_CONS_R2) {
281*2d543d20SAndroid Build Coastguard Worker if (l_flavor != CIL_CONS_R1) {
282*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "r2 on the right side must be used with r1 on the left\n");
283*2d543d20SAndroid Build Coastguard Worker goto exit;
284*2d543d20SAndroid Build Coastguard Worker }
285*2d543d20SAndroid Build Coastguard Worker } else if (r_flavor == CIL_CONS_T2) {
286*2d543d20SAndroid Build Coastguard Worker if (op != CIL_EQ && op != CIL_NEQ) {
287*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "t2 on the right side must be used with eq or neq as the operator\n");
288*2d543d20SAndroid Build Coastguard Worker goto exit;
289*2d543d20SAndroid Build Coastguard Worker } else if (l_flavor != CIL_CONS_T1) {
290*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "t2 on the right side must be used with t1 on the left\n");
291*2d543d20SAndroid Build Coastguard Worker goto exit;
292*2d543d20SAndroid Build Coastguard Worker }
293*2d543d20SAndroid Build Coastguard Worker } else if (r_flavor == CIL_CONS_L2) {
294*2d543d20SAndroid Build Coastguard Worker if (l_flavor != CIL_CONS_L1 && l_flavor != CIL_CONS_H1) {
295*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "l2 on the right side must be used with l1 or h1 on the left\n");
296*2d543d20SAndroid Build Coastguard Worker goto exit;
297*2d543d20SAndroid Build Coastguard Worker }
298*2d543d20SAndroid Build Coastguard Worker } else if (r_flavor == CIL_CONS_H2) {
299*2d543d20SAndroid Build Coastguard Worker if (l_flavor != CIL_CONS_L1 && l_flavor != CIL_CONS_L2 && l_flavor != CIL_CONS_H1 ) {
300*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "h2 on the right side must be used with l1, l2, or h1 on the left\n");
301*2d543d20SAndroid Build Coastguard Worker goto exit;
302*2d543d20SAndroid Build Coastguard Worker }
303*2d543d20SAndroid Build Coastguard Worker } else if (r_flavor == CIL_CONS_H1) {
304*2d543d20SAndroid Build Coastguard Worker if (l_flavor != CIL_CONS_L1) {
305*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "h1 on the right side must be used with l1 on the left\n");
306*2d543d20SAndroid Build Coastguard Worker goto exit;
307*2d543d20SAndroid Build Coastguard Worker }
308*2d543d20SAndroid Build Coastguard Worker }
309*2d543d20SAndroid Build Coastguard Worker }
310*2d543d20SAndroid Build Coastguard Worker
311*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
312*2d543d20SAndroid Build Coastguard Worker
313*2d543d20SAndroid Build Coastguard Worker exit:
314*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
315*2d543d20SAndroid Build Coastguard Worker }
316*2d543d20SAndroid Build Coastguard Worker
cil_verify_constraint_expr_syntax(struct cil_tree_node * current,enum cil_flavor op)317*2d543d20SAndroid Build Coastguard Worker int cil_verify_constraint_expr_syntax(struct cil_tree_node *current, enum cil_flavor op)
318*2d543d20SAndroid Build Coastguard Worker {
319*2d543d20SAndroid Build Coastguard Worker int rc;
320*2d543d20SAndroid Build Coastguard Worker enum cil_syntax syntax[] = {
321*2d543d20SAndroid Build Coastguard Worker CIL_SYN_STRING,
322*2d543d20SAndroid Build Coastguard Worker CIL_SYN_END,
323*2d543d20SAndroid Build Coastguard Worker CIL_SYN_END,
324*2d543d20SAndroid Build Coastguard Worker CIL_SYN_END
325*2d543d20SAndroid Build Coastguard Worker };
326*2d543d20SAndroid Build Coastguard Worker int syntax_len = sizeof(syntax)/sizeof(*syntax);
327*2d543d20SAndroid Build Coastguard Worker
328*2d543d20SAndroid Build Coastguard Worker switch (op) {
329*2d543d20SAndroid Build Coastguard Worker case CIL_NOT:
330*2d543d20SAndroid Build Coastguard Worker syntax[1] = CIL_SYN_LIST;
331*2d543d20SAndroid Build Coastguard Worker syntax_len--;
332*2d543d20SAndroid Build Coastguard Worker break;
333*2d543d20SAndroid Build Coastguard Worker case CIL_AND:
334*2d543d20SAndroid Build Coastguard Worker case CIL_OR:
335*2d543d20SAndroid Build Coastguard Worker syntax[1] = CIL_SYN_LIST;
336*2d543d20SAndroid Build Coastguard Worker syntax[2] = CIL_SYN_LIST;
337*2d543d20SAndroid Build Coastguard Worker break;
338*2d543d20SAndroid Build Coastguard Worker case CIL_EQ:
339*2d543d20SAndroid Build Coastguard Worker case CIL_NEQ:
340*2d543d20SAndroid Build Coastguard Worker syntax[1] = CIL_SYN_STRING;
341*2d543d20SAndroid Build Coastguard Worker syntax[2] = CIL_SYN_STRING | CIL_SYN_LIST;
342*2d543d20SAndroid Build Coastguard Worker break;
343*2d543d20SAndroid Build Coastguard Worker case CIL_CONS_DOM:
344*2d543d20SAndroid Build Coastguard Worker case CIL_CONS_DOMBY:
345*2d543d20SAndroid Build Coastguard Worker case CIL_CONS_INCOMP:
346*2d543d20SAndroid Build Coastguard Worker syntax[1] = CIL_SYN_STRING;
347*2d543d20SAndroid Build Coastguard Worker syntax[2] = CIL_SYN_STRING;
348*2d543d20SAndroid Build Coastguard Worker break;
349*2d543d20SAndroid Build Coastguard Worker default:
350*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Invalid operator (%s) for constraint expression\n", (char*)current->data);
351*2d543d20SAndroid Build Coastguard Worker goto exit;
352*2d543d20SAndroid Build Coastguard Worker }
353*2d543d20SAndroid Build Coastguard Worker
354*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_syntax(current, syntax, syntax_len);
355*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
356*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Invalid constraint syntax\n");
357*2d543d20SAndroid Build Coastguard Worker goto exit;
358*2d543d20SAndroid Build Coastguard Worker }
359*2d543d20SAndroid Build Coastguard Worker
360*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
361*2d543d20SAndroid Build Coastguard Worker
362*2d543d20SAndroid Build Coastguard Worker exit:
363*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
364*2d543d20SAndroid Build Coastguard Worker }
365*2d543d20SAndroid Build Coastguard Worker
cil_verify_conditional_blocks(struct cil_tree_node * current)366*2d543d20SAndroid Build Coastguard Worker int cil_verify_conditional_blocks(struct cil_tree_node *current)
367*2d543d20SAndroid Build Coastguard Worker {
368*2d543d20SAndroid Build Coastguard Worker int found_true = CIL_FALSE;
369*2d543d20SAndroid Build Coastguard Worker int found_false = CIL_FALSE;
370*2d543d20SAndroid Build Coastguard Worker
371*2d543d20SAndroid Build Coastguard Worker if (current->cl_head->data == CIL_KEY_CONDTRUE) {
372*2d543d20SAndroid Build Coastguard Worker found_true = CIL_TRUE;
373*2d543d20SAndroid Build Coastguard Worker } else if (current->cl_head->data == CIL_KEY_CONDFALSE) {
374*2d543d20SAndroid Build Coastguard Worker found_false = CIL_TRUE;
375*2d543d20SAndroid Build Coastguard Worker } else {
376*2d543d20SAndroid Build Coastguard Worker cil_tree_log(current, CIL_ERR, "Expected true or false block in conditional");
377*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
378*2d543d20SAndroid Build Coastguard Worker }
379*2d543d20SAndroid Build Coastguard Worker
380*2d543d20SAndroid Build Coastguard Worker current = current->next;
381*2d543d20SAndroid Build Coastguard Worker if (current != NULL) {
382*2d543d20SAndroid Build Coastguard Worker if (current->cl_head->data == CIL_KEY_CONDTRUE) {
383*2d543d20SAndroid Build Coastguard Worker if (found_true) {
384*2d543d20SAndroid Build Coastguard Worker cil_tree_log(current, CIL_ERR, "More than one true block in conditional");
385*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
386*2d543d20SAndroid Build Coastguard Worker }
387*2d543d20SAndroid Build Coastguard Worker } else if (current->cl_head->data == CIL_KEY_CONDFALSE) {
388*2d543d20SAndroid Build Coastguard Worker if (found_false) {
389*2d543d20SAndroid Build Coastguard Worker cil_tree_log(current, CIL_ERR, "More than one false block in conditional");
390*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
391*2d543d20SAndroid Build Coastguard Worker }
392*2d543d20SAndroid Build Coastguard Worker } else {
393*2d543d20SAndroid Build Coastguard Worker cil_tree_log(current, CIL_ERR, "Expected true or false block in conditional");
394*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
395*2d543d20SAndroid Build Coastguard Worker }
396*2d543d20SAndroid Build Coastguard Worker }
397*2d543d20SAndroid Build Coastguard Worker
398*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
399*2d543d20SAndroid Build Coastguard Worker }
400*2d543d20SAndroid Build Coastguard Worker
cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro * macro,struct cil_tree_node * node,const char * name)401*2d543d20SAndroid Build Coastguard Worker int cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro *macro, struct cil_tree_node *node, const char *name)
402*2d543d20SAndroid Build Coastguard Worker {
403*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *item;
404*2d543d20SAndroid Build Coastguard Worker struct cil_list *param_list = macro->params;
405*2d543d20SAndroid Build Coastguard Worker if (param_list != NULL) {
406*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(item, param_list) {
407*2d543d20SAndroid Build Coastguard Worker struct cil_param *param = item->data;
408*2d543d20SAndroid Build Coastguard Worker if (param->str == name) {
409*2d543d20SAndroid Build Coastguard Worker if (param->flavor == node->flavor) {
410*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Declaration of %s %s shadows a macro parameter with the same flavor\n", cil_node_to_string(node), name);
411*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
412*2d543d20SAndroid Build Coastguard Worker } else {
413*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_WARN, "Declaration of %s %s has same name as a macro parameter with a different flavor\n", cil_node_to_string(node), name);
414*2d543d20SAndroid Build Coastguard Worker }
415*2d543d20SAndroid Build Coastguard Worker }
416*2d543d20SAndroid Build Coastguard Worker }
417*2d543d20SAndroid Build Coastguard Worker }
418*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
419*2d543d20SAndroid Build Coastguard Worker }
420*2d543d20SAndroid Build Coastguard Worker
421*2d543d20SAndroid Build Coastguard Worker static int cil_verify_no_self_reference(enum cil_flavor flavor, struct cil_symtab_datum *datum, struct cil_stack *stack);
422*2d543d20SAndroid Build Coastguard Worker
__verify_no_self_reference_in_expr(struct cil_list * expr,struct cil_stack * stack)423*2d543d20SAndroid Build Coastguard Worker static int __verify_no_self_reference_in_expr(struct cil_list *expr, struct cil_stack *stack)
424*2d543d20SAndroid Build Coastguard Worker {
425*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *item;
426*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_OK;
427*2d543d20SAndroid Build Coastguard Worker
428*2d543d20SAndroid Build Coastguard Worker if (!expr) {
429*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
430*2d543d20SAndroid Build Coastguard Worker }
431*2d543d20SAndroid Build Coastguard Worker
432*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(item, expr) {
433*2d543d20SAndroid Build Coastguard Worker if (item->flavor == CIL_DATUM) {
434*2d543d20SAndroid Build Coastguard Worker struct cil_symtab_datum* datum = item->data;
435*2d543d20SAndroid Build Coastguard Worker rc = cil_verify_no_self_reference(FLAVOR(datum), datum, stack);
436*2d543d20SAndroid Build Coastguard Worker } else if (item->flavor == CIL_LIST) {
437*2d543d20SAndroid Build Coastguard Worker rc = __verify_no_self_reference_in_expr(item->data, stack);
438*2d543d20SAndroid Build Coastguard Worker }
439*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
440*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
441*2d543d20SAndroid Build Coastguard Worker }
442*2d543d20SAndroid Build Coastguard Worker }
443*2d543d20SAndroid Build Coastguard Worker
444*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
445*2d543d20SAndroid Build Coastguard Worker }
446*2d543d20SAndroid Build Coastguard Worker
cil_verify_no_self_reference(enum cil_flavor flavor,struct cil_symtab_datum * datum,struct cil_stack * stack)447*2d543d20SAndroid Build Coastguard Worker static int cil_verify_no_self_reference(enum cil_flavor flavor, struct cil_symtab_datum *datum, struct cil_stack *stack)
448*2d543d20SAndroid Build Coastguard Worker {
449*2d543d20SAndroid Build Coastguard Worker struct cil_stack_item *item;
450*2d543d20SAndroid Build Coastguard Worker int i = 0;
451*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_OK;
452*2d543d20SAndroid Build Coastguard Worker
453*2d543d20SAndroid Build Coastguard Worker cil_stack_for_each(stack, i, item) {
454*2d543d20SAndroid Build Coastguard Worker struct cil_symtab_datum *prev = item->data;
455*2d543d20SAndroid Build Coastguard Worker if (datum == prev) {
456*2d543d20SAndroid Build Coastguard Worker cil_tree_log(NODE(datum), CIL_ERR, "Self-reference found for %s", datum->name);
457*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
458*2d543d20SAndroid Build Coastguard Worker }
459*2d543d20SAndroid Build Coastguard Worker }
460*2d543d20SAndroid Build Coastguard Worker
461*2d543d20SAndroid Build Coastguard Worker switch (flavor) {
462*2d543d20SAndroid Build Coastguard Worker case CIL_USERATTRIBUTE: {
463*2d543d20SAndroid Build Coastguard Worker struct cil_userattribute *attr = (struct cil_userattribute *)datum;
464*2d543d20SAndroid Build Coastguard Worker cil_stack_push(stack, CIL_DATUM, datum);
465*2d543d20SAndroid Build Coastguard Worker rc = __verify_no_self_reference_in_expr(attr->expr_list, stack);
466*2d543d20SAndroid Build Coastguard Worker cil_stack_pop(stack);
467*2d543d20SAndroid Build Coastguard Worker break;
468*2d543d20SAndroid Build Coastguard Worker }
469*2d543d20SAndroid Build Coastguard Worker case CIL_ROLEATTRIBUTE: {
470*2d543d20SAndroid Build Coastguard Worker struct cil_roleattribute *attr = (struct cil_roleattribute *)datum;
471*2d543d20SAndroid Build Coastguard Worker cil_stack_push(stack, CIL_DATUM, datum);
472*2d543d20SAndroid Build Coastguard Worker rc = __verify_no_self_reference_in_expr(attr->expr_list, stack);
473*2d543d20SAndroid Build Coastguard Worker cil_stack_pop(stack);
474*2d543d20SAndroid Build Coastguard Worker break;
475*2d543d20SAndroid Build Coastguard Worker }
476*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEATTRIBUTE: {
477*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *attr = (struct cil_typeattribute *)datum;
478*2d543d20SAndroid Build Coastguard Worker cil_stack_push(stack, CIL_DATUM, datum);
479*2d543d20SAndroid Build Coastguard Worker rc = __verify_no_self_reference_in_expr(attr->expr_list, stack);
480*2d543d20SAndroid Build Coastguard Worker cil_stack_pop(stack);
481*2d543d20SAndroid Build Coastguard Worker break;
482*2d543d20SAndroid Build Coastguard Worker }
483*2d543d20SAndroid Build Coastguard Worker case CIL_CATSET: {
484*2d543d20SAndroid Build Coastguard Worker struct cil_catset *set = (struct cil_catset *)datum;
485*2d543d20SAndroid Build Coastguard Worker cil_stack_push(stack, CIL_DATUM, datum);
486*2d543d20SAndroid Build Coastguard Worker rc = __verify_no_self_reference_in_expr(set->cats->datum_expr, stack);
487*2d543d20SAndroid Build Coastguard Worker cil_stack_pop(stack);
488*2d543d20SAndroid Build Coastguard Worker break;
489*2d543d20SAndroid Build Coastguard Worker }
490*2d543d20SAndroid Build Coastguard Worker default:
491*2d543d20SAndroid Build Coastguard Worker break;
492*2d543d20SAndroid Build Coastguard Worker }
493*2d543d20SAndroid Build Coastguard Worker
494*2d543d20SAndroid Build Coastguard Worker return rc;
495*2d543d20SAndroid Build Coastguard Worker }
496*2d543d20SAndroid Build Coastguard Worker
__cil_verify_ranges(struct cil_list * list)497*2d543d20SAndroid Build Coastguard Worker int __cil_verify_ranges(struct cil_list *list)
498*2d543d20SAndroid Build Coastguard Worker {
499*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
500*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *curr;
501*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *range = NULL;
502*2d543d20SAndroid Build Coastguard Worker
503*2d543d20SAndroid Build Coastguard Worker if (list == NULL || list->head == NULL) {
504*2d543d20SAndroid Build Coastguard Worker goto exit;
505*2d543d20SAndroid Build Coastguard Worker }
506*2d543d20SAndroid Build Coastguard Worker
507*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(curr, list) {
508*2d543d20SAndroid Build Coastguard Worker /* range */
509*2d543d20SAndroid Build Coastguard Worker if (curr->flavor == CIL_LIST) {
510*2d543d20SAndroid Build Coastguard Worker range = ((struct cil_list*)curr->data)->head;
511*2d543d20SAndroid Build Coastguard Worker if (range == NULL || range->next == NULL || range->next->next != NULL) {
512*2d543d20SAndroid Build Coastguard Worker goto exit;
513*2d543d20SAndroid Build Coastguard Worker }
514*2d543d20SAndroid Build Coastguard Worker }
515*2d543d20SAndroid Build Coastguard Worker }
516*2d543d20SAndroid Build Coastguard Worker
517*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
518*2d543d20SAndroid Build Coastguard Worker
519*2d543d20SAndroid Build Coastguard Worker exit:
520*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR,"Invalid Range syntax\n");
521*2d543d20SAndroid Build Coastguard Worker return rc;
522*2d543d20SAndroid Build Coastguard Worker }
523*2d543d20SAndroid Build Coastguard Worker
cil_verify_completed_ordered_list(struct cil_list * complete,struct cil_list * ordered_lists)524*2d543d20SAndroid Build Coastguard Worker int cil_verify_completed_ordered_list(struct cil_list *complete, struct cil_list *ordered_lists)
525*2d543d20SAndroid Build Coastguard Worker {
526*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *cprev, *ccurr, *cnext;
527*2d543d20SAndroid Build Coastguard Worker int found_prev, found_next;
528*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_OK;
529*2d543d20SAndroid Build Coastguard Worker
530*2d543d20SAndroid Build Coastguard Worker found_prev = CIL_FALSE;
531*2d543d20SAndroid Build Coastguard Worker found_next = CIL_FALSE;
532*2d543d20SAndroid Build Coastguard Worker cprev = NULL;
533*2d543d20SAndroid Build Coastguard Worker ccurr = complete->head;
534*2d543d20SAndroid Build Coastguard Worker cnext = ccurr ? ccurr->next : NULL;
535*2d543d20SAndroid Build Coastguard Worker while (ccurr) {
536*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *node;
537*2d543d20SAndroid Build Coastguard Worker struct cil_ordered *ordered;
538*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *curr_list, *oprev, *ocurr, *onext;
539*2d543d20SAndroid Build Coastguard Worker int change = CIL_FALSE;
540*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(curr_list, ordered_lists) {
541*2d543d20SAndroid Build Coastguard Worker node = curr_list->data;
542*2d543d20SAndroid Build Coastguard Worker ordered = node->data;
543*2d543d20SAndroid Build Coastguard Worker oprev = NULL;
544*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(ocurr, ordered->datums) {
545*2d543d20SAndroid Build Coastguard Worker onext = ocurr ? ocurr->next : NULL;
546*2d543d20SAndroid Build Coastguard Worker if (ccurr->data == ocurr->data) {
547*2d543d20SAndroid Build Coastguard Worker if (found_prev == CIL_FALSE && ((!cprev && !oprev) ||
548*2d543d20SAndroid Build Coastguard Worker (cprev && oprev && cprev->data == oprev->data))) {
549*2d543d20SAndroid Build Coastguard Worker found_prev = CIL_TRUE;
550*2d543d20SAndroid Build Coastguard Worker change = CIL_TRUE;
551*2d543d20SAndroid Build Coastguard Worker }
552*2d543d20SAndroid Build Coastguard Worker if (found_next == CIL_FALSE && ((!cnext && !onext) ||
553*2d543d20SAndroid Build Coastguard Worker (cnext && onext && cnext->data == onext->data))) {
554*2d543d20SAndroid Build Coastguard Worker found_next = CIL_TRUE;
555*2d543d20SAndroid Build Coastguard Worker change = CIL_TRUE;
556*2d543d20SAndroid Build Coastguard Worker }
557*2d543d20SAndroid Build Coastguard Worker if (found_prev && found_next) {
558*2d543d20SAndroid Build Coastguard Worker cprev = ccurr;
559*2d543d20SAndroid Build Coastguard Worker ccurr = cnext;
560*2d543d20SAndroid Build Coastguard Worker cnext = ccurr ? ccurr->next : NULL;
561*2d543d20SAndroid Build Coastguard Worker found_prev = CIL_FALSE;
562*2d543d20SAndroid Build Coastguard Worker found_next = CIL_FALSE;
563*2d543d20SAndroid Build Coastguard Worker if (!ccurr) {
564*2d543d20SAndroid Build Coastguard Worker /* Went through the whole list */
565*2d543d20SAndroid Build Coastguard Worker return rc;
566*2d543d20SAndroid Build Coastguard Worker }
567*2d543d20SAndroid Build Coastguard Worker }
568*2d543d20SAndroid Build Coastguard Worker }
569*2d543d20SAndroid Build Coastguard Worker oprev = ocurr;
570*2d543d20SAndroid Build Coastguard Worker }
571*2d543d20SAndroid Build Coastguard Worker }
572*2d543d20SAndroid Build Coastguard Worker if (!change) {
573*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
574*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Unable to verify the order of %s\n", DATUM(ccurr->data)->fqn);
575*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Found in the following ordering rules:\n");
576*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(curr_list, ordered_lists) {
577*2d543d20SAndroid Build Coastguard Worker node = curr_list->data;
578*2d543d20SAndroid Build Coastguard Worker ordered = node->data;
579*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(ocurr, ordered->datums) {
580*2d543d20SAndroid Build Coastguard Worker if (ccurr->data == ocurr->data) {
581*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, " ");
582*2d543d20SAndroid Build Coastguard Worker }
583*2d543d20SAndroid Build Coastguard Worker }
584*2d543d20SAndroid Build Coastguard Worker }
585*2d543d20SAndroid Build Coastguard Worker cprev = ccurr;
586*2d543d20SAndroid Build Coastguard Worker ccurr = cnext;
587*2d543d20SAndroid Build Coastguard Worker cnext = ccurr ? ccurr->next : NULL;
588*2d543d20SAndroid Build Coastguard Worker found_prev = CIL_FALSE;
589*2d543d20SAndroid Build Coastguard Worker found_next = CIL_FALSE;
590*2d543d20SAndroid Build Coastguard Worker }
591*2d543d20SAndroid Build Coastguard Worker }
592*2d543d20SAndroid Build Coastguard Worker
593*2d543d20SAndroid Build Coastguard Worker return rc;
594*2d543d20SAndroid Build Coastguard Worker }
595*2d543d20SAndroid Build Coastguard Worker
596*2d543d20SAndroid Build Coastguard Worker struct cil_args_verify_order {
597*2d543d20SAndroid Build Coastguard Worker uint32_t *flavor;
598*2d543d20SAndroid Build Coastguard Worker };
599*2d543d20SAndroid Build Coastguard Worker
__cil_verify_ordered_node_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)600*2d543d20SAndroid Build Coastguard Worker int __cil_verify_ordered_node_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, void *extra_args)
601*2d543d20SAndroid Build Coastguard Worker {
602*2d543d20SAndroid Build Coastguard Worker struct cil_args_verify_order *args = extra_args;
603*2d543d20SAndroid Build Coastguard Worker uint32_t *flavor = args->flavor;
604*2d543d20SAndroid Build Coastguard Worker
605*2d543d20SAndroid Build Coastguard Worker if (node->flavor == *flavor) {
606*2d543d20SAndroid Build Coastguard Worker if (node->flavor == CIL_SID) {
607*2d543d20SAndroid Build Coastguard Worker struct cil_sid *sid = node->data;
608*2d543d20SAndroid Build Coastguard Worker if (sid->ordered == CIL_FALSE) {
609*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "SID %s not in sidorder statement", sid->datum.name);
610*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
611*2d543d20SAndroid Build Coastguard Worker }
612*2d543d20SAndroid Build Coastguard Worker } else if (node->flavor == CIL_CLASS) {
613*2d543d20SAndroid Build Coastguard Worker struct cil_class *class = node->data;
614*2d543d20SAndroid Build Coastguard Worker if (class->ordered == CIL_FALSE) {
615*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Class %s not in classorder statement", class->datum.name);
616*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
617*2d543d20SAndroid Build Coastguard Worker }
618*2d543d20SAndroid Build Coastguard Worker } else if (node->flavor == CIL_CAT) {
619*2d543d20SAndroid Build Coastguard Worker struct cil_cat *cat = node->data;
620*2d543d20SAndroid Build Coastguard Worker if (cat->ordered == CIL_FALSE) {
621*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Category %s not in categoryorder statement", cat->datum.name);
622*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
623*2d543d20SAndroid Build Coastguard Worker }
624*2d543d20SAndroid Build Coastguard Worker } else if (node->flavor == CIL_SENS) {
625*2d543d20SAndroid Build Coastguard Worker struct cil_sens *sens = node->data;
626*2d543d20SAndroid Build Coastguard Worker if (sens->ordered == CIL_FALSE) {
627*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Sensitivity %s not in sensitivityorder statement", sens->datum.name);
628*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
629*2d543d20SAndroid Build Coastguard Worker }
630*2d543d20SAndroid Build Coastguard Worker }
631*2d543d20SAndroid Build Coastguard Worker }
632*2d543d20SAndroid Build Coastguard Worker
633*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
634*2d543d20SAndroid Build Coastguard Worker }
635*2d543d20SAndroid Build Coastguard Worker
__cil_verify_ordered(struct cil_tree_node * current,enum cil_flavor flavor)636*2d543d20SAndroid Build Coastguard Worker int __cil_verify_ordered(struct cil_tree_node *current, enum cil_flavor flavor)
637*2d543d20SAndroid Build Coastguard Worker {
638*2d543d20SAndroid Build Coastguard Worker struct cil_args_verify_order extra_args;
639*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
640*2d543d20SAndroid Build Coastguard Worker
641*2d543d20SAndroid Build Coastguard Worker extra_args.flavor = &flavor;
642*2d543d20SAndroid Build Coastguard Worker
643*2d543d20SAndroid Build Coastguard Worker rc = cil_tree_walk(current, __cil_verify_ordered_node_helper, NULL, NULL, &extra_args);
644*2d543d20SAndroid Build Coastguard Worker
645*2d543d20SAndroid Build Coastguard Worker return rc;
646*2d543d20SAndroid Build Coastguard Worker }
647*2d543d20SAndroid Build Coastguard Worker
__cil_verify_initsids(struct cil_list * sids)648*2d543d20SAndroid Build Coastguard Worker int __cil_verify_initsids(struct cil_list *sids)
649*2d543d20SAndroid Build Coastguard Worker {
650*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_OK;
651*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *i;
652*2d543d20SAndroid Build Coastguard Worker
653*2d543d20SAndroid Build Coastguard Worker if (sids->head == NULL) {
654*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "At least one initial sid must be defined in the policy\n");
655*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
656*2d543d20SAndroid Build Coastguard Worker }
657*2d543d20SAndroid Build Coastguard Worker
658*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(i, sids) {
659*2d543d20SAndroid Build Coastguard Worker struct cil_sid *sid = i->data;
660*2d543d20SAndroid Build Coastguard Worker if (sid->context == NULL) {
661*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *node = sid->datum.nodes->head->data;
662*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_INFO, "No context assigned to SID %s, omitting from policy",sid->datum.name);
663*2d543d20SAndroid Build Coastguard Worker }
664*2d543d20SAndroid Build Coastguard Worker }
665*2d543d20SAndroid Build Coastguard Worker
666*2d543d20SAndroid Build Coastguard Worker return rc;
667*2d543d20SAndroid Build Coastguard Worker }
668*2d543d20SAndroid Build Coastguard Worker
__cil_is_cat_in_cats(struct cil_cat * cat,struct cil_cats * cats)669*2d543d20SAndroid Build Coastguard Worker static int __cil_is_cat_in_cats(struct cil_cat *cat, struct cil_cats *cats)
670*2d543d20SAndroid Build Coastguard Worker {
671*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *i;
672*2d543d20SAndroid Build Coastguard Worker
673*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(i, cats->datum_expr) {
674*2d543d20SAndroid Build Coastguard Worker struct cil_cat *c = i->data;
675*2d543d20SAndroid Build Coastguard Worker if (c == cat) {
676*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
677*2d543d20SAndroid Build Coastguard Worker }
678*2d543d20SAndroid Build Coastguard Worker }
679*2d543d20SAndroid Build Coastguard Worker
680*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
681*2d543d20SAndroid Build Coastguard Worker }
682*2d543d20SAndroid Build Coastguard Worker
683*2d543d20SAndroid Build Coastguard Worker
__cil_verify_cat_in_cats(struct cil_cat * cat,struct cil_cats * cats)684*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_cat_in_cats(struct cil_cat *cat, struct cil_cats *cats)
685*2d543d20SAndroid Build Coastguard Worker {
686*2d543d20SAndroid Build Coastguard Worker if (__cil_is_cat_in_cats(cat, cats) != CIL_TRUE) {
687*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Failed to find category %s in category list\n", cat->datum.name);
688*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
689*2d543d20SAndroid Build Coastguard Worker }
690*2d543d20SAndroid Build Coastguard Worker
691*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
692*2d543d20SAndroid Build Coastguard Worker }
693*2d543d20SAndroid Build Coastguard Worker
__cil_verify_cats_associated_with_sens(struct cil_sens * sens,struct cil_cats * cats)694*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_cats_associated_with_sens(struct cil_sens *sens, struct cil_cats *cats)
695*2d543d20SAndroid Build Coastguard Worker {
696*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_OK;
697*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *i, *j;
698*2d543d20SAndroid Build Coastguard Worker
699*2d543d20SAndroid Build Coastguard Worker if (!cats) {
700*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
701*2d543d20SAndroid Build Coastguard Worker }
702*2d543d20SAndroid Build Coastguard Worker
703*2d543d20SAndroid Build Coastguard Worker if (!sens->cats_list) {
704*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "No categories can be used with sensitivity %s\n", sens->datum.name);
705*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
706*2d543d20SAndroid Build Coastguard Worker }
707*2d543d20SAndroid Build Coastguard Worker
708*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(i, cats->datum_expr) {
709*2d543d20SAndroid Build Coastguard Worker struct cil_cat *cat = i->data;
710*2d543d20SAndroid Build Coastguard Worker int ok = CIL_FALSE;
711*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(j, sens->cats_list) {
712*2d543d20SAndroid Build Coastguard Worker if (__cil_is_cat_in_cats(cat, j->data) == CIL_TRUE) {
713*2d543d20SAndroid Build Coastguard Worker ok = CIL_TRUE;
714*2d543d20SAndroid Build Coastguard Worker break;
715*2d543d20SAndroid Build Coastguard Worker }
716*2d543d20SAndroid Build Coastguard Worker }
717*2d543d20SAndroid Build Coastguard Worker
718*2d543d20SAndroid Build Coastguard Worker if (ok != CIL_TRUE) {
719*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Category %s cannot be used with sensitivity %s\n",
720*2d543d20SAndroid Build Coastguard Worker cat->datum.name, sens->datum.name);
721*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
722*2d543d20SAndroid Build Coastguard Worker }
723*2d543d20SAndroid Build Coastguard Worker }
724*2d543d20SAndroid Build Coastguard Worker
725*2d543d20SAndroid Build Coastguard Worker return rc;
726*2d543d20SAndroid Build Coastguard Worker }
727*2d543d20SAndroid Build Coastguard Worker
__cil_verify_levelrange_sensitivity(struct cil_db * db,struct cil_sens * low,struct cil_sens * high)728*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_levelrange_sensitivity(struct cil_db *db, struct cil_sens *low, struct cil_sens *high)
729*2d543d20SAndroid Build Coastguard Worker {
730*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *curr;
731*2d543d20SAndroid Build Coastguard Worker int found = CIL_FALSE;
732*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
733*2d543d20SAndroid Build Coastguard Worker
734*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(curr, db->sensitivityorder) {
735*2d543d20SAndroid Build Coastguard Worker if (curr->data == low) {
736*2d543d20SAndroid Build Coastguard Worker found = CIL_TRUE;
737*2d543d20SAndroid Build Coastguard Worker }
738*2d543d20SAndroid Build Coastguard Worker
739*2d543d20SAndroid Build Coastguard Worker if ((found == CIL_TRUE) && (curr->data == high)) {
740*2d543d20SAndroid Build Coastguard Worker break;
741*2d543d20SAndroid Build Coastguard Worker }
742*2d543d20SAndroid Build Coastguard Worker }
743*2d543d20SAndroid Build Coastguard Worker
744*2d543d20SAndroid Build Coastguard Worker if (found != CIL_TRUE || curr == NULL) {
745*2d543d20SAndroid Build Coastguard Worker goto exit;
746*2d543d20SAndroid Build Coastguard Worker }
747*2d543d20SAndroid Build Coastguard Worker
748*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
749*2d543d20SAndroid Build Coastguard Worker
750*2d543d20SAndroid Build Coastguard Worker exit:
751*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Sensitivity %s does not dominate %s\n",
752*2d543d20SAndroid Build Coastguard Worker high->datum.name, low->datum.name);
753*2d543d20SAndroid Build Coastguard Worker return rc;
754*2d543d20SAndroid Build Coastguard Worker
755*2d543d20SAndroid Build Coastguard Worker }
756*2d543d20SAndroid Build Coastguard Worker
__cil_verify_levelrange_cats(struct cil_cats * low,struct cil_cats * high)757*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_levelrange_cats(struct cil_cats *low, struct cil_cats *high)
758*2d543d20SAndroid Build Coastguard Worker {
759*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
760*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *item;
761*2d543d20SAndroid Build Coastguard Worker
762*2d543d20SAndroid Build Coastguard Worker if (low == NULL || (low == NULL && high == NULL)) {
763*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
764*2d543d20SAndroid Build Coastguard Worker }
765*2d543d20SAndroid Build Coastguard Worker
766*2d543d20SAndroid Build Coastguard Worker if (high == NULL) {
767*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
768*2d543d20SAndroid Build Coastguard Worker goto exit;
769*2d543d20SAndroid Build Coastguard Worker }
770*2d543d20SAndroid Build Coastguard Worker
771*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(item, low->datum_expr) {
772*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_cat_in_cats(item->data, high);
773*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
774*2d543d20SAndroid Build Coastguard Worker goto exit;
775*2d543d20SAndroid Build Coastguard Worker }
776*2d543d20SAndroid Build Coastguard Worker }
777*2d543d20SAndroid Build Coastguard Worker
778*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
779*2d543d20SAndroid Build Coastguard Worker
780*2d543d20SAndroid Build Coastguard Worker exit:
781*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Low level category set must be a subset of the high level category set\n");
782*2d543d20SAndroid Build Coastguard Worker return rc;
783*2d543d20SAndroid Build Coastguard Worker }
784*2d543d20SAndroid Build Coastguard Worker
__cil_verify_levelrange(struct cil_db * db,struct cil_levelrange * lr)785*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_levelrange(struct cil_db *db, struct cil_levelrange *lr)
786*2d543d20SAndroid Build Coastguard Worker {
787*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
788*2d543d20SAndroid Build Coastguard Worker
789*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_levelrange_sensitivity(db, lr->low->sens, lr->high->sens);
790*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
791*2d543d20SAndroid Build Coastguard Worker goto exit;
792*2d543d20SAndroid Build Coastguard Worker }
793*2d543d20SAndroid Build Coastguard Worker
794*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_levelrange_cats(lr->low->cats, lr->high->cats);
795*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
796*2d543d20SAndroid Build Coastguard Worker goto exit;
797*2d543d20SAndroid Build Coastguard Worker }
798*2d543d20SAndroid Build Coastguard Worker
799*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_cats_associated_with_sens(lr->low->sens, lr->low->cats);
800*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
801*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Low level sensitivity and categories are not associated\n");
802*2d543d20SAndroid Build Coastguard Worker goto exit;
803*2d543d20SAndroid Build Coastguard Worker }
804*2d543d20SAndroid Build Coastguard Worker
805*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_cats_associated_with_sens(lr->high->sens, lr->high->cats);
806*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
807*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "High level sensitivity and categories are not associated\n");
808*2d543d20SAndroid Build Coastguard Worker goto exit;
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 return rc;
815*2d543d20SAndroid Build Coastguard Worker }
816*2d543d20SAndroid Build Coastguard Worker
__cil_verify_named_levelrange(struct cil_db * db,struct cil_tree_node * node)817*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_named_levelrange(struct cil_db *db, struct cil_tree_node *node)
818*2d543d20SAndroid Build Coastguard Worker {
819*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
820*2d543d20SAndroid Build Coastguard Worker struct cil_levelrange *lr = node->data;
821*2d543d20SAndroid Build Coastguard Worker
822*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_levelrange(db, lr);
823*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
824*2d543d20SAndroid Build Coastguard Worker goto exit;
825*2d543d20SAndroid Build Coastguard Worker }
826*2d543d20SAndroid Build Coastguard Worker
827*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
828*2d543d20SAndroid Build Coastguard Worker exit:
829*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid named range");
830*2d543d20SAndroid Build Coastguard Worker return rc;
831*2d543d20SAndroid Build Coastguard Worker }
832*2d543d20SAndroid Build Coastguard Worker
__cil_verify_user_pre_eval(struct cil_tree_node * node)833*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_user_pre_eval(struct cil_tree_node *node)
834*2d543d20SAndroid Build Coastguard Worker {
835*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
836*2d543d20SAndroid Build Coastguard Worker struct cil_user *user = node->data;
837*2d543d20SAndroid Build Coastguard Worker
838*2d543d20SAndroid Build Coastguard Worker if (user->dftlevel == NULL) {
839*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "User %s does not have a default level\n", user->datum.name);
840*2d543d20SAndroid Build Coastguard Worker goto exit;
841*2d543d20SAndroid Build Coastguard Worker } else if (user->range == NULL) {
842*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "User %s does not have a level range\n", user->datum.name);
843*2d543d20SAndroid Build Coastguard Worker goto exit;
844*2d543d20SAndroid Build Coastguard Worker } else if (user->bounds != NULL) {
845*2d543d20SAndroid Build Coastguard Worker int steps = 0;
846*2d543d20SAndroid Build Coastguard Worker int limit = 2;
847*2d543d20SAndroid Build Coastguard Worker struct cil_user *u1 = user;
848*2d543d20SAndroid Build Coastguard Worker struct cil_user *u2 = user->bounds;
849*2d543d20SAndroid Build Coastguard Worker
850*2d543d20SAndroid Build Coastguard Worker while (u2 != NULL) {
851*2d543d20SAndroid Build Coastguard Worker if (u1 == u2) {
852*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Circular bounds found for user %s\n", u1->datum.name);
853*2d543d20SAndroid Build Coastguard Worker goto exit;
854*2d543d20SAndroid Build Coastguard Worker }
855*2d543d20SAndroid Build Coastguard Worker
856*2d543d20SAndroid Build Coastguard Worker if (steps == limit) {
857*2d543d20SAndroid Build Coastguard Worker steps = 0;
858*2d543d20SAndroid Build Coastguard Worker limit *= 2;
859*2d543d20SAndroid Build Coastguard Worker u1 = u2;
860*2d543d20SAndroid Build Coastguard Worker }
861*2d543d20SAndroid Build Coastguard Worker
862*2d543d20SAndroid Build Coastguard Worker u2 = u2->bounds;
863*2d543d20SAndroid Build Coastguard Worker steps++;
864*2d543d20SAndroid Build Coastguard Worker }
865*2d543d20SAndroid Build Coastguard Worker }
866*2d543d20SAndroid Build Coastguard Worker
867*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
868*2d543d20SAndroid Build Coastguard Worker exit:
869*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid user");
870*2d543d20SAndroid Build Coastguard Worker return rc;
871*2d543d20SAndroid Build Coastguard Worker }
872*2d543d20SAndroid Build Coastguard Worker
__cil_verify_user_post_eval(struct cil_db * db,struct cil_tree_node * node)873*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_user_post_eval(struct cil_db *db, struct cil_tree_node *node)
874*2d543d20SAndroid Build Coastguard Worker {
875*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
876*2d543d20SAndroid Build Coastguard Worker struct cil_user *user = node->data;
877*2d543d20SAndroid Build Coastguard Worker
878*2d543d20SAndroid Build Coastguard Worker /* Verify user range only if anonymous */
879*2d543d20SAndroid Build Coastguard Worker if (user->range->datum.name == NULL) {
880*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_levelrange(db, user->range);
881*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
882*2d543d20SAndroid Build Coastguard Worker goto exit;
883*2d543d20SAndroid Build Coastguard Worker }
884*2d543d20SAndroid Build Coastguard Worker }
885*2d543d20SAndroid Build Coastguard Worker
886*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
887*2d543d20SAndroid Build Coastguard Worker exit:
888*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid user");
889*2d543d20SAndroid Build Coastguard Worker return rc;
890*2d543d20SAndroid Build Coastguard Worker }
891*2d543d20SAndroid Build Coastguard Worker
__cil_verify_role(struct cil_tree_node * node)892*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_role(struct cil_tree_node *node)
893*2d543d20SAndroid Build Coastguard Worker {
894*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
895*2d543d20SAndroid Build Coastguard Worker struct cil_role *role = node->data;
896*2d543d20SAndroid Build Coastguard Worker int steps = 0;
897*2d543d20SAndroid Build Coastguard Worker int limit = 2;
898*2d543d20SAndroid Build Coastguard Worker struct cil_role *r1 = role;
899*2d543d20SAndroid Build Coastguard Worker struct cil_role *r2 = role->bounds;
900*2d543d20SAndroid Build Coastguard Worker
901*2d543d20SAndroid Build Coastguard Worker while (r2 != NULL) {
902*2d543d20SAndroid Build Coastguard Worker if (r1 == r2) {
903*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Circular bounds found for role %s\n", r1->datum.name);
904*2d543d20SAndroid Build Coastguard Worker goto exit;
905*2d543d20SAndroid Build Coastguard Worker }
906*2d543d20SAndroid Build Coastguard Worker
907*2d543d20SAndroid Build Coastguard Worker if (steps == limit) {
908*2d543d20SAndroid Build Coastguard Worker steps = 0;
909*2d543d20SAndroid Build Coastguard Worker limit *= 2;
910*2d543d20SAndroid Build Coastguard Worker r1 = r2;
911*2d543d20SAndroid Build Coastguard Worker }
912*2d543d20SAndroid Build Coastguard Worker
913*2d543d20SAndroid Build Coastguard Worker r2 = r2->bounds;
914*2d543d20SAndroid Build Coastguard Worker steps++;
915*2d543d20SAndroid Build Coastguard Worker }
916*2d543d20SAndroid Build Coastguard Worker
917*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
918*2d543d20SAndroid Build Coastguard Worker exit:
919*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid role");
920*2d543d20SAndroid Build Coastguard Worker return rc;
921*2d543d20SAndroid Build Coastguard Worker }
922*2d543d20SAndroid Build Coastguard Worker
__cil_verify_type(struct cil_tree_node * node)923*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_type(struct cil_tree_node *node)
924*2d543d20SAndroid Build Coastguard Worker {
925*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
926*2d543d20SAndroid Build Coastguard Worker struct cil_type *type = node->data;
927*2d543d20SAndroid Build Coastguard Worker int steps = 0;
928*2d543d20SAndroid Build Coastguard Worker int limit = 2;
929*2d543d20SAndroid Build Coastguard Worker struct cil_type *t1 = type;
930*2d543d20SAndroid Build Coastguard Worker struct cil_type *t2 = type->bounds;
931*2d543d20SAndroid Build Coastguard Worker
932*2d543d20SAndroid Build Coastguard Worker while (t2 != NULL) {
933*2d543d20SAndroid Build Coastguard Worker if (t1 == t2) {
934*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Circular bounds found for type %s\n", t1->datum.name);
935*2d543d20SAndroid Build Coastguard Worker goto exit;
936*2d543d20SAndroid Build Coastguard Worker }
937*2d543d20SAndroid Build Coastguard Worker
938*2d543d20SAndroid Build Coastguard Worker if (steps == limit) {
939*2d543d20SAndroid Build Coastguard Worker steps = 0;
940*2d543d20SAndroid Build Coastguard Worker limit *= 2;
941*2d543d20SAndroid Build Coastguard Worker t1 = t2;
942*2d543d20SAndroid Build Coastguard Worker }
943*2d543d20SAndroid Build Coastguard Worker
944*2d543d20SAndroid Build Coastguard Worker t2 = t2->bounds;
945*2d543d20SAndroid Build Coastguard Worker steps++;
946*2d543d20SAndroid Build Coastguard Worker }
947*2d543d20SAndroid Build Coastguard Worker
948*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
949*2d543d20SAndroid Build Coastguard Worker exit:
950*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid type");
951*2d543d20SAndroid Build Coastguard Worker return rc;
952*2d543d20SAndroid Build Coastguard Worker }
953*2d543d20SAndroid Build Coastguard Worker
__cil_verify_context(struct cil_db * db,struct cil_context * ctx)954*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_context(struct cil_db *db, struct cil_context *ctx)
955*2d543d20SAndroid Build Coastguard Worker {
956*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
957*2d543d20SAndroid Build Coastguard Worker struct cil_user *user = ctx->user;
958*2d543d20SAndroid Build Coastguard Worker struct cil_role *role = ctx->role;
959*2d543d20SAndroid Build Coastguard Worker struct cil_type *type = ctx->type;
960*2d543d20SAndroid Build Coastguard Worker struct cil_level *user_low = user->range->low;
961*2d543d20SAndroid Build Coastguard Worker struct cil_level *user_high = user->range->high;
962*2d543d20SAndroid Build Coastguard Worker struct cil_level *ctx_low = ctx->range->low;
963*2d543d20SAndroid Build Coastguard Worker struct cil_level *ctx_high = ctx->range->high;
964*2d543d20SAndroid Build Coastguard Worker struct cil_list *sensitivityorder = db->sensitivityorder;
965*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *curr;
966*2d543d20SAndroid Build Coastguard Worker int found = CIL_FALSE;
967*2d543d20SAndroid Build Coastguard Worker
968*2d543d20SAndroid Build Coastguard Worker if (user->roles != NULL) {
969*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_get_bit(user->roles, role->value)) {
970*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Role %s is invalid for user %s\n", ctx->role_str, ctx->user_str);
971*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
972*2d543d20SAndroid Build Coastguard Worker goto exit;
973*2d543d20SAndroid Build Coastguard Worker }
974*2d543d20SAndroid Build Coastguard Worker } else {
975*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "No roles given to the user %s\n", ctx->user_str);
976*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
977*2d543d20SAndroid Build Coastguard Worker goto exit;
978*2d543d20SAndroid Build Coastguard Worker }
979*2d543d20SAndroid Build Coastguard Worker
980*2d543d20SAndroid Build Coastguard Worker if (role->types != NULL) {
981*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_get_bit(role->types, type->value)) {
982*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Type %s is invalid for role %s\n", ctx->type_str, ctx->role_str);
983*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
984*2d543d20SAndroid Build Coastguard Worker goto exit;
985*2d543d20SAndroid Build Coastguard Worker }
986*2d543d20SAndroid Build Coastguard Worker } else {
987*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "No types associated with role %s\n", ctx->role_str);
988*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
989*2d543d20SAndroid Build Coastguard Worker goto exit;
990*2d543d20SAndroid Build Coastguard Worker }
991*2d543d20SAndroid Build Coastguard Worker
992*2d543d20SAndroid Build Coastguard Worker /* Verify range only when anonymous */
993*2d543d20SAndroid Build Coastguard Worker if (ctx->range->datum.name == NULL) {
994*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_levelrange(db, ctx->range);
995*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
996*2d543d20SAndroid Build Coastguard Worker goto exit;
997*2d543d20SAndroid Build Coastguard Worker }
998*2d543d20SAndroid Build Coastguard Worker }
999*2d543d20SAndroid Build Coastguard Worker
1000*2d543d20SAndroid Build Coastguard Worker for (curr = sensitivityorder->head; curr != NULL; curr = curr->next) {
1001*2d543d20SAndroid Build Coastguard Worker struct cil_sens *sens = curr->data;
1002*2d543d20SAndroid Build Coastguard Worker
1003*2d543d20SAndroid Build Coastguard Worker if (found == CIL_FALSE) {
1004*2d543d20SAndroid Build Coastguard Worker if (sens == user_low->sens) {
1005*2d543d20SAndroid Build Coastguard Worker found = CIL_TRUE;
1006*2d543d20SAndroid Build Coastguard Worker } else if (sens == ctx_low->sens) {
1007*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Range %s is invalid for user %s\n",
1008*2d543d20SAndroid Build Coastguard Worker ctx->range_str, ctx->user_str);
1009*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
1010*2d543d20SAndroid Build Coastguard Worker goto exit;
1011*2d543d20SAndroid Build Coastguard Worker }
1012*2d543d20SAndroid Build Coastguard Worker }
1013*2d543d20SAndroid Build Coastguard Worker
1014*2d543d20SAndroid Build Coastguard Worker if (found == CIL_TRUE) {
1015*2d543d20SAndroid Build Coastguard Worker if (sens == ctx_high->sens) {
1016*2d543d20SAndroid Build Coastguard Worker break;
1017*2d543d20SAndroid Build Coastguard Worker } else if (sens == user_high->sens) {
1018*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Range %s is invalid for user %s\n",
1019*2d543d20SAndroid Build Coastguard Worker ctx->range_str, ctx->user_str);
1020*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
1021*2d543d20SAndroid Build Coastguard Worker goto exit;
1022*2d543d20SAndroid Build Coastguard Worker }
1023*2d543d20SAndroid Build Coastguard Worker }
1024*2d543d20SAndroid Build Coastguard Worker }
1025*2d543d20SAndroid Build Coastguard Worker
1026*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1027*2d543d20SAndroid Build Coastguard Worker exit:
1028*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Invalid context\n");
1029*2d543d20SAndroid Build Coastguard Worker return rc;
1030*2d543d20SAndroid Build Coastguard Worker }
1031*2d543d20SAndroid Build Coastguard Worker
__cil_verify_named_context(struct cil_db * db,struct cil_tree_node * node)1032*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_named_context(struct cil_db *db, struct cil_tree_node *node)
1033*2d543d20SAndroid Build Coastguard Worker {
1034*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1035*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = node->data;
1036*2d543d20SAndroid Build Coastguard Worker
1037*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1038*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1039*2d543d20SAndroid Build Coastguard Worker goto exit;
1040*2d543d20SAndroid Build Coastguard Worker }
1041*2d543d20SAndroid Build Coastguard Worker
1042*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1043*2d543d20SAndroid Build Coastguard Worker exit:
1044*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid named context");
1045*2d543d20SAndroid Build Coastguard Worker return rc;
1046*2d543d20SAndroid Build Coastguard Worker }
1047*2d543d20SAndroid Build Coastguard Worker
1048*2d543d20SAndroid Build Coastguard Worker /*
1049*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_rule(struct cil_tree_node *node, struct cil_complex_symtab *symtab)
1050*2d543d20SAndroid Build Coastguard Worker {
1051*2d543d20SAndroid Build Coastguard Worker
1052*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1053*2d543d20SAndroid Build Coastguard Worker struct cil_type_rule *typerule = NULL;
1054*2d543d20SAndroid Build Coastguard Worker struct cil_roletransition *roletrans = NULL;
1055*2d543d20SAndroid Build Coastguard Worker struct cil_complex_symtab_key ckey;
1056*2d543d20SAndroid Build Coastguard Worker
1057*2d543d20SAndroid Build Coastguard Worker switch (node->flavor) {
1058*2d543d20SAndroid Build Coastguard Worker case CIL_ROLETRANSITION: {
1059*2d543d20SAndroid Build Coastguard Worker roletrans = node->data;
1060*2d543d20SAndroid Build Coastguard Worker ckey.key1 = (intptr_t)roletrans->src;
1061*2d543d20SAndroid Build Coastguard Worker ckey.key2 = (intptr_t)roletrans->tgt;
1062*2d543d20SAndroid Build Coastguard Worker ckey.key3 = (intptr_t)roletrans->obj;
1063*2d543d20SAndroid Build Coastguard Worker ckey.key4 = CIL_ROLETRANSITION;
1064*2d543d20SAndroid Build Coastguard Worker break;
1065*2d543d20SAndroid Build Coastguard Worker }
1066*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE_RULE: {
1067*2d543d20SAndroid Build Coastguard Worker typerule = node->data;
1068*2d543d20SAndroid Build Coastguard Worker ckey.key1 = (intptr_t)typerule->src;
1069*2d543d20SAndroid Build Coastguard Worker ckey.key2 = (intptr_t)typerule->tgt;
1070*2d543d20SAndroid Build Coastguard Worker ckey.key3 = (intptr_t)typerule->obj;
1071*2d543d20SAndroid Build Coastguard Worker ckey.key4 = (intptr_t)typerule->rule_kind;
1072*2d543d20SAndroid Build Coastguard Worker break;
1073*2d543d20SAndroid Build Coastguard Worker }
1074*2d543d20SAndroid Build Coastguard Worker default:
1075*2d543d20SAndroid Build Coastguard Worker break;
1076*2d543d20SAndroid Build Coastguard Worker }
1077*2d543d20SAndroid Build Coastguard Worker
1078*2d543d20SAndroid Build Coastguard Worker
1079*2d543d20SAndroid Build Coastguard Worker rc = cil_complex_symtab_insert(symtab, &ckey, NULL);
1080*2d543d20SAndroid Build Coastguard Worker if (rc == SEPOL_EEXIST) {
1081*2d543d20SAndroid Build Coastguard Worker struct cil_complex_symtab_datum *datum = NULL;
1082*2d543d20SAndroid Build Coastguard Worker cil_complex_symtab_search(symtab, &ckey, &datum);
1083*2d543d20SAndroid Build Coastguard Worker if (datum == NULL) {
1084*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Duplicate rule defined");
1085*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
1086*2d543d20SAndroid Build Coastguard Worker goto exit;
1087*2d543d20SAndroid Build Coastguard Worker }
1088*2d543d20SAndroid Build Coastguard Worker }
1089*2d543d20SAndroid Build Coastguard Worker
1090*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1091*2d543d20SAndroid Build Coastguard Worker exit:
1092*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid rule");
1093*2d543d20SAndroid Build Coastguard Worker return rc;
1094*2d543d20SAndroid Build Coastguard Worker }
1095*2d543d20SAndroid Build Coastguard Worker */
1096*2d543d20SAndroid Build Coastguard Worker
__cil_verify_booleanif_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1097*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_booleanif_helper(struct cil_tree_node *node, __attribute__((unused)) uint32_t *finished, __attribute__((unused)) void *extra_args)
1098*2d543d20SAndroid Build Coastguard Worker {
1099*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1100*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *rule_node = node;
1101*2d543d20SAndroid Build Coastguard Worker struct cil_booleanif *bif = node->parent->parent->data;
1102*2d543d20SAndroid Build Coastguard Worker
1103*2d543d20SAndroid Build Coastguard Worker switch (rule_node->flavor) {
1104*2d543d20SAndroid Build Coastguard Worker case CIL_AVRULE: {
1105*2d543d20SAndroid Build Coastguard Worker struct cil_avrule *avrule = NULL;
1106*2d543d20SAndroid Build Coastguard Worker avrule = rule_node->data;
1107*2d543d20SAndroid Build Coastguard Worker if (avrule->rule_kind == CIL_AVRULE_NEVERALLOW) {
1108*2d543d20SAndroid Build Coastguard Worker if (bif->preserved_tunable) {
1109*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Neverallow found in tunableif block (treated as a booleanif due to preserve-tunables)");
1110*2d543d20SAndroid Build Coastguard Worker } else {
1111*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Neverallow found in booleanif block");
1112*2d543d20SAndroid Build Coastguard Worker }
1113*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
1114*2d543d20SAndroid Build Coastguard Worker goto exit;
1115*2d543d20SAndroid Build Coastguard Worker }
1116*2d543d20SAndroid Build Coastguard Worker break;
1117*2d543d20SAndroid Build Coastguard Worker }
1118*2d543d20SAndroid Build Coastguard Worker case CIL_DENY_RULE:
1119*2d543d20SAndroid Build Coastguard Worker if (bif->preserved_tunable) {
1120*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Not allowed to have a deny rule in a tunableif block (treated as a booleanif due to preserve-tunables)");
1121*2d543d20SAndroid Build Coastguard Worker } else {
1122*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Not allowed to have deny rule in a booleanif block");
1123*2d543d20SAndroid Build Coastguard Worker }
1124*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
1125*2d543d20SAndroid Build Coastguard Worker goto exit;
1126*2d543d20SAndroid Build Coastguard Worker break;
1127*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE_RULE: /*
1128*2d543d20SAndroid Build Coastguard Worker struct cil_type_rule *typerule = NULL;
1129*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *temp_node = NULL;
1130*2d543d20SAndroid Build Coastguard Worker struct cil_complex_symtab *symtab = extra_args;
1131*2d543d20SAndroid Build Coastguard Worker struct cil_complex_symtab_key ckey;
1132*2d543d20SAndroid Build Coastguard Worker struct cil_complex_symtab_datum datum;
1133*2d543d20SAndroid Build Coastguard Worker typerule = rule_node->data;
1134*2d543d20SAndroid Build Coastguard Worker
1135*2d543d20SAndroid Build Coastguard Worker ckey.key1 = (intptr_t)typerule->src;
1136*2d543d20SAndroid Build Coastguard Worker ckey.key2 = (intptr_t)typerule->tgt;
1137*2d543d20SAndroid Build Coastguard Worker ckey.key3 = (intptr_t)typerule->obj;
1138*2d543d20SAndroid Build Coastguard Worker ckey.key4 = (intptr_t)typerule->rule_kind;
1139*2d543d20SAndroid Build Coastguard Worker
1140*2d543d20SAndroid Build Coastguard Worker datum.data = node;
1141*2d543d20SAndroid Build Coastguard Worker
1142*2d543d20SAndroid Build Coastguard Worker rc = cil_complex_symtab_insert(symtab, &ckey, &datum);
1143*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1144*2d543d20SAndroid Build Coastguard Worker goto exit;
1145*2d543d20SAndroid Build Coastguard Worker }
1146*2d543d20SAndroid Build Coastguard Worker
1147*2d543d20SAndroid Build Coastguard Worker for (temp_node = rule_node->next;
1148*2d543d20SAndroid Build Coastguard Worker temp_node != NULL;
1149*2d543d20SAndroid Build Coastguard Worker temp_node = temp_node->next) {
1150*2d543d20SAndroid Build Coastguard Worker
1151*2d543d20SAndroid Build Coastguard Worker if (temp_node->flavor == CIL_TYPE_RULE) {
1152*2d543d20SAndroid Build Coastguard Worker typerule = temp_node->data;
1153*2d543d20SAndroid Build Coastguard Worker if ((intptr_t)typerule->src == ckey.key1 &&
1154*2d543d20SAndroid Build Coastguard Worker (intptr_t)typerule->tgt == ckey.key2 &&
1155*2d543d20SAndroid Build Coastguard Worker (intptr_t)typerule->obj == ckey.key3 &&
1156*2d543d20SAndroid Build Coastguard Worker (intptr_t)typerule->rule_kind == ckey.key4) {
1157*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Duplicate type rule found (line: %d)\n", node->line);
1158*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
1159*2d543d20SAndroid Build Coastguard Worker goto exit;
1160*2d543d20SAndroid Build Coastguard Worker }
1161*2d543d20SAndroid Build Coastguard Worker }
1162*2d543d20SAndroid Build Coastguard Worker }
1163*2d543d20SAndroid Build Coastguard Worker break;*/
1164*2d543d20SAndroid Build Coastguard Worker
1165*2d543d20SAndroid Build Coastguard Worker //TODO Fix duplicate type_rule detection
1166*2d543d20SAndroid Build Coastguard Worker break;
1167*2d543d20SAndroid Build Coastguard Worker case CIL_CALL:
1168*2d543d20SAndroid Build Coastguard Worker //Fall through to check content of call
1169*2d543d20SAndroid Build Coastguard Worker break;
1170*2d543d20SAndroid Build Coastguard Worker case CIL_TUNABLEIF:
1171*2d543d20SAndroid Build Coastguard Worker //Fall through
1172*2d543d20SAndroid Build Coastguard Worker break;
1173*2d543d20SAndroid Build Coastguard Worker case CIL_NAMETYPETRANSITION:
1174*2d543d20SAndroid Build Coastguard Worker /* While type transitions with file component are not allowed in
1175*2d543d20SAndroid Build Coastguard Worker booleanif statements if they don't have "*" as the file. We
1176*2d543d20SAndroid Build Coastguard Worker can't check that here. Or at least we won't right now. */
1177*2d543d20SAndroid Build Coastguard Worker break;
1178*2d543d20SAndroid Build Coastguard Worker default: {
1179*2d543d20SAndroid Build Coastguard Worker const char * flavor = cil_node_to_string(node);
1180*2d543d20SAndroid Build Coastguard Worker if (bif->preserved_tunable) {
1181*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid %s statement in tunableif (treated as a booleanif due to preserve-tunables)", flavor);
1182*2d543d20SAndroid Build Coastguard Worker } else {
1183*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid %s statement in booleanif", flavor);
1184*2d543d20SAndroid Build Coastguard Worker }
1185*2d543d20SAndroid Build Coastguard Worker goto exit;
1186*2d543d20SAndroid Build Coastguard Worker }
1187*2d543d20SAndroid Build Coastguard Worker }
1188*2d543d20SAndroid Build Coastguard Worker
1189*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
1190*2d543d20SAndroid Build Coastguard Worker exit:
1191*2d543d20SAndroid Build Coastguard Worker return rc;
1192*2d543d20SAndroid Build Coastguard Worker }
1193*2d543d20SAndroid Build Coastguard Worker
__cil_verify_booleanif(struct cil_tree_node * node,struct cil_complex_symtab * symtab)1194*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_booleanif(struct cil_tree_node *node, struct cil_complex_symtab *symtab)
1195*2d543d20SAndroid Build Coastguard Worker {
1196*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1197*2d543d20SAndroid Build Coastguard Worker struct cil_booleanif *bif = (struct cil_booleanif*)node->data;
1198*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *cond_block = node->cl_head;
1199*2d543d20SAndroid Build Coastguard Worker
1200*2d543d20SAndroid Build Coastguard Worker while (cond_block != NULL) {
1201*2d543d20SAndroid Build Coastguard Worker rc = cil_tree_walk(cond_block, __cil_verify_booleanif_helper, NULL, NULL, symtab);
1202*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1203*2d543d20SAndroid Build Coastguard Worker goto exit;
1204*2d543d20SAndroid Build Coastguard Worker }
1205*2d543d20SAndroid Build Coastguard Worker cond_block = cond_block->next;
1206*2d543d20SAndroid Build Coastguard Worker }
1207*2d543d20SAndroid Build Coastguard Worker
1208*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1209*2d543d20SAndroid Build Coastguard Worker exit:
1210*2d543d20SAndroid Build Coastguard Worker if (bif->preserved_tunable) {
1211*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid tunableif (treated as a booleanif due to preserve-tunables)");
1212*2d543d20SAndroid Build Coastguard Worker } else {
1213*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid booleanif");
1214*2d543d20SAndroid Build Coastguard Worker }
1215*2d543d20SAndroid Build Coastguard Worker return rc;
1216*2d543d20SAndroid Build Coastguard Worker }
1217*2d543d20SAndroid Build Coastguard Worker
__cil_verify_netifcon(struct cil_db * db,struct cil_tree_node * node)1218*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_netifcon(struct cil_db *db, struct cil_tree_node *node)
1219*2d543d20SAndroid Build Coastguard Worker {
1220*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1221*2d543d20SAndroid Build Coastguard Worker struct cil_netifcon *netif = node->data;
1222*2d543d20SAndroid Build Coastguard Worker struct cil_context *if_ctx = netif->if_context;
1223*2d543d20SAndroid Build Coastguard Worker struct cil_context *pkt_ctx = netif->packet_context;
1224*2d543d20SAndroid Build Coastguard Worker
1225*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1226*2d543d20SAndroid Build Coastguard Worker if (if_ctx->datum.name == NULL) {
1227*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, if_ctx);
1228*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1229*2d543d20SAndroid Build Coastguard Worker goto exit;
1230*2d543d20SAndroid Build Coastguard Worker }
1231*2d543d20SAndroid Build Coastguard Worker }
1232*2d543d20SAndroid Build Coastguard Worker
1233*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1234*2d543d20SAndroid Build Coastguard Worker if (pkt_ctx->datum.name == NULL) {
1235*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, pkt_ctx);
1236*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1237*2d543d20SAndroid Build Coastguard Worker goto exit;
1238*2d543d20SAndroid Build Coastguard Worker }
1239*2d543d20SAndroid Build Coastguard Worker }
1240*2d543d20SAndroid Build Coastguard Worker
1241*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1242*2d543d20SAndroid Build Coastguard Worker
1243*2d543d20SAndroid Build Coastguard Worker exit:
1244*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid netifcon");
1245*2d543d20SAndroid Build Coastguard Worker return rc;
1246*2d543d20SAndroid Build Coastguard Worker }
1247*2d543d20SAndroid Build Coastguard Worker
__cil_verify_ibendportcon(struct cil_db * db,struct cil_tree_node * node)1248*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_ibendportcon(struct cil_db *db, struct cil_tree_node *node)
1249*2d543d20SAndroid Build Coastguard Worker {
1250*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1251*2d543d20SAndroid Build Coastguard Worker struct cil_ibendportcon *ib_end_port = node->data;
1252*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = ib_end_port->context;
1253*2d543d20SAndroid Build Coastguard Worker
1254*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1255*2d543d20SAndroid Build Coastguard Worker if (!ctx->datum.name) {
1256*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1257*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK)
1258*2d543d20SAndroid Build Coastguard Worker goto exit;
1259*2d543d20SAndroid Build Coastguard Worker }
1260*2d543d20SAndroid Build Coastguard Worker
1261*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1262*2d543d20SAndroid Build Coastguard Worker
1263*2d543d20SAndroid Build Coastguard Worker exit:
1264*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid ibendportcon");
1265*2d543d20SAndroid Build Coastguard Worker return rc;
1266*2d543d20SAndroid Build Coastguard Worker }
1267*2d543d20SAndroid Build Coastguard Worker
__cil_verify_genfscon(struct cil_db * db,struct cil_tree_node * node)1268*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_genfscon(struct cil_db *db, struct cil_tree_node *node)
1269*2d543d20SAndroid Build Coastguard Worker {
1270*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1271*2d543d20SAndroid Build Coastguard Worker struct cil_genfscon *genfs = node->data;
1272*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = genfs->context;
1273*2d543d20SAndroid Build Coastguard Worker
1274*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1275*2d543d20SAndroid Build Coastguard Worker if (ctx->datum.name == NULL) {
1276*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1277*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1278*2d543d20SAndroid Build Coastguard Worker goto exit;
1279*2d543d20SAndroid Build Coastguard Worker }
1280*2d543d20SAndroid Build Coastguard Worker }
1281*2d543d20SAndroid Build Coastguard Worker
1282*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1283*2d543d20SAndroid Build Coastguard Worker
1284*2d543d20SAndroid Build Coastguard Worker exit:
1285*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid genfscon");
1286*2d543d20SAndroid Build Coastguard Worker return rc;
1287*2d543d20SAndroid Build Coastguard Worker }
1288*2d543d20SAndroid Build Coastguard Worker
__cil_verify_filecon(struct cil_db * db,struct cil_tree_node * node)1289*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_filecon(struct cil_db *db, struct cil_tree_node *node)
1290*2d543d20SAndroid Build Coastguard Worker {
1291*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1292*2d543d20SAndroid Build Coastguard Worker struct cil_filecon *file = node->data;
1293*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = file->context;
1294*2d543d20SAndroid Build Coastguard Worker
1295*2d543d20SAndroid Build Coastguard Worker if (ctx == NULL) {
1296*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
1297*2d543d20SAndroid Build Coastguard Worker goto exit;
1298*2d543d20SAndroid Build Coastguard Worker }
1299*2d543d20SAndroid Build Coastguard Worker
1300*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1301*2d543d20SAndroid Build Coastguard Worker if (ctx->datum.name == NULL) {
1302*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1303*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1304*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid filecon");
1305*2d543d20SAndroid Build Coastguard Worker goto exit;
1306*2d543d20SAndroid Build Coastguard Worker }
1307*2d543d20SAndroid Build Coastguard Worker }
1308*2d543d20SAndroid Build Coastguard Worker
1309*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1310*2d543d20SAndroid Build Coastguard Worker
1311*2d543d20SAndroid Build Coastguard Worker exit:
1312*2d543d20SAndroid Build Coastguard Worker return rc;
1313*2d543d20SAndroid Build Coastguard Worker }
1314*2d543d20SAndroid Build Coastguard Worker
__cil_verify_nodecon(struct cil_db * db,struct cil_tree_node * node)1315*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_nodecon(struct cil_db *db, struct cil_tree_node *node)
1316*2d543d20SAndroid Build Coastguard Worker {
1317*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1318*2d543d20SAndroid Build Coastguard Worker struct cil_nodecon *nodecon = node->data;
1319*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = nodecon->context;
1320*2d543d20SAndroid Build Coastguard Worker
1321*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1322*2d543d20SAndroid Build Coastguard Worker if (ctx->datum.name == NULL) {
1323*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1324*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1325*2d543d20SAndroid Build Coastguard Worker goto exit;
1326*2d543d20SAndroid Build Coastguard Worker }
1327*2d543d20SAndroid Build Coastguard Worker }
1328*2d543d20SAndroid Build Coastguard Worker
1329*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1330*2d543d20SAndroid Build Coastguard Worker
1331*2d543d20SAndroid Build Coastguard Worker exit:
1332*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid nodecon");
1333*2d543d20SAndroid Build Coastguard Worker return rc;
1334*2d543d20SAndroid Build Coastguard Worker }
1335*2d543d20SAndroid Build Coastguard Worker
__cil_verify_ibpkeycon(struct cil_db * db,struct cil_tree_node * node)1336*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_ibpkeycon(struct cil_db *db, struct cil_tree_node *node)
1337*2d543d20SAndroid Build Coastguard Worker {
1338*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1339*2d543d20SAndroid Build Coastguard Worker struct cil_ibpkeycon *pkey = node->data;
1340*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = pkey->context;
1341*2d543d20SAndroid Build Coastguard Worker
1342*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1343*2d543d20SAndroid Build Coastguard Worker if (!ctx->datum.name) {
1344*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1345*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK)
1346*2d543d20SAndroid Build Coastguard Worker goto exit;
1347*2d543d20SAndroid Build Coastguard Worker }
1348*2d543d20SAndroid Build Coastguard Worker
1349*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1350*2d543d20SAndroid Build Coastguard Worker
1351*2d543d20SAndroid Build Coastguard Worker exit:
1352*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid ibpkeycon");
1353*2d543d20SAndroid Build Coastguard Worker return rc;
1354*2d543d20SAndroid Build Coastguard Worker }
1355*2d543d20SAndroid Build Coastguard Worker
__cil_verify_portcon(struct cil_db * db,struct cil_tree_node * node)1356*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_portcon(struct cil_db *db, struct cil_tree_node *node)
1357*2d543d20SAndroid Build Coastguard Worker {
1358*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1359*2d543d20SAndroid Build Coastguard Worker struct cil_portcon *port = node->data;
1360*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = port->context;
1361*2d543d20SAndroid Build Coastguard Worker
1362*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1363*2d543d20SAndroid Build Coastguard Worker if (ctx->datum.name == NULL) {
1364*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1365*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1366*2d543d20SAndroid Build Coastguard Worker goto exit;
1367*2d543d20SAndroid Build Coastguard Worker }
1368*2d543d20SAndroid Build Coastguard Worker }
1369*2d543d20SAndroid Build Coastguard Worker
1370*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1371*2d543d20SAndroid Build Coastguard Worker
1372*2d543d20SAndroid Build Coastguard Worker exit:
1373*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid portcon");
1374*2d543d20SAndroid Build Coastguard Worker return rc;
1375*2d543d20SAndroid Build Coastguard Worker }
1376*2d543d20SAndroid Build Coastguard Worker
__cil_verify_pirqcon(struct cil_db * db,struct cil_tree_node * node)1377*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_pirqcon(struct cil_db *db, struct cil_tree_node *node)
1378*2d543d20SAndroid Build Coastguard Worker {
1379*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1380*2d543d20SAndroid Build Coastguard Worker struct cil_pirqcon *pirq = node->data;
1381*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = pirq->context;
1382*2d543d20SAndroid Build Coastguard Worker
1383*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1384*2d543d20SAndroid Build Coastguard Worker if (ctx->datum.name == NULL) {
1385*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1386*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1387*2d543d20SAndroid Build Coastguard Worker goto exit;
1388*2d543d20SAndroid Build Coastguard Worker }
1389*2d543d20SAndroid Build Coastguard Worker }
1390*2d543d20SAndroid Build Coastguard Worker
1391*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1392*2d543d20SAndroid Build Coastguard Worker
1393*2d543d20SAndroid Build Coastguard Worker exit:
1394*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid pirqcon");
1395*2d543d20SAndroid Build Coastguard Worker return rc;
1396*2d543d20SAndroid Build Coastguard Worker }
1397*2d543d20SAndroid Build Coastguard Worker
__cil_verify_iomemcon(struct cil_db * db,struct cil_tree_node * node)1398*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_iomemcon(struct cil_db *db, struct cil_tree_node *node)
1399*2d543d20SAndroid Build Coastguard Worker {
1400*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1401*2d543d20SAndroid Build Coastguard Worker struct cil_iomemcon *iomem = node->data;
1402*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = iomem->context;
1403*2d543d20SAndroid Build Coastguard Worker
1404*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1405*2d543d20SAndroid Build Coastguard Worker if (ctx->datum.name == NULL) {
1406*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1407*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1408*2d543d20SAndroid Build Coastguard Worker goto exit;
1409*2d543d20SAndroid Build Coastguard Worker }
1410*2d543d20SAndroid Build Coastguard Worker }
1411*2d543d20SAndroid Build Coastguard Worker
1412*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1413*2d543d20SAndroid Build Coastguard Worker
1414*2d543d20SAndroid Build Coastguard Worker exit:
1415*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid iomemcon");
1416*2d543d20SAndroid Build Coastguard Worker return rc;
1417*2d543d20SAndroid Build Coastguard Worker }
1418*2d543d20SAndroid Build Coastguard Worker
__cil_verify_ioportcon(struct cil_db * db,struct cil_tree_node * node)1419*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_ioportcon(struct cil_db *db, struct cil_tree_node *node)
1420*2d543d20SAndroid Build Coastguard Worker {
1421*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1422*2d543d20SAndroid Build Coastguard Worker struct cil_ioportcon *ioport = node->data;
1423*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = ioport->context;
1424*2d543d20SAndroid Build Coastguard Worker
1425*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1426*2d543d20SAndroid Build Coastguard Worker if (ctx->datum.name == NULL) {
1427*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1428*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1429*2d543d20SAndroid Build Coastguard Worker goto exit;
1430*2d543d20SAndroid Build Coastguard Worker }
1431*2d543d20SAndroid Build Coastguard Worker }
1432*2d543d20SAndroid Build Coastguard Worker
1433*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1434*2d543d20SAndroid Build Coastguard Worker
1435*2d543d20SAndroid Build Coastguard Worker exit:
1436*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid ioportcon");
1437*2d543d20SAndroid Build Coastguard Worker return rc;
1438*2d543d20SAndroid Build Coastguard Worker }
1439*2d543d20SAndroid Build Coastguard Worker
__cil_verify_pcidevicecon(struct cil_db * db,struct cil_tree_node * node)1440*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_pcidevicecon(struct cil_db *db, struct cil_tree_node *node)
1441*2d543d20SAndroid Build Coastguard Worker {
1442*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1443*2d543d20SAndroid Build Coastguard Worker struct cil_pcidevicecon *pcidev = node->data;
1444*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = pcidev->context;
1445*2d543d20SAndroid Build Coastguard Worker
1446*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1447*2d543d20SAndroid Build Coastguard Worker if (ctx->datum.name == NULL) {
1448*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1449*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1450*2d543d20SAndroid Build Coastguard Worker goto exit;
1451*2d543d20SAndroid Build Coastguard Worker }
1452*2d543d20SAndroid Build Coastguard Worker }
1453*2d543d20SAndroid Build Coastguard Worker
1454*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1455*2d543d20SAndroid Build Coastguard Worker
1456*2d543d20SAndroid Build Coastguard Worker exit:
1457*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid pcidevicecon");
1458*2d543d20SAndroid Build Coastguard Worker return rc;
1459*2d543d20SAndroid Build Coastguard Worker }
1460*2d543d20SAndroid Build Coastguard Worker
__cil_verify_devicetreecon(struct cil_db * db,struct cil_tree_node * node)1461*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_devicetreecon(struct cil_db *db, struct cil_tree_node *node)
1462*2d543d20SAndroid Build Coastguard Worker {
1463*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1464*2d543d20SAndroid Build Coastguard Worker struct cil_devicetreecon *dt = node->data;
1465*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = dt->context;
1466*2d543d20SAndroid Build Coastguard Worker
1467*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1468*2d543d20SAndroid Build Coastguard Worker if (ctx->datum.name == NULL) {
1469*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1470*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1471*2d543d20SAndroid Build Coastguard Worker goto exit;
1472*2d543d20SAndroid Build Coastguard Worker }
1473*2d543d20SAndroid Build Coastguard Worker }
1474*2d543d20SAndroid Build Coastguard Worker
1475*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1476*2d543d20SAndroid Build Coastguard Worker
1477*2d543d20SAndroid Build Coastguard Worker exit:
1478*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid devicetreecon");
1479*2d543d20SAndroid Build Coastguard Worker return rc;
1480*2d543d20SAndroid Build Coastguard Worker }
1481*2d543d20SAndroid Build Coastguard Worker
__cil_verify_fsuse(struct cil_db * db,struct cil_tree_node * node)1482*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_fsuse(struct cil_db *db, struct cil_tree_node *node)
1483*2d543d20SAndroid Build Coastguard Worker {
1484*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1485*2d543d20SAndroid Build Coastguard Worker struct cil_fsuse *fsuse = node->data;
1486*2d543d20SAndroid Build Coastguard Worker struct cil_context *ctx = fsuse->context;
1487*2d543d20SAndroid Build Coastguard Worker
1488*2d543d20SAndroid Build Coastguard Worker /* Verify only when anonymous */
1489*2d543d20SAndroid Build Coastguard Worker if (ctx->datum.name == NULL) {
1490*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_context(db, ctx);
1491*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1492*2d543d20SAndroid Build Coastguard Worker goto exit;
1493*2d543d20SAndroid Build Coastguard Worker }
1494*2d543d20SAndroid Build Coastguard Worker }
1495*2d543d20SAndroid Build Coastguard Worker
1496*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1497*2d543d20SAndroid Build Coastguard Worker
1498*2d543d20SAndroid Build Coastguard Worker exit:
1499*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid fsuse");
1500*2d543d20SAndroid Build Coastguard Worker return rc;
1501*2d543d20SAndroid Build Coastguard Worker }
1502*2d543d20SAndroid Build Coastguard Worker
__cil_verify_permissionx(struct cil_permissionx * permx,struct cil_tree_node * node)1503*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tree_node *node)
1504*2d543d20SAndroid Build Coastguard Worker {
1505*2d543d20SAndroid Build Coastguard Worker int rc;
1506*2d543d20SAndroid Build Coastguard Worker struct cil_list *classes = NULL;
1507*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *item;
1508*2d543d20SAndroid Build Coastguard Worker struct cil_class *class;
1509*2d543d20SAndroid Build Coastguard Worker struct cil_symtab_datum *perm_datum;
1510*2d543d20SAndroid Build Coastguard Worker char *kind_str;
1511*2d543d20SAndroid Build Coastguard Worker
1512*2d543d20SAndroid Build Coastguard Worker switch (permx->kind) {
1513*2d543d20SAndroid Build Coastguard Worker case CIL_PERMX_KIND_IOCTL:
1514*2d543d20SAndroid Build Coastguard Worker kind_str = CIL_KEY_IOCTL;
1515*2d543d20SAndroid Build Coastguard Worker break;
1516*2d543d20SAndroid Build Coastguard Worker case CIL_PERMX_KIND_NLMSG:
1517*2d543d20SAndroid Build Coastguard Worker kind_str = CIL_KEY_NLMSG;
1518*2d543d20SAndroid Build Coastguard Worker break;
1519*2d543d20SAndroid Build Coastguard Worker default:
1520*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid permissionx kind (%d)", permx->kind);
1521*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
1522*2d543d20SAndroid Build Coastguard Worker goto exit;
1523*2d543d20SAndroid Build Coastguard Worker }
1524*2d543d20SAndroid Build Coastguard Worker
1525*2d543d20SAndroid Build Coastguard Worker classes = cil_expand_class(permx->obj);
1526*2d543d20SAndroid Build Coastguard Worker
1527*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(item, classes) {
1528*2d543d20SAndroid Build Coastguard Worker class = item->data;
1529*2d543d20SAndroid Build Coastguard Worker rc = cil_symtab_get_datum(&class->perms, kind_str, &perm_datum);
1530*2d543d20SAndroid Build Coastguard Worker if (rc == SEPOL_ENOENT) {
1531*2d543d20SAndroid Build Coastguard Worker if (class->common != NULL) {
1532*2d543d20SAndroid Build Coastguard Worker rc = cil_symtab_get_datum(&class->common->perms, kind_str, &perm_datum);
1533*2d543d20SAndroid Build Coastguard Worker }
1534*2d543d20SAndroid Build Coastguard Worker
1535*2d543d20SAndroid Build Coastguard Worker if (rc == SEPOL_ENOENT) {
1536*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid permissionx: %s is not a permission of class %s", kind_str, class->datum.name);
1537*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
1538*2d543d20SAndroid Build Coastguard Worker goto exit;
1539*2d543d20SAndroid Build Coastguard Worker }
1540*2d543d20SAndroid Build Coastguard Worker }
1541*2d543d20SAndroid Build Coastguard Worker }
1542*2d543d20SAndroid Build Coastguard Worker
1543*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
1544*2d543d20SAndroid Build Coastguard Worker
1545*2d543d20SAndroid Build Coastguard Worker exit:
1546*2d543d20SAndroid Build Coastguard Worker if (classes != NULL) {
1547*2d543d20SAndroid Build Coastguard Worker cil_list_destroy(&classes, CIL_FALSE);
1548*2d543d20SAndroid Build Coastguard Worker }
1549*2d543d20SAndroid Build Coastguard Worker
1550*2d543d20SAndroid Build Coastguard Worker return rc;
1551*2d543d20SAndroid Build Coastguard Worker }
1552*2d543d20SAndroid Build Coastguard Worker
__cil_verify_avrulex(struct cil_tree_node * node)1553*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_avrulex(struct cil_tree_node *node)
1554*2d543d20SAndroid Build Coastguard Worker {
1555*2d543d20SAndroid Build Coastguard Worker struct cil_avrule *avrulex = node->data;
1556*2d543d20SAndroid Build Coastguard Worker return __cil_verify_permissionx(avrulex->perms.x.permx, node);
1557*2d543d20SAndroid Build Coastguard Worker }
1558*2d543d20SAndroid Build Coastguard Worker
__cil_verify_class(struct cil_tree_node * node)1559*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_class(struct cil_tree_node *node)
1560*2d543d20SAndroid Build Coastguard Worker {
1561*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1562*2d543d20SAndroid Build Coastguard Worker struct cil_class *class = node->data;
1563*2d543d20SAndroid Build Coastguard Worker
1564*2d543d20SAndroid Build Coastguard Worker if (class->common != NULL) {
1565*2d543d20SAndroid Build Coastguard Worker struct cil_class *common = class->common;
1566*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *common_node = common->datum.nodes->head->data;
1567*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *curr_com_perm = NULL;
1568*2d543d20SAndroid Build Coastguard Worker
1569*2d543d20SAndroid Build Coastguard Worker for (curr_com_perm = common_node->cl_head;
1570*2d543d20SAndroid Build Coastguard Worker curr_com_perm != NULL;
1571*2d543d20SAndroid Build Coastguard Worker curr_com_perm = curr_com_perm->next) {
1572*2d543d20SAndroid Build Coastguard Worker struct cil_perm *com_perm = curr_com_perm->data;
1573*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *curr_class_perm = NULL;
1574*2d543d20SAndroid Build Coastguard Worker
1575*2d543d20SAndroid Build Coastguard Worker for (curr_class_perm = node->cl_head;
1576*2d543d20SAndroid Build Coastguard Worker curr_class_perm != NULL;
1577*2d543d20SAndroid Build Coastguard Worker curr_class_perm = curr_class_perm->next) {
1578*2d543d20SAndroid Build Coastguard Worker struct cil_perm *class_perm = curr_class_perm->data;
1579*2d543d20SAndroid Build Coastguard Worker
1580*2d543d20SAndroid Build Coastguard Worker if (com_perm->datum.name == class_perm->datum.name) {
1581*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Duplicate permissions between %s common and class declarations\n", class_perm->datum.name);
1582*2d543d20SAndroid Build Coastguard Worker goto exit;
1583*2d543d20SAndroid Build Coastguard Worker }
1584*2d543d20SAndroid Build Coastguard Worker }
1585*2d543d20SAndroid Build Coastguard Worker }
1586*2d543d20SAndroid Build Coastguard Worker }
1587*2d543d20SAndroid Build Coastguard Worker
1588*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1589*2d543d20SAndroid Build Coastguard Worker
1590*2d543d20SAndroid Build Coastguard Worker exit:
1591*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid class");
1592*2d543d20SAndroid Build Coastguard Worker return rc;
1593*2d543d20SAndroid Build Coastguard Worker }
1594*2d543d20SAndroid Build Coastguard Worker
__cil_verify_policycap(struct cil_tree_node * node)1595*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_policycap(struct cil_tree_node *node)
1596*2d543d20SAndroid Build Coastguard Worker {
1597*2d543d20SAndroid Build Coastguard Worker int rc;
1598*2d543d20SAndroid Build Coastguard Worker struct cil_policycap *polcap = node->data;
1599*2d543d20SAndroid Build Coastguard Worker
1600*2d543d20SAndroid Build Coastguard Worker rc = sepol_polcap_getnum((const char*)polcap->datum.name);
1601*2d543d20SAndroid Build Coastguard Worker if (rc == SEPOL_ERR) {
1602*2d543d20SAndroid Build Coastguard Worker goto exit;
1603*2d543d20SAndroid Build Coastguard Worker }
1604*2d543d20SAndroid Build Coastguard Worker
1605*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1606*2d543d20SAndroid Build Coastguard Worker
1607*2d543d20SAndroid Build Coastguard Worker exit:
1608*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Invalid policycap (%s)", (const char*)polcap->datum.name);
1609*2d543d20SAndroid Build Coastguard Worker return rc;
1610*2d543d20SAndroid Build Coastguard Worker }
1611*2d543d20SAndroid Build Coastguard Worker
__cil_verify_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1612*2d543d20SAndroid Build Coastguard Worker int __cil_verify_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
1613*2d543d20SAndroid Build Coastguard Worker {
1614*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1615*2d543d20SAndroid Build Coastguard Worker int *avrule_cnt = 0;
1616*2d543d20SAndroid Build Coastguard Worker int *handleunknown;
1617*2d543d20SAndroid Build Coastguard Worker int *mls;
1618*2d543d20SAndroid Build Coastguard Worker int *nseuserdflt = 0;
1619*2d543d20SAndroid Build Coastguard Worker int *pass = 0;
1620*2d543d20SAndroid Build Coastguard Worker struct cil_args_verify *args = extra_args;
1621*2d543d20SAndroid Build Coastguard Worker struct cil_complex_symtab *csymtab = NULL;
1622*2d543d20SAndroid Build Coastguard Worker struct cil_db *db = NULL;
1623*2d543d20SAndroid Build Coastguard Worker
1624*2d543d20SAndroid Build Coastguard Worker if (node == NULL || extra_args == NULL) {
1625*2d543d20SAndroid Build Coastguard Worker goto exit;
1626*2d543d20SAndroid Build Coastguard Worker }
1627*2d543d20SAndroid Build Coastguard Worker
1628*2d543d20SAndroid Build Coastguard Worker db = args->db;
1629*2d543d20SAndroid Build Coastguard Worker avrule_cnt = args->avrule_cnt;
1630*2d543d20SAndroid Build Coastguard Worker handleunknown = args->handleunknown;
1631*2d543d20SAndroid Build Coastguard Worker mls = args->mls;
1632*2d543d20SAndroid Build Coastguard Worker nseuserdflt = args->nseuserdflt;
1633*2d543d20SAndroid Build Coastguard Worker csymtab = args->csymtab;
1634*2d543d20SAndroid Build Coastguard Worker pass = args->pass;
1635*2d543d20SAndroid Build Coastguard Worker
1636*2d543d20SAndroid Build Coastguard Worker if (node->flavor == CIL_MACRO) {
1637*2d543d20SAndroid Build Coastguard Worker *finished = CIL_TREE_SKIP_HEAD;
1638*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
1639*2d543d20SAndroid Build Coastguard Worker goto exit;
1640*2d543d20SAndroid Build Coastguard Worker } else if (node->flavor == CIL_BLOCK) {
1641*2d543d20SAndroid Build Coastguard Worker struct cil_block *blk = node->data;
1642*2d543d20SAndroid Build Coastguard Worker if (blk->is_abstract == CIL_TRUE) {
1643*2d543d20SAndroid Build Coastguard Worker *finished = CIL_TREE_SKIP_HEAD;
1644*2d543d20SAndroid Build Coastguard Worker }
1645*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
1646*2d543d20SAndroid Build Coastguard Worker goto exit;
1647*2d543d20SAndroid Build Coastguard Worker }
1648*2d543d20SAndroid Build Coastguard Worker
1649*2d543d20SAndroid Build Coastguard Worker switch (*pass) {
1650*2d543d20SAndroid Build Coastguard Worker case 0: {
1651*2d543d20SAndroid Build Coastguard Worker switch (node->flavor) {
1652*2d543d20SAndroid Build Coastguard Worker case CIL_USER:
1653*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_user_post_eval(db, node);
1654*2d543d20SAndroid Build Coastguard Worker break;
1655*2d543d20SAndroid Build Coastguard Worker case CIL_SELINUXUSERDEFAULT:
1656*2d543d20SAndroid Build Coastguard Worker (*nseuserdflt)++;
1657*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
1658*2d543d20SAndroid Build Coastguard Worker break;
1659*2d543d20SAndroid Build Coastguard Worker case CIL_ROLE:
1660*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_role(node);
1661*2d543d20SAndroid Build Coastguard Worker break;
1662*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE:
1663*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_type(node);
1664*2d543d20SAndroid Build Coastguard Worker break;
1665*2d543d20SAndroid Build Coastguard Worker case CIL_AVRULE:
1666*2d543d20SAndroid Build Coastguard Worker (*avrule_cnt)++;
1667*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
1668*2d543d20SAndroid Build Coastguard Worker break;
1669*2d543d20SAndroid Build Coastguard Worker case CIL_HANDLEUNKNOWN:
1670*2d543d20SAndroid Build Coastguard Worker if (*handleunknown != -1) {
1671*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Policy can not have more than one handleunknown\n");
1672*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
1673*2d543d20SAndroid Build Coastguard Worker } else {
1674*2d543d20SAndroid Build Coastguard Worker *handleunknown = ((struct cil_handleunknown*)node->data)->handle_unknown;
1675*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
1676*2d543d20SAndroid Build Coastguard Worker }
1677*2d543d20SAndroid Build Coastguard Worker break;
1678*2d543d20SAndroid Build Coastguard Worker case CIL_MLS:
1679*2d543d20SAndroid Build Coastguard Worker if (*mls != -1) {
1680*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "Policy can not have more than one mls\n");
1681*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
1682*2d543d20SAndroid Build Coastguard Worker } else {
1683*2d543d20SAndroid Build Coastguard Worker *mls = ((struct cil_mls*)node->data)->value;
1684*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
1685*2d543d20SAndroid Build Coastguard Worker }
1686*2d543d20SAndroid Build Coastguard Worker break;
1687*2d543d20SAndroid Build Coastguard Worker case CIL_ROLETRANSITION:
1688*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK; //TODO __cil_verify_rule doesn't work quite right
1689*2d543d20SAndroid Build Coastguard Worker //rc = __cil_verify_rule(node, csymtab);
1690*2d543d20SAndroid Build Coastguard Worker break;
1691*2d543d20SAndroid Build Coastguard Worker case CIL_TYPE_RULE:
1692*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK; //TODO __cil_verify_rule doesn't work quite right
1693*2d543d20SAndroid Build Coastguard Worker //rc = __cil_verify_rule(node, csymtab);
1694*2d543d20SAndroid Build Coastguard Worker break;
1695*2d543d20SAndroid Build Coastguard Worker case CIL_BOOLEANIF:
1696*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_booleanif(node, csymtab);
1697*2d543d20SAndroid Build Coastguard Worker *finished = CIL_TREE_SKIP_HEAD;
1698*2d543d20SAndroid Build Coastguard Worker break;
1699*2d543d20SAndroid Build Coastguard Worker case CIL_LEVELRANGE:
1700*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_named_levelrange(db, node);
1701*2d543d20SAndroid Build Coastguard Worker break;
1702*2d543d20SAndroid Build Coastguard Worker case CIL_CLASS:
1703*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_class(node);
1704*2d543d20SAndroid Build Coastguard Worker break;
1705*2d543d20SAndroid Build Coastguard Worker case CIL_POLICYCAP:
1706*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_policycap(node);
1707*2d543d20SAndroid Build Coastguard Worker break;
1708*2d543d20SAndroid Build Coastguard Worker default:
1709*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
1710*2d543d20SAndroid Build Coastguard Worker break;
1711*2d543d20SAndroid Build Coastguard Worker }
1712*2d543d20SAndroid Build Coastguard Worker break;
1713*2d543d20SAndroid Build Coastguard Worker }
1714*2d543d20SAndroid Build Coastguard Worker case 1: {
1715*2d543d20SAndroid Build Coastguard Worker switch (node->flavor) {
1716*2d543d20SAndroid Build Coastguard Worker case CIL_CONTEXT:
1717*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_named_context(db, node);
1718*2d543d20SAndroid Build Coastguard Worker break;
1719*2d543d20SAndroid Build Coastguard Worker case CIL_NETIFCON:
1720*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_netifcon(db, node);
1721*2d543d20SAndroid Build Coastguard Worker break;
1722*2d543d20SAndroid Build Coastguard Worker case CIL_GENFSCON:
1723*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_genfscon(db, node);
1724*2d543d20SAndroid Build Coastguard Worker break;
1725*2d543d20SAndroid Build Coastguard Worker case CIL_FILECON:
1726*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_filecon(db, node);
1727*2d543d20SAndroid Build Coastguard Worker break;
1728*2d543d20SAndroid Build Coastguard Worker case CIL_NODECON:
1729*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_nodecon(db, node);
1730*2d543d20SAndroid Build Coastguard Worker break;
1731*2d543d20SAndroid Build Coastguard Worker case CIL_IBPKEYCON:
1732*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_ibpkeycon(db, node);
1733*2d543d20SAndroid Build Coastguard Worker break;
1734*2d543d20SAndroid Build Coastguard Worker case CIL_IBENDPORTCON:
1735*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_ibendportcon(db, node);
1736*2d543d20SAndroid Build Coastguard Worker break;
1737*2d543d20SAndroid Build Coastguard Worker case CIL_PORTCON:
1738*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_portcon(db, node);
1739*2d543d20SAndroid Build Coastguard Worker break;
1740*2d543d20SAndroid Build Coastguard Worker case CIL_PIRQCON:
1741*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_pirqcon(db, node);
1742*2d543d20SAndroid Build Coastguard Worker break;
1743*2d543d20SAndroid Build Coastguard Worker case CIL_IOMEMCON:
1744*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_iomemcon(db, node);
1745*2d543d20SAndroid Build Coastguard Worker break;
1746*2d543d20SAndroid Build Coastguard Worker case CIL_IOPORTCON:
1747*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_ioportcon(db, node);
1748*2d543d20SAndroid Build Coastguard Worker break;
1749*2d543d20SAndroid Build Coastguard Worker case CIL_PCIDEVICECON:
1750*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_pcidevicecon(db, node);
1751*2d543d20SAndroid Build Coastguard Worker break;
1752*2d543d20SAndroid Build Coastguard Worker case CIL_DEVICETREECON:
1753*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_devicetreecon(db, node);
1754*2d543d20SAndroid Build Coastguard Worker break;
1755*2d543d20SAndroid Build Coastguard Worker case CIL_FSUSE:
1756*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_fsuse(db, node);
1757*2d543d20SAndroid Build Coastguard Worker break;
1758*2d543d20SAndroid Build Coastguard Worker case CIL_AVRULEX:
1759*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_avrulex(node);
1760*2d543d20SAndroid Build Coastguard Worker break;
1761*2d543d20SAndroid Build Coastguard Worker case CIL_PERMISSIONX:
1762*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_permissionx(node->data, node);
1763*2d543d20SAndroid Build Coastguard Worker break;
1764*2d543d20SAndroid Build Coastguard Worker case CIL_RANGETRANSITION:
1765*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
1766*2d543d20SAndroid Build Coastguard Worker break;
1767*2d543d20SAndroid Build Coastguard Worker default:
1768*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
1769*2d543d20SAndroid Build Coastguard Worker break;
1770*2d543d20SAndroid Build Coastguard Worker }
1771*2d543d20SAndroid Build Coastguard Worker break;
1772*2d543d20SAndroid Build Coastguard Worker }
1773*2d543d20SAndroid Build Coastguard Worker default:
1774*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_ERR;
1775*2d543d20SAndroid Build Coastguard Worker }
1776*2d543d20SAndroid Build Coastguard Worker
1777*2d543d20SAndroid Build Coastguard Worker exit:
1778*2d543d20SAndroid Build Coastguard Worker return rc;
1779*2d543d20SAndroid Build Coastguard Worker }
1780*2d543d20SAndroid Build Coastguard Worker
__add_perm_to_list(hashtab_key_t k,hashtab_datum_t d,void * args)1781*2d543d20SAndroid Build Coastguard Worker static int __add_perm_to_list(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
1782*2d543d20SAndroid Build Coastguard Worker {
1783*2d543d20SAndroid Build Coastguard Worker struct cil_list *perm_list = (struct cil_list *)args;
1784*2d543d20SAndroid Build Coastguard Worker
1785*2d543d20SAndroid Build Coastguard Worker cil_list_append(perm_list, CIL_DATUM, d);
1786*2d543d20SAndroid Build Coastguard Worker
1787*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1788*2d543d20SAndroid Build Coastguard Worker }
1789*2d543d20SAndroid Build Coastguard Worker
1790*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_classperms(struct cil_list *classperms, struct cil_symtab_datum *orig, struct cil_symtab_datum *cur, unsigned steps, unsigned limit);
1791*2d543d20SAndroid Build Coastguard Worker
__cil_verify_map_perm(struct cil_class * class,struct cil_perm * perm,struct cil_symtab_datum * orig,unsigned steps,unsigned limit)1792*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_map_perm(struct cil_class *class, struct cil_perm *perm, struct cil_symtab_datum *orig, unsigned steps, unsigned limit)
1793*2d543d20SAndroid Build Coastguard Worker {
1794*2d543d20SAndroid Build Coastguard Worker int rc;
1795*2d543d20SAndroid Build Coastguard Worker
1796*2d543d20SAndroid Build Coastguard Worker if (!perm->classperms) {
1797*2d543d20SAndroid Build Coastguard Worker cil_tree_log(NODE(class), CIL_ERR, "No class permissions for map class %s, permission %s", DATUM(class)->name, DATUM(perm)->name);
1798*2d543d20SAndroid Build Coastguard Worker goto exit;
1799*2d543d20SAndroid Build Coastguard Worker }
1800*2d543d20SAndroid Build Coastguard Worker
1801*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_classperms(perm->classperms, orig, &perm->datum, steps, limit);
1802*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1803*2d543d20SAndroid Build Coastguard Worker cil_tree_log(NODE(class), CIL_ERR, "There was an error verifying class permissions for map class %s, permission %s", DATUM(class)->name, DATUM(perm)->name);
1804*2d543d20SAndroid Build Coastguard Worker goto exit;
1805*2d543d20SAndroid Build Coastguard Worker }
1806*2d543d20SAndroid Build Coastguard Worker
1807*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1808*2d543d20SAndroid Build Coastguard Worker
1809*2d543d20SAndroid Build Coastguard Worker exit:
1810*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
1811*2d543d20SAndroid Build Coastguard Worker }
1812*2d543d20SAndroid Build Coastguard Worker
1813*2d543d20SAndroid Build Coastguard Worker
__cil_verify_perms(struct cil_class * class,struct cil_list * perms,struct cil_symtab_datum * orig,unsigned steps,unsigned limit)1814*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_perms(struct cil_class *class, struct cil_list *perms, struct cil_symtab_datum *orig, unsigned steps, unsigned limit)
1815*2d543d20SAndroid Build Coastguard Worker {
1816*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_ERR;
1817*2d543d20SAndroid Build Coastguard Worker int count = 0;
1818*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *i = NULL;
1819*2d543d20SAndroid Build Coastguard Worker
1820*2d543d20SAndroid Build Coastguard Worker if (!perms) {
1821*2d543d20SAndroid Build Coastguard Worker cil_tree_log(NODE(class), CIL_ERR, "No permissions for class %s in class permissions", DATUM(class)->name);
1822*2d543d20SAndroid Build Coastguard Worker goto exit;
1823*2d543d20SAndroid Build Coastguard Worker }
1824*2d543d20SAndroid Build Coastguard Worker
1825*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(i, perms) {
1826*2d543d20SAndroid Build Coastguard Worker count++;
1827*2d543d20SAndroid Build Coastguard Worker if (i->flavor == CIL_LIST) {
1828*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_perms(class, i->data, orig, steps, limit);
1829*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1830*2d543d20SAndroid Build Coastguard Worker goto exit;
1831*2d543d20SAndroid Build Coastguard Worker }
1832*2d543d20SAndroid Build Coastguard Worker } else if (i->flavor == CIL_DATUM) {
1833*2d543d20SAndroid Build Coastguard Worker struct cil_perm *perm = i->data;
1834*2d543d20SAndroid Build Coastguard Worker if (FLAVOR(perm) == CIL_MAP_PERM) {
1835*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_map_perm(class, perm, orig, steps, limit);
1836*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1837*2d543d20SAndroid Build Coastguard Worker goto exit;
1838*2d543d20SAndroid Build Coastguard Worker }
1839*2d543d20SAndroid Build Coastguard Worker }
1840*2d543d20SAndroid Build Coastguard Worker } else if (i->flavor == CIL_OP) {
1841*2d543d20SAndroid Build Coastguard Worker enum cil_flavor op = (enum cil_flavor)(uintptr_t)i->data;
1842*2d543d20SAndroid Build Coastguard Worker if (op == CIL_ALL) {
1843*2d543d20SAndroid Build Coastguard Worker struct cil_list *perm_list;
1844*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *j = NULL;
1845*2d543d20SAndroid Build Coastguard Worker int count2 = 0;
1846*2d543d20SAndroid Build Coastguard Worker cil_list_init(&perm_list, CIL_MAP_PERM);
1847*2d543d20SAndroid Build Coastguard Worker cil_symtab_map(&class->perms, __add_perm_to_list, perm_list);
1848*2d543d20SAndroid Build Coastguard Worker if (class->common != NULL) {
1849*2d543d20SAndroid Build Coastguard Worker cil_symtab_map(&class->common->perms, __add_perm_to_list, perm_list);
1850*2d543d20SAndroid Build Coastguard Worker }
1851*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(j, perm_list) {
1852*2d543d20SAndroid Build Coastguard Worker count2++;
1853*2d543d20SAndroid Build Coastguard Worker struct cil_perm *perm = j->data;
1854*2d543d20SAndroid Build Coastguard Worker if (FLAVOR(perm) == CIL_MAP_PERM) {
1855*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_map_perm(class, perm, orig, steps, limit);
1856*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1857*2d543d20SAndroid Build Coastguard Worker cil_list_destroy(&perm_list, CIL_FALSE);
1858*2d543d20SAndroid Build Coastguard Worker goto exit;
1859*2d543d20SAndroid Build Coastguard Worker }
1860*2d543d20SAndroid Build Coastguard Worker }
1861*2d543d20SAndroid Build Coastguard Worker }
1862*2d543d20SAndroid Build Coastguard Worker cil_list_destroy(&perm_list, CIL_FALSE);
1863*2d543d20SAndroid Build Coastguard Worker if (count2 == 0) {
1864*2d543d20SAndroid Build Coastguard Worker cil_tree_log(NODE(class), CIL_ERR, "Operator \"all\" used for %s which has no permissions associated with it", DATUM(class)->name);
1865*2d543d20SAndroid Build Coastguard Worker goto exit;
1866*2d543d20SAndroid Build Coastguard Worker }
1867*2d543d20SAndroid Build Coastguard Worker }
1868*2d543d20SAndroid Build Coastguard Worker } else {
1869*2d543d20SAndroid Build Coastguard Worker cil_tree_log(NODE(class), CIL_ERR, "Permission list for %s has an unexpected flavor: %d", DATUM(class)->name, i->flavor);
1870*2d543d20SAndroid Build Coastguard Worker goto exit;
1871*2d543d20SAndroid Build Coastguard Worker }
1872*2d543d20SAndroid Build Coastguard Worker }
1873*2d543d20SAndroid Build Coastguard Worker
1874*2d543d20SAndroid Build Coastguard Worker if (count == 0) {
1875*2d543d20SAndroid Build Coastguard Worker cil_tree_log(NODE(class), CIL_ERR, "Empty permissions list for class %s in class permissions", DATUM(class)->name);
1876*2d543d20SAndroid Build Coastguard Worker goto exit;
1877*2d543d20SAndroid Build Coastguard Worker }
1878*2d543d20SAndroid Build Coastguard Worker
1879*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1880*2d543d20SAndroid Build Coastguard Worker
1881*2d543d20SAndroid Build Coastguard Worker exit:
1882*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
1883*2d543d20SAndroid Build Coastguard Worker }
1884*2d543d20SAndroid Build Coastguard Worker
__cil_verify_classperms(struct cil_list * classperms,struct cil_symtab_datum * orig,struct cil_symtab_datum * cur,unsigned steps,unsigned limit)1885*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_classperms(struct cil_list *classperms, struct cil_symtab_datum *orig, struct cil_symtab_datum *cur, unsigned steps, unsigned limit)
1886*2d543d20SAndroid Build Coastguard Worker {
1887*2d543d20SAndroid Build Coastguard Worker int rc;
1888*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *i;
1889*2d543d20SAndroid Build Coastguard Worker
1890*2d543d20SAndroid Build Coastguard Worker if (classperms == NULL) {
1891*2d543d20SAndroid Build Coastguard Worker goto exit;
1892*2d543d20SAndroid Build Coastguard Worker }
1893*2d543d20SAndroid Build Coastguard Worker
1894*2d543d20SAndroid Build Coastguard Worker if (steps > 0 && orig == cur) {
1895*2d543d20SAndroid Build Coastguard Worker cil_tree_log(NODE(cur), CIL_ERR, "Found circular class permissions involving %s", cur->name);
1896*2d543d20SAndroid Build Coastguard Worker goto exit;
1897*2d543d20SAndroid Build Coastguard Worker } else {
1898*2d543d20SAndroid Build Coastguard Worker steps++;
1899*2d543d20SAndroid Build Coastguard Worker if (steps > limit) {
1900*2d543d20SAndroid Build Coastguard Worker steps = 1;
1901*2d543d20SAndroid Build Coastguard Worker limit *= 2;
1902*2d543d20SAndroid Build Coastguard Worker orig = cur;
1903*2d543d20SAndroid Build Coastguard Worker }
1904*2d543d20SAndroid Build Coastguard Worker }
1905*2d543d20SAndroid Build Coastguard Worker
1906*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(i, classperms) {
1907*2d543d20SAndroid Build Coastguard Worker if (i->flavor == CIL_CLASSPERMS) {
1908*2d543d20SAndroid Build Coastguard Worker struct cil_classperms *cp = i->data;
1909*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_perms(cp->class, cp->perms, orig, steps, limit);
1910*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1911*2d543d20SAndroid Build Coastguard Worker goto exit;
1912*2d543d20SAndroid Build Coastguard Worker }
1913*2d543d20SAndroid Build Coastguard Worker } else { /* SET */
1914*2d543d20SAndroid Build Coastguard Worker struct cil_classperms_set *cp_set = i->data;
1915*2d543d20SAndroid Build Coastguard Worker struct cil_classpermission *cp = cp_set->set;
1916*2d543d20SAndroid Build Coastguard Worker if (!cp->classperms) {
1917*2d543d20SAndroid Build Coastguard Worker cil_tree_log(NODE(cur), CIL_ERR, "Classpermission %s does not have a classpermissionset", DATUM(cp)->name);
1918*2d543d20SAndroid Build Coastguard Worker }
1919*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_classperms(cp->classperms, orig, &cp->datum, steps, limit);
1920*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1921*2d543d20SAndroid Build Coastguard Worker goto exit;
1922*2d543d20SAndroid Build Coastguard Worker }
1923*2d543d20SAndroid Build Coastguard Worker }
1924*2d543d20SAndroid Build Coastguard Worker }
1925*2d543d20SAndroid Build Coastguard Worker
1926*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1927*2d543d20SAndroid Build Coastguard Worker
1928*2d543d20SAndroid Build Coastguard Worker exit:
1929*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
1930*2d543d20SAndroid Build Coastguard Worker }
1931*2d543d20SAndroid Build Coastguard Worker
__cil_verify_classpermission(struct cil_tree_node * node)1932*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_classpermission(struct cil_tree_node *node)
1933*2d543d20SAndroid Build Coastguard Worker {
1934*2d543d20SAndroid Build Coastguard Worker int rc;
1935*2d543d20SAndroid Build Coastguard Worker struct cil_classpermission *cp = node->data;
1936*2d543d20SAndroid Build Coastguard Worker
1937*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_classperms(cp->classperms, &cp->datum, &cp->datum, 0, 2);
1938*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1939*2d543d20SAndroid Build Coastguard Worker cil_tree_log(node, CIL_ERR, "Error verifying class permissions for classpermission %s", DATUM(cp)->name);
1940*2d543d20SAndroid Build Coastguard Worker }
1941*2d543d20SAndroid Build Coastguard Worker
1942*2d543d20SAndroid Build Coastguard Worker return rc;
1943*2d543d20SAndroid Build Coastguard Worker }
1944*2d543d20SAndroid Build Coastguard Worker
1945*2d543d20SAndroid Build Coastguard Worker struct cil_verify_map_args {
1946*2d543d20SAndroid Build Coastguard Worker struct cil_class *class;
1947*2d543d20SAndroid Build Coastguard Worker struct cil_tree_node *node;
1948*2d543d20SAndroid Build Coastguard Worker int rc;
1949*2d543d20SAndroid Build Coastguard Worker };
1950*2d543d20SAndroid Build Coastguard Worker
__verify_map_perm_classperms(hashtab_key_t k,hashtab_datum_t d,void * args)1951*2d543d20SAndroid Build Coastguard Worker static int __verify_map_perm_classperms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
1952*2d543d20SAndroid Build Coastguard Worker {
1953*2d543d20SAndroid Build Coastguard Worker struct cil_verify_map_args *map_args = args;
1954*2d543d20SAndroid Build Coastguard Worker struct cil_perm *cmp = (struct cil_perm *)d;
1955*2d543d20SAndroid Build Coastguard Worker int rc;
1956*2d543d20SAndroid Build Coastguard Worker
1957*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_classperms(cmp->classperms, &cmp->datum, &cmp->datum, 0, 2);
1958*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
1959*2d543d20SAndroid Build Coastguard Worker cil_tree_log(NODE(cmp), CIL_ERR, "Error verifying class permissions for map class %s, permission %s", DATUM(map_args->class)->name, DATUM(cmp)->name);
1960*2d543d20SAndroid Build Coastguard Worker map_args->rc = rc;
1961*2d543d20SAndroid Build Coastguard Worker }
1962*2d543d20SAndroid Build Coastguard Worker
1963*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1964*2d543d20SAndroid Build Coastguard Worker }
1965*2d543d20SAndroid Build Coastguard Worker
__cil_verify_map_class(struct cil_tree_node * node)1966*2d543d20SAndroid Build Coastguard Worker static int __cil_verify_map_class(struct cil_tree_node *node)
1967*2d543d20SAndroid Build Coastguard Worker {
1968*2d543d20SAndroid Build Coastguard Worker struct cil_class *mc = node->data;
1969*2d543d20SAndroid Build Coastguard Worker struct cil_verify_map_args map_args;
1970*2d543d20SAndroid Build Coastguard Worker
1971*2d543d20SAndroid Build Coastguard Worker map_args.class = mc;
1972*2d543d20SAndroid Build Coastguard Worker map_args.node = node;
1973*2d543d20SAndroid Build Coastguard Worker map_args.rc = SEPOL_OK;
1974*2d543d20SAndroid Build Coastguard Worker
1975*2d543d20SAndroid Build Coastguard Worker cil_symtab_map(&mc->perms, __verify_map_perm_classperms, &map_args);
1976*2d543d20SAndroid Build Coastguard Worker
1977*2d543d20SAndroid Build Coastguard Worker if (map_args.rc != SEPOL_OK) {
1978*2d543d20SAndroid Build Coastguard Worker return SEPOL_ERR;
1979*2d543d20SAndroid Build Coastguard Worker }
1980*2d543d20SAndroid Build Coastguard Worker
1981*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
1982*2d543d20SAndroid Build Coastguard Worker }
1983*2d543d20SAndroid Build Coastguard Worker
__cil_pre_verify_helper(struct cil_tree_node * node,uint32_t * finished,void * extra_args)1984*2d543d20SAndroid Build Coastguard Worker int __cil_pre_verify_helper(struct cil_tree_node *node, uint32_t *finished, __attribute__((unused)) void *extra_args)
1985*2d543d20SAndroid Build Coastguard Worker {
1986*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_OK;
1987*2d543d20SAndroid Build Coastguard Worker
1988*2d543d20SAndroid Build Coastguard Worker switch (node->flavor) {
1989*2d543d20SAndroid Build Coastguard Worker case CIL_MACRO: {
1990*2d543d20SAndroid Build Coastguard Worker *finished = CIL_TREE_SKIP_HEAD;
1991*2d543d20SAndroid Build Coastguard Worker break;
1992*2d543d20SAndroid Build Coastguard Worker }
1993*2d543d20SAndroid Build Coastguard Worker case CIL_BLOCK: {
1994*2d543d20SAndroid Build Coastguard Worker struct cil_block *blk = node->data;
1995*2d543d20SAndroid Build Coastguard Worker if (blk->is_abstract == CIL_TRUE) {
1996*2d543d20SAndroid Build Coastguard Worker *finished = CIL_TREE_SKIP_HEAD;
1997*2d543d20SAndroid Build Coastguard Worker }
1998*2d543d20SAndroid Build Coastguard Worker break;
1999*2d543d20SAndroid Build Coastguard Worker }
2000*2d543d20SAndroid Build Coastguard Worker case CIL_USER:
2001*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_user_pre_eval(node);
2002*2d543d20SAndroid Build Coastguard Worker break;
2003*2d543d20SAndroid Build Coastguard Worker case CIL_MAP_CLASS:
2004*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_map_class(node);
2005*2d543d20SAndroid Build Coastguard Worker break;
2006*2d543d20SAndroid Build Coastguard Worker case CIL_CLASSPERMISSION:
2007*2d543d20SAndroid Build Coastguard Worker rc = __cil_verify_classpermission(node);
2008*2d543d20SAndroid Build Coastguard Worker break;
2009*2d543d20SAndroid Build Coastguard Worker case CIL_USERATTRIBUTE:
2010*2d543d20SAndroid Build Coastguard Worker case CIL_ROLEATTRIBUTE:
2011*2d543d20SAndroid Build Coastguard Worker case CIL_TYPEATTRIBUTE:
2012*2d543d20SAndroid Build Coastguard Worker case CIL_CATSET: {
2013*2d543d20SAndroid Build Coastguard Worker struct cil_stack *stack;
2014*2d543d20SAndroid Build Coastguard Worker cil_stack_init(&stack);
2015*2d543d20SAndroid Build Coastguard Worker rc = cil_verify_no_self_reference(node->flavor, node->data, stack);
2016*2d543d20SAndroid Build Coastguard Worker cil_stack_destroy(&stack);
2017*2d543d20SAndroid Build Coastguard Worker break;
2018*2d543d20SAndroid Build Coastguard Worker }
2019*2d543d20SAndroid Build Coastguard Worker default:
2020*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
2021*2d543d20SAndroid Build Coastguard Worker break;
2022*2d543d20SAndroid Build Coastguard Worker }
2023*2d543d20SAndroid Build Coastguard Worker
2024*2d543d20SAndroid Build Coastguard Worker return rc;
2025*2d543d20SAndroid Build Coastguard Worker }
2026