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 <sepol/policydb/ebitmap.h>
31*2d543d20SAndroid Build Coastguard Worker
32*2d543d20SAndroid Build Coastguard Worker #include "cil_internal.h"
33*2d543d20SAndroid Build Coastguard Worker #include "cil_find.h"
34*2d543d20SAndroid Build Coastguard Worker #include "cil_flavor.h"
35*2d543d20SAndroid Build Coastguard Worker #include "cil_list.h"
36*2d543d20SAndroid Build Coastguard Worker #include "cil_log.h"
37*2d543d20SAndroid Build Coastguard Worker #include "cil_symtab.h"
38*2d543d20SAndroid Build Coastguard Worker
39*2d543d20SAndroid Build Coastguard Worker struct cil_args_find {
40*2d543d20SAndroid Build Coastguard Worker enum cil_flavor flavor;
41*2d543d20SAndroid Build Coastguard Worker void *target;
42*2d543d20SAndroid Build Coastguard Worker struct cil_list *matching;
43*2d543d20SAndroid Build Coastguard Worker int match_self;
44*2d543d20SAndroid Build Coastguard Worker };
45*2d543d20SAndroid Build Coastguard Worker
cil_type_match_any(struct cil_symtab_datum * d1,struct cil_symtab_datum * d2)46*2d543d20SAndroid Build Coastguard Worker static int cil_type_match_any(struct cil_symtab_datum *d1, struct cil_symtab_datum *d2)
47*2d543d20SAndroid Build Coastguard Worker {
48*2d543d20SAndroid Build Coastguard Worker enum cil_flavor f1 = FLAVOR(d1);
49*2d543d20SAndroid Build Coastguard Worker enum cil_flavor f2 = FLAVOR(d2);
50*2d543d20SAndroid Build Coastguard Worker
51*2d543d20SAndroid Build Coastguard Worker if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
52*2d543d20SAndroid Build Coastguard Worker struct cil_type *t1 = (struct cil_type *)d1;
53*2d543d20SAndroid Build Coastguard Worker struct cil_type *t2 = (struct cil_type *)d2;
54*2d543d20SAndroid Build Coastguard Worker if (t1->value == t2->value) {
55*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
56*2d543d20SAndroid Build Coastguard Worker }
57*2d543d20SAndroid Build Coastguard Worker } else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
58*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *a = (struct cil_typeattribute *)d1;
59*2d543d20SAndroid Build Coastguard Worker struct cil_type *t = (struct cil_type *)d2;
60*2d543d20SAndroid Build Coastguard Worker if (ebitmap_get_bit(a->types, t->value)) {
61*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
62*2d543d20SAndroid Build Coastguard Worker }
63*2d543d20SAndroid Build Coastguard Worker } else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
64*2d543d20SAndroid Build Coastguard Worker struct cil_type *t = (struct cil_type *)d1;
65*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *a = (struct cil_typeattribute *)d2;
66*2d543d20SAndroid Build Coastguard Worker if (ebitmap_get_bit(a->types, t->value)) {
67*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
68*2d543d20SAndroid Build Coastguard Worker }
69*2d543d20SAndroid Build Coastguard Worker } else {
70*2d543d20SAndroid Build Coastguard Worker /* Both are attributes */
71*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1;
72*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2;
73*2d543d20SAndroid Build Coastguard Worker if (d1 == d2) {
74*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
75*2d543d20SAndroid Build Coastguard Worker } else if (ebitmap_match_any(a1->types, a2->types)) {
76*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
77*2d543d20SAndroid Build Coastguard Worker }
78*2d543d20SAndroid Build Coastguard Worker }
79*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
80*2d543d20SAndroid Build Coastguard Worker }
81*2d543d20SAndroid Build Coastguard Worker
cil_type_matches(ebitmap_t * matches,struct cil_symtab_datum * d1,struct cil_symtab_datum * d2)82*2d543d20SAndroid Build Coastguard Worker static int cil_type_matches(ebitmap_t *matches, struct cil_symtab_datum *d1, struct cil_symtab_datum *d2)
83*2d543d20SAndroid Build Coastguard Worker {
84*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_OK;
85*2d543d20SAndroid Build Coastguard Worker enum cil_flavor f1 = FLAVOR(d1);
86*2d543d20SAndroid Build Coastguard Worker enum cil_flavor f2 = FLAVOR(d2);
87*2d543d20SAndroid Build Coastguard Worker
88*2d543d20SAndroid Build Coastguard Worker if (f1 == CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
89*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1;
90*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2;
91*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(matches, a1->types, a2->types);
92*2d543d20SAndroid Build Coastguard Worker } else {
93*2d543d20SAndroid Build Coastguard Worker ebitmap_init(matches);
94*2d543d20SAndroid Build Coastguard Worker if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
95*2d543d20SAndroid Build Coastguard Worker struct cil_type *t1 = (struct cil_type *)d1;
96*2d543d20SAndroid Build Coastguard Worker struct cil_type *t2 = (struct cil_type *)d2;
97*2d543d20SAndroid Build Coastguard Worker if (t1->value == t2->value) {
98*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_set_bit(matches, t1->value, 1);
99*2d543d20SAndroid Build Coastguard Worker }
100*2d543d20SAndroid Build Coastguard Worker } else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
101*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *a = (struct cil_typeattribute *)d1;
102*2d543d20SAndroid Build Coastguard Worker struct cil_type *t = (struct cil_type *)d2;
103*2d543d20SAndroid Build Coastguard Worker if (ebitmap_get_bit(a->types, t->value)) {
104*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_set_bit(matches, t->value, 1);
105*2d543d20SAndroid Build Coastguard Worker }
106*2d543d20SAndroid Build Coastguard Worker } else { // f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE
107*2d543d20SAndroid Build Coastguard Worker struct cil_type *t = (struct cil_type *)d1;
108*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *a = (struct cil_typeattribute *)d2;
109*2d543d20SAndroid Build Coastguard Worker if (ebitmap_get_bit(a->types, t->value)) {
110*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_set_bit(matches, t->value, 1);
111*2d543d20SAndroid Build Coastguard Worker }
112*2d543d20SAndroid Build Coastguard Worker }
113*2d543d20SAndroid Build Coastguard Worker if (rc != SEPOL_OK) {
114*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(matches);
115*2d543d20SAndroid Build Coastguard Worker }
116*2d543d20SAndroid Build Coastguard Worker }
117*2d543d20SAndroid Build Coastguard Worker
118*2d543d20SAndroid Build Coastguard Worker return rc;
119*2d543d20SAndroid Build Coastguard Worker }
120*2d543d20SAndroid Build Coastguard Worker
121*2d543d20SAndroid Build Coastguard Worker /* s1 is the src type that is matched with a self
122*2d543d20SAndroid Build Coastguard Worker * s2, and t2 are the source and type of the other rule
123*2d543d20SAndroid Build Coastguard Worker * Assumes there is a match between s1 and s2
124*2d543d20SAndroid Build Coastguard Worker */
cil_self_match_any(struct cil_symtab_datum * s1,struct cil_symtab_datum * s2,struct cil_symtab_datum * t2)125*2d543d20SAndroid Build Coastguard Worker static int cil_self_match_any(struct cil_symtab_datum *s1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2)
126*2d543d20SAndroid Build Coastguard Worker {
127*2d543d20SAndroid Build Coastguard Worker int rc;
128*2d543d20SAndroid Build Coastguard Worker
129*2d543d20SAndroid Build Coastguard Worker if (FLAVOR(s1) != CIL_TYPEATTRIBUTE) {
130*2d543d20SAndroid Build Coastguard Worker rc = cil_type_match_any(s1, t2);
131*2d543d20SAndroid Build Coastguard Worker } else {
132*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *a = (struct cil_typeattribute *)s1;
133*2d543d20SAndroid Build Coastguard Worker ebitmap_t map;
134*2d543d20SAndroid Build Coastguard Worker rc = cil_type_matches(&map, s2, t2);
135*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
136*2d543d20SAndroid Build Coastguard Worker return rc;
137*2d543d20SAndroid Build Coastguard Worker }
138*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&map)) {
139*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
140*2d543d20SAndroid Build Coastguard Worker }
141*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_match_any(&map, a->types);
142*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&map);
143*2d543d20SAndroid Build Coastguard Worker }
144*2d543d20SAndroid Build Coastguard Worker
145*2d543d20SAndroid Build Coastguard Worker return rc;
146*2d543d20SAndroid Build Coastguard Worker }
147*2d543d20SAndroid Build Coastguard Worker
148*2d543d20SAndroid Build Coastguard Worker /* s1 is the src type that is matched with a notself
149*2d543d20SAndroid Build Coastguard Worker * s2 and t2 are the source and type of the other rule
150*2d543d20SAndroid Build Coastguard Worker * Assumes there is a match between s1 and s2
151*2d543d20SAndroid Build Coastguard Worker */
cil_notself_match_any(struct cil_symtab_datum * s1,struct cil_symtab_datum * s2,struct cil_symtab_datum * t2)152*2d543d20SAndroid Build Coastguard Worker static int cil_notself_match_any(struct cil_symtab_datum *s1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2)
153*2d543d20SAndroid Build Coastguard Worker {
154*2d543d20SAndroid Build Coastguard Worker int rc;
155*2d543d20SAndroid Build Coastguard Worker ebitmap_node_t *snode, *tnode;
156*2d543d20SAndroid Build Coastguard Worker unsigned int s,t;
157*2d543d20SAndroid Build Coastguard Worker
158*2d543d20SAndroid Build Coastguard Worker if (FLAVOR(s1) != CIL_TYPEATTRIBUTE) {
159*2d543d20SAndroid Build Coastguard Worker struct cil_type *ts1 = (struct cil_type *)s1;
160*2d543d20SAndroid Build Coastguard Worker if (FLAVOR(t2) != CIL_TYPEATTRIBUTE) {
161*2d543d20SAndroid Build Coastguard Worker struct cil_type *tt2 = (struct cil_type *)t2;
162*2d543d20SAndroid Build Coastguard Worker if (ts1->value != tt2->value) {
163*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
164*2d543d20SAndroid Build Coastguard Worker }
165*2d543d20SAndroid Build Coastguard Worker } else {
166*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *at2 = (struct cil_typeattribute *)t2;
167*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(at2->types, tnode, t) {
168*2d543d20SAndroid Build Coastguard Worker if (t != (unsigned int)ts1->value) {
169*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
170*2d543d20SAndroid Build Coastguard Worker }
171*2d543d20SAndroid Build Coastguard Worker }
172*2d543d20SAndroid Build Coastguard Worker }
173*2d543d20SAndroid Build Coastguard Worker } else {
174*2d543d20SAndroid Build Coastguard Worker ebitmap_t smap;
175*2d543d20SAndroid Build Coastguard Worker rc = cil_type_matches(&smap, s1, s2);
176*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
177*2d543d20SAndroid Build Coastguard Worker return rc;
178*2d543d20SAndroid Build Coastguard Worker }
179*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&smap)) {
180*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
181*2d543d20SAndroid Build Coastguard Worker }
182*2d543d20SAndroid Build Coastguard Worker if (FLAVOR(t2) != CIL_TYPEATTRIBUTE) {
183*2d543d20SAndroid Build Coastguard Worker struct cil_type *tt2 = (struct cil_type *)t2;
184*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&smap, snode, s) {
185*2d543d20SAndroid Build Coastguard Worker if (s != (unsigned int)tt2->value) {
186*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&smap);
187*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
188*2d543d20SAndroid Build Coastguard Worker }
189*2d543d20SAndroid Build Coastguard Worker }
190*2d543d20SAndroid Build Coastguard Worker } else {
191*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *at2 = (struct cil_typeattribute *)t2;
192*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&smap, snode, s) {
193*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(at2->types, tnode, t) {
194*2d543d20SAndroid Build Coastguard Worker if (s != t) {
195*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&smap);
196*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
197*2d543d20SAndroid Build Coastguard Worker }
198*2d543d20SAndroid Build Coastguard Worker }
199*2d543d20SAndroid Build Coastguard Worker }
200*2d543d20SAndroid Build Coastguard Worker }
201*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&smap);
202*2d543d20SAndroid Build Coastguard Worker }
203*2d543d20SAndroid Build Coastguard Worker
204*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
205*2d543d20SAndroid Build Coastguard Worker }
206*2d543d20SAndroid Build Coastguard Worker
207*2d543d20SAndroid Build Coastguard Worker /* s1 is the src type that is matched with an other
208*2d543d20SAndroid Build Coastguard Worker * s2, and t2 are the source and type of the other rule
209*2d543d20SAndroid Build Coastguard Worker * Assumes there is a match between s1 and s2
210*2d543d20SAndroid Build Coastguard Worker */
cil_other_match_any(struct cil_symtab_datum * s1,struct cil_symtab_datum * s2,struct cil_symtab_datum * t2)211*2d543d20SAndroid Build Coastguard Worker static int cil_other_match_any(struct cil_symtab_datum *s1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2)
212*2d543d20SAndroid Build Coastguard Worker {
213*2d543d20SAndroid Build Coastguard Worker int rc;
214*2d543d20SAndroid Build Coastguard Worker ebitmap_t smap, tmap;
215*2d543d20SAndroid Build Coastguard Worker ebitmap_node_t *snode, *tnode;
216*2d543d20SAndroid Build Coastguard Worker unsigned int s,t;
217*2d543d20SAndroid Build Coastguard Worker
218*2d543d20SAndroid Build Coastguard Worker if (FLAVOR(s1) != CIL_TYPEATTRIBUTE) {
219*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
220*2d543d20SAndroid Build Coastguard Worker }
221*2d543d20SAndroid Build Coastguard Worker
222*2d543d20SAndroid Build Coastguard Worker rc = cil_type_matches(&smap, s1, s2);
223*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
224*2d543d20SAndroid Build Coastguard Worker return rc;
225*2d543d20SAndroid Build Coastguard Worker }
226*2d543d20SAndroid Build Coastguard Worker
227*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&smap)) {
228*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
229*2d543d20SAndroid Build Coastguard Worker }
230*2d543d20SAndroid Build Coastguard Worker
231*2d543d20SAndroid Build Coastguard Worker rc = cil_type_matches(&tmap, s1, t2);
232*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
233*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&smap);
234*2d543d20SAndroid Build Coastguard Worker return rc;
235*2d543d20SAndroid Build Coastguard Worker }
236*2d543d20SAndroid Build Coastguard Worker
237*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&tmap)) {
238*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&smap);
239*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
240*2d543d20SAndroid Build Coastguard Worker }
241*2d543d20SAndroid Build Coastguard Worker
242*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&smap, snode, s) {
243*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&tmap, tnode, t) {
244*2d543d20SAndroid Build Coastguard Worker if (s != t) {
245*2d543d20SAndroid Build Coastguard Worker rc = CIL_TRUE;
246*2d543d20SAndroid Build Coastguard Worker goto exit;
247*2d543d20SAndroid Build Coastguard Worker }
248*2d543d20SAndroid Build Coastguard Worker }
249*2d543d20SAndroid Build Coastguard Worker }
250*2d543d20SAndroid Build Coastguard Worker
251*2d543d20SAndroid Build Coastguard Worker rc = CIL_FALSE;
252*2d543d20SAndroid Build Coastguard Worker
253*2d543d20SAndroid Build Coastguard Worker exit:
254*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&smap);
255*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&tmap);
256*2d543d20SAndroid Build Coastguard Worker return rc;
257*2d543d20SAndroid Build Coastguard Worker }
258*2d543d20SAndroid Build Coastguard Worker
259*2d543d20SAndroid Build Coastguard Worker /* s2 is the src type that is matched with an other
260*2d543d20SAndroid Build Coastguard Worker * Assumes there is a match between s1 and s2
261*2d543d20SAndroid Build Coastguard Worker * s1 is not needed, since it is known that there is a match
262*2d543d20SAndroid Build Coastguard Worker */
cil_notself_other_match_any(struct cil_symtab_datum * s2)263*2d543d20SAndroid Build Coastguard Worker static int cil_notself_other_match_any(struct cil_symtab_datum *s2)
264*2d543d20SAndroid Build Coastguard Worker {
265*2d543d20SAndroid Build Coastguard Worker if (FLAVOR(s2) == CIL_TYPEATTRIBUTE) {
266*2d543d20SAndroid Build Coastguard Worker struct cil_typeattribute *as2 = (struct cil_typeattribute *)s2;
267*2d543d20SAndroid Build Coastguard Worker if (ebitmap_cardinality(as2->types) > 1) {
268*2d543d20SAndroid Build Coastguard Worker return CIL_TRUE;
269*2d543d20SAndroid Build Coastguard Worker }
270*2d543d20SAndroid Build Coastguard Worker }
271*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
272*2d543d20SAndroid Build Coastguard Worker }
273*2d543d20SAndroid Build Coastguard Worker
cil_classperms_match_any(struct cil_classperms * cp1,struct cil_classperms * cp2)274*2d543d20SAndroid Build Coastguard Worker static int cil_classperms_match_any(struct cil_classperms *cp1, struct cil_classperms *cp2)
275*2d543d20SAndroid Build Coastguard Worker {
276*2d543d20SAndroid Build Coastguard Worker struct cil_class *c1 = cp1->class;
277*2d543d20SAndroid Build Coastguard Worker struct cil_class *c2 = cp2->class;
278*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *i1, *i2;
279*2d543d20SAndroid Build Coastguard Worker
280*2d543d20SAndroid Build Coastguard Worker if (&c1->datum != &c2->datum) return CIL_FALSE;
281*2d543d20SAndroid Build Coastguard Worker
282*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(i1, cp1->perms) {
283*2d543d20SAndroid Build Coastguard Worker struct cil_perm *p1 = i1->data;
284*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(i2, cp2->perms) {
285*2d543d20SAndroid Build Coastguard Worker struct cil_perm *p2 = i2->data;
286*2d543d20SAndroid Build Coastguard Worker if (&p1->datum == &p2->datum) return CIL_TRUE;
287*2d543d20SAndroid Build Coastguard Worker }
288*2d543d20SAndroid Build Coastguard Worker }
289*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
290*2d543d20SAndroid Build Coastguard Worker }
291*2d543d20SAndroid Build Coastguard Worker
__cil_classperms_list_match_any(struct cil_classperms * cp1,struct cil_list * cpl2)292*2d543d20SAndroid Build Coastguard Worker static int __cil_classperms_list_match_any(struct cil_classperms *cp1, struct cil_list *cpl2)
293*2d543d20SAndroid Build Coastguard Worker {
294*2d543d20SAndroid Build Coastguard Worker int rc;
295*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *curr;
296*2d543d20SAndroid Build Coastguard Worker
297*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(curr, cpl2) {
298*2d543d20SAndroid Build Coastguard Worker if (curr->flavor == CIL_CLASSPERMS) {
299*2d543d20SAndroid Build Coastguard Worker struct cil_classperms *cp = curr->data;
300*2d543d20SAndroid Build Coastguard Worker if (FLAVOR(cp->class) == CIL_CLASS) {
301*2d543d20SAndroid Build Coastguard Worker rc = cil_classperms_match_any(cp1, cp);
302*2d543d20SAndroid Build Coastguard Worker if (rc == CIL_TRUE) return CIL_TRUE;
303*2d543d20SAndroid Build Coastguard Worker } else { /* MAP */
304*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *i = NULL;
305*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(i, cp->perms) {
306*2d543d20SAndroid Build Coastguard Worker struct cil_perm *cmp = i->data;
307*2d543d20SAndroid Build Coastguard Worker rc = __cil_classperms_list_match_any(cp1, cmp->classperms);
308*2d543d20SAndroid Build Coastguard Worker if (rc == CIL_TRUE) return CIL_TRUE;
309*2d543d20SAndroid Build Coastguard Worker }
310*2d543d20SAndroid Build Coastguard Worker }
311*2d543d20SAndroid Build Coastguard Worker } else { /* SET */
312*2d543d20SAndroid Build Coastguard Worker struct cil_classperms_set *cp_set = curr->data;
313*2d543d20SAndroid Build Coastguard Worker struct cil_classpermission *cp = cp_set->set;
314*2d543d20SAndroid Build Coastguard Worker rc = __cil_classperms_list_match_any(cp1, cp->classperms);
315*2d543d20SAndroid Build Coastguard Worker if (rc == CIL_TRUE) return CIL_TRUE;
316*2d543d20SAndroid Build Coastguard Worker }
317*2d543d20SAndroid Build Coastguard Worker }
318*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
319*2d543d20SAndroid Build Coastguard Worker }
320*2d543d20SAndroid Build Coastguard Worker
cil_classperms_list_match_any(struct cil_list * cpl1,struct cil_list * cpl2)321*2d543d20SAndroid Build Coastguard Worker static int cil_classperms_list_match_any(struct cil_list *cpl1, struct cil_list *cpl2)
322*2d543d20SAndroid Build Coastguard Worker {
323*2d543d20SAndroid Build Coastguard Worker int rc;
324*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *curr;
325*2d543d20SAndroid Build Coastguard Worker
326*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(curr, cpl1) {
327*2d543d20SAndroid Build Coastguard Worker if (curr->flavor == CIL_CLASSPERMS) {
328*2d543d20SAndroid Build Coastguard Worker struct cil_classperms *cp = curr->data;
329*2d543d20SAndroid Build Coastguard Worker if (FLAVOR(cp->class) == CIL_CLASS) {
330*2d543d20SAndroid Build Coastguard Worker rc = __cil_classperms_list_match_any(cp, cpl2);
331*2d543d20SAndroid Build Coastguard Worker if (rc == CIL_TRUE) return CIL_TRUE;
332*2d543d20SAndroid Build Coastguard Worker } else { /* MAP */
333*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *i = NULL;
334*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(i, cp->perms) {
335*2d543d20SAndroid Build Coastguard Worker struct cil_perm *cmp = i->data;
336*2d543d20SAndroid Build Coastguard Worker rc = cil_classperms_list_match_any(cmp->classperms, cpl2);
337*2d543d20SAndroid Build Coastguard Worker if (rc == CIL_TRUE) return CIL_TRUE;
338*2d543d20SAndroid Build Coastguard Worker }
339*2d543d20SAndroid Build Coastguard Worker }
340*2d543d20SAndroid Build Coastguard Worker } else { /* SET */
341*2d543d20SAndroid Build Coastguard Worker struct cil_classperms_set *cp_set = curr->data;
342*2d543d20SAndroid Build Coastguard Worker struct cil_classpermission *cp = cp_set->set;
343*2d543d20SAndroid Build Coastguard Worker rc = cil_classperms_list_match_any(cp->classperms, cpl2);
344*2d543d20SAndroid Build Coastguard Worker if (rc == CIL_TRUE) return CIL_TRUE;
345*2d543d20SAndroid Build Coastguard Worker }
346*2d543d20SAndroid Build Coastguard Worker }
347*2d543d20SAndroid Build Coastguard Worker return CIL_FALSE;
348*2d543d20SAndroid Build Coastguard Worker }
349*2d543d20SAndroid Build Coastguard Worker
__add_classes_from_classperms_list(struct cil_list * classperms,struct cil_list * class_list)350*2d543d20SAndroid Build Coastguard Worker static void __add_classes_from_classperms_list(struct cil_list *classperms, struct cil_list *class_list)
351*2d543d20SAndroid Build Coastguard Worker {
352*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *curr;
353*2d543d20SAndroid Build Coastguard Worker
354*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(curr, classperms) {
355*2d543d20SAndroid Build Coastguard Worker if (curr->flavor == CIL_CLASSPERMS) {
356*2d543d20SAndroid Build Coastguard Worker struct cil_classperms *cp = curr->data;
357*2d543d20SAndroid Build Coastguard Worker if (FLAVOR(cp->class) == CIL_CLASS) {
358*2d543d20SAndroid Build Coastguard Worker cil_list_append(class_list, CIL_CLASS, cp->class);
359*2d543d20SAndroid Build Coastguard Worker } else { /* MAP */
360*2d543d20SAndroid Build Coastguard Worker struct cil_list_item *i = NULL;
361*2d543d20SAndroid Build Coastguard Worker cil_list_for_each(i, cp->perms) {
362*2d543d20SAndroid Build Coastguard Worker struct cil_perm *cmp = i->data;
363*2d543d20SAndroid Build Coastguard Worker __add_classes_from_classperms_list(cmp->classperms, class_list);
364*2d543d20SAndroid Build Coastguard Worker }
365*2d543d20SAndroid Build Coastguard Worker }
366*2d543d20SAndroid Build Coastguard Worker } else { /* SET */
367*2d543d20SAndroid Build Coastguard Worker struct cil_classperms_set *cp_set = curr->data;
368*2d543d20SAndroid Build Coastguard Worker struct cil_classpermission *cp = cp_set->set;
369*2d543d20SAndroid Build Coastguard Worker __add_classes_from_classperms_list(cp->classperms, class_list);
370*2d543d20SAndroid Build Coastguard Worker }
371*2d543d20SAndroid Build Coastguard Worker }
372*2d543d20SAndroid Build Coastguard Worker }
373*2d543d20SAndroid Build Coastguard Worker
__add_classes_from_map_perms(hashtab_key_t k,hashtab_datum_t d,void * args)374*2d543d20SAndroid Build Coastguard Worker static int __add_classes_from_map_perms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
375*2d543d20SAndroid Build Coastguard Worker {
376*2d543d20SAndroid Build Coastguard Worker struct cil_list *class_list = args;
377*2d543d20SAndroid Build Coastguard Worker struct cil_perm *cmp = (struct cil_perm *)d;
378*2d543d20SAndroid Build Coastguard Worker
379*2d543d20SAndroid Build Coastguard Worker __add_classes_from_classperms_list(cmp->classperms, class_list);
380*2d543d20SAndroid Build Coastguard Worker
381*2d543d20SAndroid Build Coastguard Worker return SEPOL_OK;
382*2d543d20SAndroid Build Coastguard Worker }
383*2d543d20SAndroid Build Coastguard Worker
cil_expand_class(struct cil_class * class)384*2d543d20SAndroid Build Coastguard Worker struct cil_list *cil_expand_class(struct cil_class *class)
385*2d543d20SAndroid Build Coastguard Worker {
386*2d543d20SAndroid Build Coastguard Worker struct cil_list *class_list;
387*2d543d20SAndroid Build Coastguard Worker
388*2d543d20SAndroid Build Coastguard Worker cil_list_init(&class_list, CIL_CLASS);
389*2d543d20SAndroid Build Coastguard Worker
390*2d543d20SAndroid Build Coastguard Worker if (FLAVOR(class) == CIL_CLASS) {
391*2d543d20SAndroid Build Coastguard Worker cil_list_append(class_list, CIL_CLASS, class);
392*2d543d20SAndroid Build Coastguard Worker } else { /* MAP */
393*2d543d20SAndroid Build Coastguard Worker cil_symtab_map(&class->perms, __add_classes_from_map_perms, class_list);
394*2d543d20SAndroid Build Coastguard Worker }
395*2d543d20SAndroid Build Coastguard Worker
396*2d543d20SAndroid Build Coastguard Worker return class_list;
397*2d543d20SAndroid Build Coastguard Worker }
398*2d543d20SAndroid Build Coastguard Worker
cil_permissionx_match_any(struct cil_permissionx * px1,struct cil_permissionx * px2)399*2d543d20SAndroid Build Coastguard Worker static int cil_permissionx_match_any(struct cil_permissionx *px1, struct cil_permissionx *px2)
400*2d543d20SAndroid Build Coastguard Worker {
401*2d543d20SAndroid Build Coastguard Worker int rc = CIL_FALSE;
402*2d543d20SAndroid Build Coastguard Worker struct cil_list *cl1 = NULL;
403*2d543d20SAndroid Build Coastguard Worker struct cil_list *cl2 = NULL;
404*2d543d20SAndroid Build Coastguard Worker
405*2d543d20SAndroid Build Coastguard Worker if (px1->kind != px2->kind) goto exit;
406*2d543d20SAndroid Build Coastguard Worker
407*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_match_any(px1->perms, px2->perms)) goto exit;
408*2d543d20SAndroid Build Coastguard Worker
409*2d543d20SAndroid Build Coastguard Worker cl1 = cil_expand_class(px1->obj);
410*2d543d20SAndroid Build Coastguard Worker cl2 = cil_expand_class(px2->obj);
411*2d543d20SAndroid Build Coastguard Worker
412*2d543d20SAndroid Build Coastguard Worker if (!cil_list_match_any(cl1, cl2)) goto exit;
413*2d543d20SAndroid Build Coastguard Worker
414*2d543d20SAndroid Build Coastguard Worker rc = CIL_TRUE;
415*2d543d20SAndroid Build Coastguard Worker
416*2d543d20SAndroid Build Coastguard Worker exit:
417*2d543d20SAndroid Build Coastguard Worker cil_list_destroy(&cl1, CIL_FALSE);
418*2d543d20SAndroid Build Coastguard Worker cil_list_destroy(&cl2, CIL_FALSE);
419*2d543d20SAndroid Build Coastguard Worker
420*2d543d20SAndroid Build Coastguard Worker return rc;
421*2d543d20SAndroid Build Coastguard Worker }
422*2d543d20SAndroid Build Coastguard Worker
cil_find_matching_avrule(struct cil_tree_node * node,struct cil_avrule * avrule,struct cil_avrule * target,struct cil_list * matching,int match_self)423*2d543d20SAndroid Build Coastguard Worker static int cil_find_matching_avrule(struct cil_tree_node *node, struct cil_avrule *avrule, struct cil_avrule *target, struct cil_list *matching, int match_self)
424*2d543d20SAndroid Build Coastguard Worker {
425*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_OK;
426*2d543d20SAndroid Build Coastguard Worker struct cil_symtab_datum *s1 = avrule->src;
427*2d543d20SAndroid Build Coastguard Worker struct cil_symtab_datum *t1 = avrule->tgt;
428*2d543d20SAndroid Build Coastguard Worker struct cil_symtab_datum *s2 = target->src;
429*2d543d20SAndroid Build Coastguard Worker struct cil_symtab_datum *t2 = target->tgt;
430*2d543d20SAndroid Build Coastguard Worker
431*2d543d20SAndroid Build Coastguard Worker if (match_self != CIL_TRUE && avrule == target) goto exit;
432*2d543d20SAndroid Build Coastguard Worker
433*2d543d20SAndroid Build Coastguard Worker if (avrule->rule_kind != target->rule_kind) goto exit;
434*2d543d20SAndroid Build Coastguard Worker
435*2d543d20SAndroid Build Coastguard Worker if (avrule->is_extended != target->is_extended) goto exit;
436*2d543d20SAndroid Build Coastguard Worker
437*2d543d20SAndroid Build Coastguard Worker if (!cil_type_match_any(s1, s2)) goto exit;
438*2d543d20SAndroid Build Coastguard Worker
439*2d543d20SAndroid Build Coastguard Worker if (t1->fqn == CIL_KEY_SELF) {
440*2d543d20SAndroid Build Coastguard Worker if (t2->fqn == CIL_KEY_SELF) {
441*2d543d20SAndroid Build Coastguard Worker /* The earlier check whether s1 and s2 matches is all that is needed */
442*2d543d20SAndroid Build Coastguard Worker rc = CIL_TRUE;
443*2d543d20SAndroid Build Coastguard Worker } else if (t2->fqn == CIL_KEY_NOTSELF || t2->fqn == CIL_KEY_OTHER) {
444*2d543d20SAndroid Build Coastguard Worker rc = CIL_FALSE;
445*2d543d20SAndroid Build Coastguard Worker } else {
446*2d543d20SAndroid Build Coastguard Worker rc = cil_self_match_any(s1, s2, t2);
447*2d543d20SAndroid Build Coastguard Worker }
448*2d543d20SAndroid Build Coastguard Worker } else if (t1->fqn == CIL_KEY_NOTSELF) {
449*2d543d20SAndroid Build Coastguard Worker if (t2->fqn == CIL_KEY_SELF) {
450*2d543d20SAndroid Build Coastguard Worker rc = CIL_FALSE;
451*2d543d20SAndroid Build Coastguard Worker } else if (t2->fqn == CIL_KEY_NOTSELF) {
452*2d543d20SAndroid Build Coastguard Worker /* The earlier check whether s1 and s2 matches is all that is needed */
453*2d543d20SAndroid Build Coastguard Worker rc = CIL_TRUE;
454*2d543d20SAndroid Build Coastguard Worker } else if (t2->fqn == CIL_KEY_OTHER) {
455*2d543d20SAndroid Build Coastguard Worker rc = cil_notself_other_match_any(s2);
456*2d543d20SAndroid Build Coastguard Worker } else {
457*2d543d20SAndroid Build Coastguard Worker rc = cil_notself_match_any(s1, s2, t2);
458*2d543d20SAndroid Build Coastguard Worker }
459*2d543d20SAndroid Build Coastguard Worker } else if (t1->fqn == CIL_KEY_OTHER) {
460*2d543d20SAndroid Build Coastguard Worker if (t2->fqn == CIL_KEY_SELF) {
461*2d543d20SAndroid Build Coastguard Worker rc = CIL_FALSE;
462*2d543d20SAndroid Build Coastguard Worker } else if (t2->fqn == CIL_KEY_NOTSELF) {
463*2d543d20SAndroid Build Coastguard Worker rc = cil_notself_other_match_any(s1);
464*2d543d20SAndroid Build Coastguard Worker } else if (t2->fqn == CIL_KEY_OTHER) {
465*2d543d20SAndroid Build Coastguard Worker /* The earlier check whether s1 and s2 matches is all that is needed */
466*2d543d20SAndroid Build Coastguard Worker rc = CIL_TRUE;
467*2d543d20SAndroid Build Coastguard Worker } else {
468*2d543d20SAndroid Build Coastguard Worker rc = cil_other_match_any(s1, s2, t2);
469*2d543d20SAndroid Build Coastguard Worker }
470*2d543d20SAndroid Build Coastguard Worker } else {
471*2d543d20SAndroid Build Coastguard Worker if (t2->fqn == CIL_KEY_SELF) {
472*2d543d20SAndroid Build Coastguard Worker rc = cil_self_match_any(s2, s1, t1);
473*2d543d20SAndroid Build Coastguard Worker } else if (t2->fqn == CIL_KEY_NOTSELF) {
474*2d543d20SAndroid Build Coastguard Worker rc = cil_notself_match_any(s2, s1, t1);
475*2d543d20SAndroid Build Coastguard Worker } else if (t2->fqn == CIL_KEY_OTHER) {
476*2d543d20SAndroid Build Coastguard Worker rc = cil_other_match_any(s2, s1, t1);
477*2d543d20SAndroid Build Coastguard Worker } else {
478*2d543d20SAndroid Build Coastguard Worker rc = cil_type_match_any(t1, t2);
479*2d543d20SAndroid Build Coastguard Worker }
480*2d543d20SAndroid Build Coastguard Worker }
481*2d543d20SAndroid Build Coastguard Worker
482*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
483*2d543d20SAndroid Build Coastguard Worker goto exit;
484*2d543d20SAndroid Build Coastguard Worker } else if (rc == CIL_FALSE) {
485*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
486*2d543d20SAndroid Build Coastguard Worker goto exit;
487*2d543d20SAndroid Build Coastguard Worker }
488*2d543d20SAndroid Build Coastguard Worker
489*2d543d20SAndroid Build Coastguard Worker if (!target->is_extended) {
490*2d543d20SAndroid Build Coastguard Worker if (cil_classperms_list_match_any(avrule->perms.classperms, target->perms.classperms)) {
491*2d543d20SAndroid Build Coastguard Worker cil_list_append(matching, CIL_NODE, node);
492*2d543d20SAndroid Build Coastguard Worker }
493*2d543d20SAndroid Build Coastguard Worker } else {
494*2d543d20SAndroid Build Coastguard Worker if (cil_permissionx_match_any(avrule->perms.x.permx, target->perms.x.permx)) {
495*2d543d20SAndroid Build Coastguard Worker cil_list_append(matching, CIL_NODE, node);
496*2d543d20SAndroid Build Coastguard Worker }
497*2d543d20SAndroid Build Coastguard Worker }
498*2d543d20SAndroid Build Coastguard Worker
499*2d543d20SAndroid Build Coastguard Worker rc = SEPOL_OK;
500*2d543d20SAndroid Build Coastguard Worker
501*2d543d20SAndroid Build Coastguard Worker exit:
502*2d543d20SAndroid Build Coastguard Worker return rc;
503*2d543d20SAndroid Build Coastguard Worker }
504*2d543d20SAndroid Build Coastguard Worker
__cil_find_matching_avrule_in_ast(struct cil_tree_node * node,uint32_t * finished,void * extra_args)505*2d543d20SAndroid Build Coastguard Worker static int __cil_find_matching_avrule_in_ast(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
506*2d543d20SAndroid Build Coastguard Worker {
507*2d543d20SAndroid Build Coastguard Worker int rc = SEPOL_OK;
508*2d543d20SAndroid Build Coastguard Worker struct cil_args_find *args = extra_args;
509*2d543d20SAndroid Build Coastguard Worker
510*2d543d20SAndroid Build Coastguard Worker if (node->flavor == CIL_BLOCK) {
511*2d543d20SAndroid Build Coastguard Worker struct cil_block *blk = node->data;
512*2d543d20SAndroid Build Coastguard Worker if (blk->is_abstract == CIL_TRUE) {
513*2d543d20SAndroid Build Coastguard Worker *finished = CIL_TREE_SKIP_HEAD;
514*2d543d20SAndroid Build Coastguard Worker goto exit;
515*2d543d20SAndroid Build Coastguard Worker }
516*2d543d20SAndroid Build Coastguard Worker } else if (node->flavor == CIL_MACRO) {
517*2d543d20SAndroid Build Coastguard Worker *finished = CIL_TREE_SKIP_HEAD;
518*2d543d20SAndroid Build Coastguard Worker goto exit;
519*2d543d20SAndroid Build Coastguard Worker } else if (node->flavor == CIL_AVRULE || node->flavor == CIL_AVRULEX) {
520*2d543d20SAndroid Build Coastguard Worker if (node->flavor == args->flavor) {
521*2d543d20SAndroid Build Coastguard Worker rc = cil_find_matching_avrule(node, node->data, args->target, args->matching, args->match_self);
522*2d543d20SAndroid Build Coastguard Worker }
523*2d543d20SAndroid Build Coastguard Worker }
524*2d543d20SAndroid Build Coastguard Worker
525*2d543d20SAndroid Build Coastguard Worker exit:
526*2d543d20SAndroid Build Coastguard Worker return rc;
527*2d543d20SAndroid Build Coastguard Worker }
528*2d543d20SAndroid Build Coastguard Worker
cil_find_matching_avrule_in_ast(struct cil_tree_node * current,enum cil_flavor flavor,void * target,struct cil_list * matching,int match_self)529*2d543d20SAndroid Build Coastguard Worker int cil_find_matching_avrule_in_ast(struct cil_tree_node *current, enum cil_flavor flavor, void *target, struct cil_list *matching, int match_self)
530*2d543d20SAndroid Build Coastguard Worker {
531*2d543d20SAndroid Build Coastguard Worker int rc;
532*2d543d20SAndroid Build Coastguard Worker struct cil_args_find args;
533*2d543d20SAndroid Build Coastguard Worker
534*2d543d20SAndroid Build Coastguard Worker args.flavor = flavor;
535*2d543d20SAndroid Build Coastguard Worker args.target = target;
536*2d543d20SAndroid Build Coastguard Worker args.matching = matching;
537*2d543d20SAndroid Build Coastguard Worker args.match_self = match_self;
538*2d543d20SAndroid Build Coastguard Worker
539*2d543d20SAndroid Build Coastguard Worker rc = cil_tree_walk(current, __cil_find_matching_avrule_in_ast, NULL, NULL, &args);
540*2d543d20SAndroid Build Coastguard Worker if (rc) {
541*2d543d20SAndroid Build Coastguard Worker cil_log(CIL_ERR, "An error occurred while searching for avrule in AST\n");
542*2d543d20SAndroid Build Coastguard Worker }
543*2d543d20SAndroid Build Coastguard Worker
544*2d543d20SAndroid Build Coastguard Worker return rc;
545*2d543d20SAndroid Build Coastguard Worker }
546