/src/selinux/libsepol/cil/src/cil_deny.c
Line | Count | Source |
1 | | /* |
2 | | * This file is public domain software, i.e. not copyrighted. |
3 | | * |
4 | | * Warranty Exclusion |
5 | | * ------------------ |
6 | | * You agree that this software is a non-commercially developed program |
7 | | * that may contain "bugs" (as that term is used in the industry) and |
8 | | * that it may not function as intended. The software is licensed |
9 | | * "as is". NSA makes no, and hereby expressly disclaims all, warranties, |
10 | | * express, implied, statutory, or otherwise with respect to the software, |
11 | | * including noninfringement and the implied warranties of merchantability |
12 | | * and fitness for a particular purpose. |
13 | | * |
14 | | * Limitation of Liability |
15 | | *----------------------- |
16 | | * In no event will NSA be liable for any damages, including loss of data, |
17 | | * lost profits, cost of cover, or other special, incidental, consequential, |
18 | | * direct or indirect damages arising from the software or the use thereof, |
19 | | * however caused and on any theory of liability. This limitation will apply |
20 | | * even if NSA has been advised of the possibility of such damage. You |
21 | | * acknowledge that this is a reasonable allocation of risk. |
22 | | * |
23 | | * Original author: James Carter |
24 | | */ |
25 | | |
26 | | #include <sepol/policydb/ebitmap.h> |
27 | | |
28 | | #include "cil_internal.h" |
29 | | #include "cil_find.h" |
30 | | #include "cil_flavor.h" |
31 | | #include "cil_list.h" |
32 | | #include "cil_strpool.h" |
33 | | #include "cil_log.h" |
34 | | #include "cil_symtab.h" |
35 | | #include "cil_build_ast.h" |
36 | | #include "cil_copy_ast.h" |
37 | | #include "cil_deny.h" |
38 | | |
39 | 31.9k | #define CIL_DENY_ATTR_PREFIX "deny_rule_attr" |
40 | | |
41 | | /* |
42 | | * A deny rule is like a neverallow rule, except that permissions are |
43 | | * removed rather than an error reported. |
44 | | * |
45 | | * (allow S1 T1 P1) |
46 | | * (deny S2 T2 P2) |
47 | | * |
48 | | * First, write the allow rule with all of the permissions not in the deny rule |
49 | | * P3 = P1 and not P2 |
50 | | * (allow S1 T1 P3) |
51 | | * |
52 | | * Obviously, the rule is only written if P3 is not an empty list. This goes |
53 | | * for the rest of the rules as well--they are only written if the source and |
54 | | * target exist. |
55 | | * |
56 | | * The remaining rules will only involve the common permissions |
57 | | * P4 = P1 and P2 |
58 | | * |
59 | | * Next, write the allow rule for any types in S1 that are not in S2 |
60 | | * S3 = S1 and not S2 |
61 | | * (allow S3 T1 P4) |
62 | | * |
63 | | * Finally, write any allow rules needed to cover the types in T1 that are |
64 | | * not in T2. Since, T1 and T2 might be "self", "notself", or "other", this |
65 | | * requires more complicated handling. Any rule with "self" will not match |
66 | | * a rule with either "notself" or "other". |
67 | | * |
68 | | * if (T1 is self and T2 is self) or (T1 is notself and T2 is notself) then |
69 | | * Nothing more needs to be done. |
70 | | * |
71 | | * The rest of the rules will depend on the intersection of S1 and S2 |
72 | | * which cannot be the empty set since the allow and deny rules match. |
73 | | * S4 = S1 and S2 |
74 | | * |
75 | | * if T1 is notself or T1 is other or T2 is notself or T2 is other then |
76 | | * if T1 is notself then |
77 | | * if T2 is other then |
78 | | * T = ALL and not S2 |
79 | | * (allow S4 T P4) |
80 | | * else [T2 is not self, notself, or other] |
81 | | * S5 = S4 and not T2 |
82 | | * S6 = S4 and T2 |
83 | | * TA = ALL and not T2 |
84 | | * TB = TA and not S4 |
85 | | * (allow S6 TA P4) |
86 | | * (allow S5 TB P4) |
87 | | * if cardinality(S5) > 1 then |
88 | | * (allow S5 other P4) |
89 | | * else if T1 is other then |
90 | | * (allow S3 S4 P4) |
91 | | * if T2 is notself then |
92 | | * [Nothing else is needed] |
93 | | * else if T2 is other then |
94 | | * (allow S4 S3 P4) |
95 | | * else [T2 is not self, notself, or other] |
96 | | * S5 = S4 and not T2 |
97 | | * S6 = S4 and T2 |
98 | | * TC = S1 and not T2 |
99 | | * TD = S3 and not T2 |
100 | | * (allow S6 TC P4) |
101 | | * (allow S5 TD P4) |
102 | | * if cardinality(S5) > 1 then |
103 | | * (allow S5 other P4) |
104 | | * else [T1 is not self, notself, or other] |
105 | | * S8 = S4 and T1 |
106 | | * (allow S8 self P4) |
107 | | * if T2 is notself then |
108 | | * [Nothing else is needed] |
109 | | * else [T2 is other] |
110 | | * T = T1 and not S2 |
111 | | * (allow S4 T P4) |
112 | | * else [Neither T1 nor T2 are notself or other] |
113 | | * if T1 is self and T2 is not self then |
114 | | * S5 = S4 and not T2 |
115 | | * (allow S5 self P4) |
116 | | * else if T1 is not self and T2 is self then |
117 | | * S7 = S4 and not T1 |
118 | | * S8 = S4 and T1 |
119 | | * T8 = T1 and not S4 |
120 | | * (allow S7 T1 P4) |
121 | | * (allow S8 T8 P4) |
122 | | * if cardinality(S8) > 1 then |
123 | | * (allow S8 other P4) |
124 | | * else [Neither T1 nor T2 is self] |
125 | | * T3 = T1 and not T2 |
126 | | * (allow S4 T3 P4) |
127 | | */ |
128 | | |
129 | | static int cil_perm_match(const struct cil_perm *p1, const struct cil_list *pl2) |
130 | 1.80M | { |
131 | 1.80M | struct cil_list_item *curr; |
132 | | |
133 | 2.41M | cil_list_for_each(curr, pl2) { |
134 | 2.41M | struct cil_perm *p = curr->data; |
135 | 2.41M | if (p == p1) { |
136 | 1.51M | return CIL_TRUE; |
137 | 1.51M | } |
138 | 2.41M | } |
139 | 293k | return CIL_FALSE; |
140 | 1.80M | } |
141 | | |
142 | | static int cil_class_perm_match(const struct cil_class *c1, const struct cil_perm *p1, const struct cil_list *cpl2) |
143 | 2.95M | { |
144 | 2.95M | struct cil_list_item *curr; |
145 | | |
146 | 3.14M | cil_list_for_each(curr, cpl2) { |
147 | 3.14M | if (curr->flavor == CIL_CLASSPERMS) { |
148 | 1.89M | struct cil_classperms *cp = curr->data; |
149 | 1.89M | if (FLAVOR(cp->class) == CIL_CLASS) { |
150 | 1.81M | if (cp->class == c1) { |
151 | 1.80M | if (cil_perm_match(p1, cp->perms)) { |
152 | 1.51M | return CIL_TRUE; |
153 | 1.51M | } |
154 | 1.80M | } |
155 | 1.81M | } else { /* MAP */ |
156 | 82.8k | struct cil_list_item *p; |
157 | 104k | cil_list_for_each(p, cp->perms) { |
158 | 104k | struct cil_perm *cmp = p->data; |
159 | 104k | if (cil_class_perm_match(c1, p1, cmp->classperms)) { |
160 | 47.1k | return CIL_TRUE; |
161 | 47.1k | } |
162 | 104k | } |
163 | 82.8k | } |
164 | 1.89M | } else { /* SET */ |
165 | 1.24M | struct cil_classperms_set *cp_set = curr->data; |
166 | 1.24M | struct cil_classpermission *cp = cp_set->set; |
167 | 1.24M | if (cil_class_perm_match(c1, p1, cp->classperms)) { |
168 | 1.07M | return CIL_TRUE; |
169 | 1.07M | } |
170 | 1.24M | } |
171 | 3.14M | } |
172 | 317k | return CIL_FALSE; |
173 | 2.95M | } |
174 | | |
175 | | static int cil_classperms_match_any(const struct cil_classperms *cp1, const struct cil_list *cpl2) |
176 | 686k | { |
177 | 686k | struct cil_list_item *curr; |
178 | | |
179 | 702k | cil_list_for_each(curr, cp1->perms) { |
180 | 702k | struct cil_perm *perm = curr->data; |
181 | 702k | if (cil_class_perm_match(cp1->class, perm, cpl2)) { |
182 | 675k | return CIL_TRUE; |
183 | 675k | } |
184 | 702k | } |
185 | 11.5k | return CIL_FALSE; |
186 | 686k | } |
187 | | |
188 | | int cil_classperms_list_match_any(const struct cil_list *cpl1, const struct cil_list *cpl2) |
189 | 436k | { |
190 | 436k | struct cil_list_item *curr; |
191 | | |
192 | 436k | if (!cpl1 || !cpl2) { |
193 | 0 | return (!cpl1 && !cpl2) ? CIL_TRUE : CIL_FALSE; |
194 | 0 | } |
195 | | |
196 | 442k | cil_list_for_each(curr, cpl1) { |
197 | 442k | if (curr->flavor == CIL_CLASSPERMS) { |
198 | 431k | struct cil_classperms *cp = curr->data; |
199 | 431k | if (FLAVOR(cp->class) == CIL_CLASS) { |
200 | 428k | if (cil_classperms_match_any(cp, cpl2)) { |
201 | 418k | return CIL_TRUE; |
202 | 418k | } |
203 | 428k | } else { /* MAP */ |
204 | 3.25k | struct cil_list_item *p; |
205 | 4.43k | cil_list_for_each(p, cp->perms) { |
206 | 4.43k | struct cil_perm *cmp = p->data; |
207 | 4.43k | if (cil_classperms_list_match_any(cmp->classperms, cpl2)) { |
208 | 3.22k | return CIL_TRUE; |
209 | 3.22k | } |
210 | 4.43k | } |
211 | 3.25k | } |
212 | 431k | } else { /* SET */ |
213 | 10.2k | struct cil_classperms_set *cp_set = curr->data; |
214 | 10.2k | struct cil_classpermission *cp = cp_set->set; |
215 | 10.2k | if (cil_classperms_list_match_any(cp->classperms, cpl2)) { |
216 | 7.74k | return CIL_TRUE; |
217 | 7.74k | } |
218 | 10.2k | } |
219 | 442k | } |
220 | 6.60k | return CIL_FALSE; |
221 | 436k | } |
222 | | |
223 | | static int cil_classperms_match_all(const struct cil_classperms *cp1, const struct cil_list *cpl2) |
224 | 282k | { |
225 | 282k | struct cil_list_item *curr; |
226 | | |
227 | 448k | cil_list_for_each(curr, cp1->perms) { |
228 | 448k | struct cil_perm *perm = curr->data; |
229 | 448k | if (!cil_class_perm_match(cp1->class, perm, cpl2)) { |
230 | 28.0k | return CIL_FALSE; |
231 | 28.0k | } |
232 | 448k | } |
233 | 254k | return CIL_TRUE; |
234 | 282k | } |
235 | | |
236 | | int cil_classperms_list_match_all(const struct cil_list *cpl1, const struct cil_list *cpl2) |
237 | 278k | { |
238 | 278k | struct cil_list_item *curr; |
239 | | |
240 | 278k | if (!cpl1 || !cpl2) { |
241 | 0 | return (!cpl1 && !cpl2) ? CIL_TRUE : CIL_FALSE; |
242 | 0 | } |
243 | | |
244 | 426k | cil_list_for_each(curr, cpl1) { |
245 | 426k | if (curr->flavor == CIL_CLASSPERMS) { |
246 | 274k | struct cil_classperms *cp = curr->data; |
247 | 274k | if (FLAVOR(cp->class) == CIL_CLASS) { |
248 | 270k | if (!cil_classperms_match_all(cp, cpl2)) { |
249 | 17.3k | return CIL_FALSE; |
250 | 17.3k | } |
251 | 270k | } else { /* MAP */ |
252 | 3.18k | struct cil_list_item *p; |
253 | 4.28k | cil_list_for_each(p, cp->perms) { |
254 | 4.28k | struct cil_perm *cmp = p->data; |
255 | 4.28k | if (!cil_classperms_list_match_all(cmp->classperms, cpl2)) { |
256 | 1.79k | return CIL_FALSE; |
257 | 1.79k | } |
258 | 4.28k | } |
259 | 3.18k | } |
260 | 274k | } else { /* SET */ |
261 | 151k | struct cil_classperms_set *cp_set = curr->data; |
262 | 151k | struct cil_classpermission *cp = cp_set->set; |
263 | 151k | if (!cil_classperms_list_match_all(cp->classperms, cpl2)) { |
264 | 3.37k | return CIL_FALSE; |
265 | 3.37k | } |
266 | 151k | } |
267 | 426k | } |
268 | 255k | return CIL_TRUE; |
269 | 278k | } |
270 | | |
271 | | static void cil_classperms_copy(struct cil_classperms **new, const struct cil_classperms *old) |
272 | 242k | { |
273 | 242k | cil_classperms_init(new); |
274 | 242k | (*new)->class_str = old->class_str; |
275 | 242k | (*new)->class = old->class; |
276 | 242k | cil_copy_list(old->perm_strs, &(*new)->perm_strs); |
277 | 242k | cil_copy_list(old->perms, &(*new)->perms); |
278 | 242k | } |
279 | | |
280 | | static void cil_classperms_set_copy(struct cil_classperms_set **new, const struct cil_classperms_set *old) |
281 | 4.69k | { |
282 | 4.69k | cil_classperms_set_init(new); |
283 | 4.69k | (*new)->set_str = old->set_str; |
284 | 4.69k | (*new)->set = old->set; |
285 | 4.69k | } |
286 | | |
287 | | void cil_classperms_list_copy(struct cil_list **new, const struct cil_list *old) |
288 | 236k | { |
289 | 236k | struct cil_list_item *curr; |
290 | | |
291 | 236k | if (!new) { |
292 | 0 | return; |
293 | 0 | } |
294 | | |
295 | 236k | if (!old) { |
296 | 0 | *new = NULL; |
297 | 0 | return; |
298 | 0 | } |
299 | | |
300 | 236k | cil_list_init(new, CIL_LIST); |
301 | | |
302 | 241k | cil_list_for_each(curr, old) { |
303 | 241k | if (curr->flavor == CIL_CLASSPERMS) { |
304 | 239k | struct cil_classperms *new_cp; |
305 | 239k | cil_classperms_copy(&new_cp, curr->data); |
306 | 239k | cil_list_append(*new, CIL_CLASSPERMS, new_cp); |
307 | 239k | } else { /* SET */ |
308 | 1.39k | struct cil_classperms_set *new_cps; |
309 | 1.39k | cil_classperms_set_copy(&new_cps, curr->data); |
310 | 1.39k | cil_list_append(*new, CIL_CLASSPERMS_SET, new_cps); |
311 | 1.39k | } |
312 | 241k | } |
313 | | |
314 | 236k | if (cil_list_is_empty(*new)) { |
315 | 0 | cil_list_destroy(new, CIL_FALSE); |
316 | 0 | } |
317 | 236k | } |
318 | | |
319 | | /* Append cp1 and cpl2 to result */ |
320 | | static void cil_classperms_and(struct cil_list **result, const struct cil_classperms *cp1, const struct cil_list *cpl2) |
321 | 11.7k | { |
322 | 11.7k | struct cil_classperms *new_cp = NULL; |
323 | 11.7k | struct cil_list_item *curr; |
324 | | |
325 | 11.7k | if (cil_classperms_match_all(cp1, cpl2)) { |
326 | 973 | cil_classperms_copy(&new_cp, cp1); |
327 | 973 | cil_list_append(*result, CIL_CLASSPERMS, new_cp); |
328 | 973 | return; |
329 | 973 | } |
330 | | |
331 | 26.1k | cil_list_for_each(curr, cp1->perms) { |
332 | 26.1k | struct cil_perm *perm = curr->data; |
333 | 26.1k | if (cil_class_perm_match(cp1->class, perm, cpl2)) { |
334 | 5.66k | if (new_cp == NULL) { |
335 | 5.09k | cil_classperms_init(&new_cp); |
336 | 5.09k | new_cp->class_str = cp1->class_str; |
337 | 5.09k | new_cp->class = cp1->class; |
338 | 5.09k | cil_list_init(&new_cp->perm_strs, CIL_PERM); |
339 | 5.09k | cil_list_init(&new_cp->perms, CIL_PERM); |
340 | 5.09k | cil_list_append(*result, CIL_CLASSPERMS, new_cp); |
341 | 5.09k | } |
342 | 5.66k | cil_list_append(new_cp->perm_strs, CIL_STRING, perm->datum.fqn); |
343 | 5.66k | cil_list_append(new_cp->perms, CIL_DATUM, perm); |
344 | 5.66k | } |
345 | 26.1k | } |
346 | 10.7k | } |
347 | | |
348 | | /* Append cp1 and cpl2 to result */ |
349 | | static void cil_classperms_map_and(struct cil_list **result, const struct cil_classperms *cp1, const struct cil_list *cpl2) |
350 | 3.20k | { |
351 | 3.20k | struct cil_classperms *new_cp = NULL; |
352 | 3.20k | struct cil_list_item *p; |
353 | | |
354 | 7.86k | cil_list_for_each(p, cp1->perms) { |
355 | 7.86k | struct cil_perm *map_perm = p->data; |
356 | 7.86k | if (cil_classperms_list_match_all(map_perm->classperms, cpl2)) { |
357 | 3.36k | if (new_cp == NULL) { |
358 | 2.21k | cil_classperms_init(&new_cp); |
359 | 2.21k | new_cp->class_str = cp1->class_str; |
360 | 2.21k | new_cp->class = cp1->class; |
361 | 2.21k | cil_list_init(&new_cp->perm_strs, CIL_PERM); |
362 | 2.21k | cil_list_init(&new_cp->perms, CIL_PERM); |
363 | 2.21k | cil_list_append(*result, CIL_CLASSPERMS, new_cp); |
364 | 2.21k | } |
365 | 3.36k | cil_list_append(new_cp->perm_strs, CIL_STRING, map_perm->datum.fqn); |
366 | 3.36k | cil_list_append(new_cp->perms, CIL_DATUM, map_perm); |
367 | 4.49k | } else { |
368 | 4.49k | struct cil_list *new_cpl = NULL; |
369 | 4.49k | cil_classperms_list_and(&new_cpl, map_perm->classperms, cpl2); |
370 | 4.49k | if (new_cpl) { |
371 | 2.55k | struct cil_list_item *i; |
372 | 7.98k | cil_list_for_each(i, new_cpl) { |
373 | 7.98k | cil_list_append(*result, i->flavor, i->data); |
374 | 7.98k | } |
375 | 2.55k | cil_list_destroy(&new_cpl, CIL_FALSE); |
376 | 2.55k | } |
377 | 4.49k | } |
378 | 7.86k | } |
379 | 3.20k | } |
380 | | |
381 | | /* Append cps1 and cpl2 to result */ |
382 | | static void cil_classperms_set_and(struct cil_list **result, const struct cil_classperms_set *cps1, const struct cil_list *cpl2) |
383 | 4.43k | { |
384 | 4.43k | struct cil_classpermission *cp = cps1->set; |
385 | | |
386 | 4.43k | if (cil_classperms_list_match_all(cp->classperms, cpl2)) { |
387 | 2.38k | struct cil_classperms_set *new_cps; |
388 | 2.38k | cil_classperms_set_copy(&new_cps, cps1); |
389 | 2.38k | cil_list_append(*result, CIL_CLASSPERMS_SET, new_cps); |
390 | 2.38k | } else { |
391 | 2.05k | struct cil_list *new_cpl; |
392 | 2.05k | cil_classperms_list_and(&new_cpl, cp->classperms, cpl2); |
393 | 2.05k | if (new_cpl) { |
394 | 839 | struct cil_list_item *i; |
395 | 1.38k | cil_list_for_each(i, new_cpl) { |
396 | 1.38k | cil_list_append(*result, i->flavor, i->data); |
397 | 1.38k | } |
398 | 839 | cil_list_destroy(&new_cpl, CIL_FALSE); |
399 | 839 | } |
400 | 2.05k | } |
401 | 4.43k | } |
402 | | |
403 | | /* result = cpl1 and cpl2 */ |
404 | | void cil_classperms_list_and(struct cil_list **result, const struct cil_list *cpl1, const struct cil_list *cpl2) |
405 | 109k | { |
406 | 109k | struct cil_list_item *curr; |
407 | | |
408 | 109k | if (!result) { |
409 | 0 | return; |
410 | 0 | } |
411 | | |
412 | 109k | if (!cpl1 || !cpl2) { |
413 | 0 | *result = NULL; |
414 | 0 | return; |
415 | 0 | } |
416 | | |
417 | 109k | if (cil_classperms_list_match_all(cpl1, cpl2)) { |
418 | 98.6k | cil_classperms_list_copy(result, cpl1); |
419 | 98.6k | return; |
420 | 98.6k | } |
421 | | |
422 | 10.7k | cil_list_init(result, CIL_LIST); |
423 | | |
424 | 19.3k | cil_list_for_each(curr, cpl1) { |
425 | 19.3k | if (curr->flavor == CIL_CLASSPERMS) { |
426 | 14.9k | struct cil_classperms *cp = curr->data; |
427 | 14.9k | if (FLAVOR(cp->class) == CIL_CLASS) { |
428 | 11.7k | cil_classperms_and(result, cp, cpl2); |
429 | 11.7k | } else { /* MAP */ |
430 | 3.20k | cil_classperms_map_and(result, cp, cpl2); |
431 | 3.20k | } |
432 | 14.9k | } else { /* SET */ |
433 | 4.43k | struct cil_classperms_set *cps = curr->data; |
434 | 4.43k | cil_classperms_set_and(result, cps, cpl2); |
435 | 4.43k | } |
436 | 19.3k | } |
437 | | |
438 | 10.7k | if (cil_list_is_empty(*result)) { |
439 | 3.15k | cil_list_destroy(result, CIL_FALSE); |
440 | 3.15k | } |
441 | 10.7k | } |
442 | | |
443 | | /* Append cp1 and not cpl2 to result */ |
444 | | static void cil_classperms_andnot(struct cil_list **result, const struct cil_classperms *cp1, const struct cil_list *cpl2) |
445 | 258k | { |
446 | 258k | struct cil_classperms *new_cp = NULL; |
447 | 258k | struct cil_list_item *curr; |
448 | | |
449 | 258k | if (!cil_classperms_match_any(cp1, cpl2)) { |
450 | 1.66k | cil_classperms_copy(&new_cp, cp1); |
451 | 1.66k | cil_list_append(*result, CIL_CLASSPERMS, new_cp); |
452 | 1.66k | return; |
453 | 1.66k | } |
454 | | |
455 | 421k | cil_list_for_each(curr, cp1->perms) { |
456 | 421k | struct cil_perm *perm = curr->data; |
457 | 421k | if (!cil_class_perm_match(cp1->class, perm, cpl2)) { |
458 | 8.33k | if (new_cp == NULL) { |
459 | 5.09k | cil_classperms_init(&new_cp); |
460 | 5.09k | new_cp->class_str = cp1->class_str; |
461 | 5.09k | new_cp->class = cp1->class; |
462 | 5.09k | cil_list_init(&new_cp->perm_strs, CIL_PERM); |
463 | 5.09k | cil_list_init(&new_cp->perms, CIL_PERM); |
464 | 5.09k | cil_list_append(*result, CIL_CLASSPERMS, new_cp); |
465 | 5.09k | } |
466 | 8.33k | cil_list_append(new_cp->perm_strs, CIL_STRING, perm->datum.fqn); |
467 | 8.33k | cil_list_append(new_cp->perms, CIL_DATUM, perm); |
468 | 8.33k | } |
469 | 421k | } |
470 | 256k | } |
471 | | |
472 | | /* Append cp1 and not cpl2 to result */ |
473 | | static void cil_classperms_map_andnot(struct cil_list **result, const struct cil_classperms *cp1, const struct cil_list *cpl2) |
474 | 4.60k | { |
475 | 4.60k | struct cil_classperms *new_cp = NULL; |
476 | 4.60k | struct cil_list_item *p; |
477 | | |
478 | 9.93k | cil_list_for_each(p, cp1->perms) { |
479 | 9.93k | struct cil_perm *map_perm = p->data; |
480 | 9.93k | if (!cil_classperms_list_match_any(map_perm->classperms, cpl2)) { |
481 | 1.94k | if (new_cp == NULL) { |
482 | 1.25k | cil_classperms_init(&new_cp); |
483 | 1.25k | new_cp->class_str = cp1->class_str; |
484 | 1.25k | new_cp->class = cp1->class; |
485 | 1.25k | cil_list_init(&new_cp->perm_strs, CIL_PERM); |
486 | 1.25k | cil_list_init(&new_cp->perms, CIL_PERM); |
487 | 1.25k | cil_list_append(*result, CIL_CLASSPERMS, new_cp); |
488 | 1.25k | } |
489 | 1.94k | cil_list_append(new_cp->perm_strs, CIL_STRING, map_perm->datum.fqn); |
490 | 1.94k | cil_list_append(new_cp->perms, CIL_DATUM, map_perm); |
491 | 7.98k | } else { |
492 | 7.98k | struct cil_list *new_cpl = NULL; |
493 | 7.98k | cil_classperms_list_andnot(&new_cpl, map_perm->classperms, cpl2); |
494 | 7.98k | if (new_cpl) { |
495 | 2.55k | struct cil_list_item *i; |
496 | 5.14k | cil_list_for_each(i, new_cpl) { |
497 | 5.14k | cil_list_append(*result, i->flavor, i->data); |
498 | 5.14k | } |
499 | 2.55k | cil_list_destroy(&new_cpl, CIL_FALSE); |
500 | 2.55k | } |
501 | 7.98k | } |
502 | 9.93k | } |
503 | 4.60k | } |
504 | | |
505 | | /* Append cps1 and not cpl2 to result */ |
506 | | static void cil_classperms_set_andnot(struct cil_list **result, const struct cil_classperms_set *cps1, const struct cil_list *cpl2) |
507 | 150k | { |
508 | 150k | struct cil_classpermission *cp = cps1->set; |
509 | | |
510 | 150k | if (!cil_classperms_list_match_any(cp->classperms, cpl2)) { |
511 | 914 | struct cil_classperms_set *new_cps; |
512 | 914 | cil_classperms_set_copy(&new_cps, cps1); |
513 | 914 | cil_list_append(*result, CIL_CLASSPERMS_SET, new_cps); |
514 | 149k | } else { |
515 | 149k | struct cil_list *new_cpl; |
516 | 149k | cil_classperms_list_andnot(&new_cpl, cp->classperms, cpl2); |
517 | 149k | if (new_cpl) { |
518 | 839 | struct cil_list_item *i; |
519 | 1.59k | cil_list_for_each(i, new_cpl) { |
520 | 1.59k | cil_list_append(*result, i->flavor, i->data); |
521 | 1.59k | } |
522 | 839 | cil_list_destroy(&new_cpl, CIL_FALSE); |
523 | 839 | } |
524 | 149k | } |
525 | 150k | } |
526 | | |
527 | | /* result = cpl1 and not cpl2 */ |
528 | | void cil_classperms_list_andnot(struct cil_list **result, const struct cil_list *cpl1, const struct cil_list *cpl2) |
529 | 260k | { |
530 | 260k | struct cil_list_item *curr; |
531 | | |
532 | 260k | if (!result) { |
533 | 0 | return; |
534 | 0 | } |
535 | | |
536 | 260k | if (!cpl1) { |
537 | 0 | *result = NULL; |
538 | 0 | return; |
539 | 0 | } |
540 | | |
541 | 260k | if (!cpl2 || !cil_classperms_list_match_any(cpl1, cpl2)) { |
542 | 0 | cil_classperms_list_copy(result, cpl1); |
543 | 0 | return; |
544 | 0 | } |
545 | | |
546 | 260k | cil_list_init(result, CIL_LIST); |
547 | | |
548 | 413k | cil_list_for_each(curr, cpl1) { |
549 | 413k | if (curr->flavor == CIL_CLASSPERMS) { |
550 | 263k | struct cil_classperms *cp = curr->data; |
551 | 263k | if (FLAVOR(cp->class) == CIL_CLASS) { |
552 | 258k | cil_classperms_andnot(result, cp, cpl2); |
553 | 258k | } else { /* MAP */ |
554 | 4.60k | cil_classperms_map_andnot(result, cp, cpl2); |
555 | 4.60k | } |
556 | 263k | } else { /* SET */ |
557 | 150k | struct cil_classperms_set *cps = curr->data; |
558 | 150k | cil_classperms_set_andnot(result, cps, cpl2); |
559 | 150k | } |
560 | 413k | } |
561 | | |
562 | 260k | if (cil_list_is_empty(*result)) { |
563 | 253k | cil_list_destroy(result, CIL_FALSE); |
564 | 253k | } |
565 | 260k | } |
566 | | |
567 | | static int cil_datum_cardinality(const struct cil_symtab_datum *d) |
568 | 19.5k | { |
569 | 19.5k | if (!d) { |
570 | 734 | return 0; |
571 | 734 | } |
572 | 18.7k | if (FLAVOR(d) != CIL_TYPEATTRIBUTE) { |
573 | 10.0k | return 1; |
574 | 10.0k | } else { |
575 | 8.77k | struct cil_typeattribute *a = (struct cil_typeattribute *)d; |
576 | 8.77k | return ebitmap_cardinality(a->types); |
577 | 8.77k | } |
578 | 18.7k | } |
579 | | |
580 | | /* result = ALL and not d2 */ |
581 | | static int cil_datum_not(ebitmap_t *result, const struct cil_symtab_datum *d, int max) |
582 | 20.9k | { |
583 | 20.9k | int rc = SEPOL_OK; |
584 | | |
585 | 20.9k | if (FLAVOR(d) != CIL_TYPEATTRIBUTE) { |
586 | 11.4k | struct cil_type *t = (struct cil_type *)d; |
587 | 11.4k | ebitmap_t e; |
588 | | |
589 | 11.4k | ebitmap_init(&e); |
590 | 11.4k | rc = ebitmap_set_bit(&e, t->value, 1); |
591 | 11.4k | if (rc != SEPOL_OK) { |
592 | 0 | ebitmap_destroy(&e); |
593 | 0 | goto exit; |
594 | 0 | } |
595 | | |
596 | 11.4k | ebitmap_init(result); |
597 | 11.4k | rc = ebitmap_not(result, &e, max); |
598 | 11.4k | if (rc != SEPOL_OK) { |
599 | 0 | ebitmap_destroy(&e); |
600 | 0 | ebitmap_destroy(result); |
601 | 0 | goto exit; |
602 | 0 | } |
603 | 11.4k | ebitmap_destroy(&e); |
604 | 11.4k | } else { |
605 | 9.49k | struct cil_typeattribute *a = (struct cil_typeattribute *)d; |
606 | | |
607 | 9.49k | ebitmap_init(result); |
608 | 9.49k | rc = ebitmap_not(result, a->types, max); |
609 | 9.49k | if (rc != SEPOL_OK) { |
610 | 0 | ebitmap_destroy(result); |
611 | 0 | goto exit; |
612 | 0 | } |
613 | 9.49k | } |
614 | 20.9k | exit: |
615 | 20.9k | return rc; |
616 | 20.9k | } |
617 | | |
618 | | /* result = d1 and d2 */ |
619 | | static int cil_datums_and(ebitmap_t *result, const struct cil_symtab_datum *d1, const struct cil_symtab_datum *d2) |
620 | 109k | { |
621 | 109k | int rc = SEPOL_OK; |
622 | 109k | enum cil_flavor f1 = FLAVOR(d1); |
623 | 109k | enum cil_flavor f2 = FLAVOR(d2); |
624 | | |
625 | 109k | if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) { |
626 | 7.28k | struct cil_type *t1 = (struct cil_type *)d1; |
627 | 7.28k | struct cil_type *t2 = (struct cil_type *)d2; |
628 | 7.28k | ebitmap_init(result); |
629 | 7.28k | if (t1->value == t2->value) { |
630 | 0 | rc = ebitmap_set_bit(result, t1->value, 1); |
631 | 0 | if (rc != SEPOL_OK) { |
632 | 0 | ebitmap_destroy(result); |
633 | 0 | goto exit; |
634 | 0 | } |
635 | 0 | } |
636 | 101k | } else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) { |
637 | 11.9k | struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1; |
638 | 11.9k | struct cil_type *t2 = (struct cil_type *)d2; |
639 | 11.9k | ebitmap_init(result); |
640 | 11.9k | if (ebitmap_get_bit(a1->types, t2->value)) { |
641 | 7.87k | rc = ebitmap_set_bit(result, t2->value, 1); |
642 | 7.87k | if (rc != SEPOL_OK) { |
643 | 0 | ebitmap_destroy(result); |
644 | 0 | goto exit; |
645 | 0 | } |
646 | 7.87k | } |
647 | 89.8k | } else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) { |
648 | 27.5k | struct cil_type *t1 = (struct cil_type *)d1; |
649 | 27.5k | struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2; |
650 | 27.5k | ebitmap_init(result); |
651 | 27.5k | if (ebitmap_get_bit(a2->types, t1->value)) { |
652 | 26.9k | rc = ebitmap_set_bit(result, t1->value, 1); |
653 | 26.9k | if (rc != SEPOL_OK) { |
654 | 0 | ebitmap_destroy(result); |
655 | 0 | goto exit; |
656 | 0 | } |
657 | 26.9k | } |
658 | 62.2k | } else { |
659 | | /* Both are attributes */ |
660 | 62.2k | struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1; |
661 | 62.2k | struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2; |
662 | 62.2k | rc = ebitmap_and(result, a1->types, a2->types); |
663 | 62.2k | if (rc != SEPOL_OK) { |
664 | 0 | ebitmap_destroy(result); |
665 | 0 | goto exit; |
666 | 0 | } |
667 | 62.2k | } |
668 | 109k | exit: |
669 | 109k | return rc; |
670 | 109k | } |
671 | | |
672 | | /* result = d1 and not d2 */ |
673 | | static int cil_datums_andnot(ebitmap_t *result, const struct cil_symtab_datum *d1, const struct cil_symtab_datum *d2) |
674 | 188k | { |
675 | 188k | int rc = SEPOL_OK; |
676 | 188k | enum cil_flavor f1 = FLAVOR(d1); |
677 | 188k | enum cil_flavor f2 = FLAVOR(d2); |
678 | | |
679 | 188k | if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) { |
680 | 6.27k | struct cil_type *t1 = (struct cil_type *)d1; |
681 | 6.27k | struct cil_type *t2 = (struct cil_type *)d2; |
682 | 6.27k | ebitmap_init(result); |
683 | 6.27k | if (t1->value != t2->value) { |
684 | 6.27k | rc = ebitmap_set_bit(result, t1->value, 1); |
685 | 6.27k | if (rc != SEPOL_OK) { |
686 | 0 | ebitmap_destroy(result); |
687 | 0 | goto exit; |
688 | 0 | } |
689 | 6.27k | } |
690 | 181k | } else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) { |
691 | 61.3k | struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1; |
692 | 61.3k | struct cil_type *t2 = (struct cil_type *)d2; |
693 | 61.3k | rc = ebitmap_cpy(result, a1->types); |
694 | 61.3k | if (rc != SEPOL_OK) { |
695 | 0 | goto exit; |
696 | 0 | } |
697 | 61.3k | rc = ebitmap_set_bit(result, t2->value, 0); |
698 | 61.3k | if (rc != SEPOL_OK) { |
699 | 0 | ebitmap_destroy(result); |
700 | 0 | goto exit; |
701 | 0 | } |
702 | 120k | } else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) { |
703 | 28.6k | struct cil_type *t1 = (struct cil_type *)d1; |
704 | 28.6k | struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2; |
705 | 28.6k | ebitmap_init(result); |
706 | 28.6k | if (!ebitmap_get_bit(a2->types, t1->value)) { |
707 | 568 | rc = ebitmap_set_bit(result, t1->value, 1); |
708 | 568 | if (rc != SEPOL_OK) { |
709 | 0 | ebitmap_destroy(result); |
710 | 0 | goto exit; |
711 | 0 | } |
712 | 568 | } |
713 | 91.9k | } else { |
714 | | /* Both are attributes */ |
715 | 91.9k | struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1; |
716 | 91.9k | struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2; |
717 | 91.9k | rc = ebitmap_andnot(result, a1->types, a2->types, a1->types->highbit); |
718 | 91.9k | if (rc != SEPOL_OK) { |
719 | 0 | ebitmap_destroy(result); |
720 | 0 | goto exit; |
721 | 0 | } |
722 | 91.9k | } |
723 | 188k | exit: |
724 | 188k | return rc; |
725 | 188k | } |
726 | | |
727 | | static size_t num_digits(unsigned n) |
728 | 15.9k | { |
729 | 15.9k | size_t num = 1; |
730 | 51.7k | while (n >= 10) { |
731 | 35.7k | n /= 10; |
732 | 35.7k | num++; |
733 | 35.7k | } |
734 | 15.9k | return num; |
735 | 15.9k | } |
736 | | |
737 | | static char *cil_create_new_attribute_name(unsigned num) |
738 | 15.9k | { |
739 | 15.9k | char *s1 = NULL; |
740 | 15.9k | char *s2 = NULL; |
741 | 15.9k | size_t len_num = num_digits(num); |
742 | 15.9k | size_t len = strlen(CIL_DENY_ATTR_PREFIX) + 1 + len_num + 1; |
743 | 15.9k | int rc; |
744 | | |
745 | 15.9k | if (len >= CIL_MAX_NAME_LENGTH) { |
746 | 0 | cil_log(CIL_ERR, "Name length greater than max name length of %d", |
747 | 0 | CIL_MAX_NAME_LENGTH); |
748 | 0 | goto exit; |
749 | 0 | } |
750 | | |
751 | 15.9k | s1 = cil_malloc(len); |
752 | 15.9k | rc = snprintf(s1, len, "%s_%u", CIL_DENY_ATTR_PREFIX, num); |
753 | 15.9k | if (rc < 0 || (size_t)rc >= len) { |
754 | 0 | cil_log(CIL_ERR, "Error creating new attribute name"); |
755 | 0 | free(s1); |
756 | 0 | goto exit; |
757 | 0 | } |
758 | | |
759 | 15.9k | s2 = cil_strpool_add(s1); |
760 | 15.9k | free(s1); |
761 | | |
762 | 15.9k | exit: |
763 | 15.9k | return s2; |
764 | 15.9k | } |
765 | | |
766 | | static struct cil_list *cil_create_and_expr_list(enum cil_flavor f1, void *v1, enum cil_flavor f2, void *v2) |
767 | 218k | { |
768 | 218k | struct cil_list *expr; |
769 | | |
770 | 218k | cil_list_init(&expr, CIL_TYPE); |
771 | 218k | cil_list_append(expr, CIL_OP, (void *)CIL_AND); |
772 | 218k | cil_list_append(expr, f1, v1); |
773 | 218k | cil_list_append(expr, f2, v2); |
774 | | |
775 | 218k | return expr; |
776 | 218k | } |
777 | | |
778 | | static struct cil_list *cil_create_andnot_expr_list(enum cil_flavor f1, void *v1, enum cil_flavor f2, void *v2) |
779 | 418k | { |
780 | 418k | struct cil_list *expr, *sub_expr; |
781 | | |
782 | 418k | cil_list_init(&expr, CIL_TYPE); |
783 | 418k | cil_list_append(expr, CIL_OP, (void *)CIL_AND); |
784 | 418k | cil_list_append(expr, f1, v1); |
785 | 418k | cil_list_init(&sub_expr, CIL_TYPE); |
786 | 418k | cil_list_append(sub_expr, CIL_OP, (void *)CIL_NOT); |
787 | 418k | cil_list_append(sub_expr, f2, v2); |
788 | 418k | cil_list_append(expr, CIL_LIST, sub_expr); |
789 | | |
790 | 418k | return expr; |
791 | 418k | } |
792 | | |
793 | | static struct cil_tree_node *cil_create_and_insert_node(struct cil_tree_node *prev, enum cil_flavor flavor, void *data) |
794 | 169k | { |
795 | 169k | struct cil_tree_node *new; |
796 | | |
797 | 169k | cil_tree_node_init(&new); |
798 | 169k | new->parent = prev->parent; |
799 | 169k | new->line = prev->line; |
800 | 169k | new->hll_offset = prev->hll_offset; |
801 | 169k | new->flavor = flavor; |
802 | 169k | new->data = data; |
803 | 169k | new->next = prev->next; |
804 | 169k | prev->next = new; |
805 | | |
806 | 169k | return new; |
807 | 169k | } |
808 | | |
809 | | static int cil_create_and_insert_attribute_and_set(struct cil_db *db, struct cil_tree_node *prev, struct cil_list *str_expr, struct cil_list *datum_expr, ebitmap_t *types, struct cil_symtab_datum **d) |
810 | 15.9k | { |
811 | 15.9k | struct cil_tree_node *attr_node = NULL; |
812 | 15.9k | char *name; |
813 | 15.9k | struct cil_typeattribute *attr = NULL; |
814 | 15.9k | struct cil_tree_node *attrset_node = NULL; |
815 | 15.9k | struct cil_typeattributeset *attrset = NULL; |
816 | 15.9k | symtab_t *symtab = NULL; |
817 | 15.9k | int rc = SEPOL_ERR; |
818 | | |
819 | 15.9k | name = cil_create_new_attribute_name(db->num_types_and_attrs); |
820 | 15.9k | if (!name) { |
821 | 0 | goto exit; |
822 | 0 | } |
823 | | |
824 | 15.9k | cil_typeattributeset_init(&attrset); |
825 | 15.9k | attrset->attr_str = name; |
826 | 15.9k | attrset->str_expr = str_expr; |
827 | 15.9k | attrset->datum_expr = datum_expr; |
828 | | |
829 | 15.9k | cil_typeattribute_init(&attr); |
830 | 15.9k | cil_list_init(&attr->expr_list, CIL_TYPE); |
831 | 15.9k | cil_list_append(attr->expr_list, CIL_LIST, datum_expr); |
832 | 15.9k | attr->types = types; |
833 | 15.9k | attr->used = CIL_ATTR_AVRULE; |
834 | 15.9k | attr->keep = (ebitmap_cardinality(types) < db->attrs_expand_size) ? CIL_FALSE : CIL_TRUE; |
835 | | |
836 | 15.9k | attr_node = cil_create_and_insert_node(prev, CIL_TYPEATTRIBUTE, attr); |
837 | 15.9k | attrset_node = cil_create_and_insert_node(attr_node, CIL_TYPEATTRIBUTESET, attrset); |
838 | | |
839 | 15.9k | rc = cil_get_symtab(prev->parent, &symtab, CIL_SYM_TYPES); |
840 | 15.9k | if (rc != SEPOL_OK) { |
841 | 0 | goto exit; |
842 | 0 | } |
843 | | |
844 | 15.9k | rc = cil_symtab_insert(symtab, name, &attr->datum, attr_node); |
845 | 15.9k | if (rc != SEPOL_OK) { |
846 | 0 | goto exit; |
847 | 0 | } |
848 | | |
849 | 15.9k | db->num_types_and_attrs++; |
850 | | |
851 | 15.9k | *d = &attr->datum; |
852 | | |
853 | 15.9k | return SEPOL_OK; |
854 | | |
855 | 0 | exit: |
856 | 0 | if (attr_node) { |
857 | 0 | cil_destroy_typeattribute(attr_node->data); // This will not destroy datum_expr |
858 | 0 | free(attr_node); |
859 | 0 | } |
860 | 0 | if (attrset_node) { |
861 | 0 | prev->next = attrset_node->next; |
862 | 0 | free(attrset_node); |
863 | 0 | } |
864 | 0 | return rc; |
865 | 15.9k | } |
866 | | |
867 | | struct attr_symtab_map_data { |
868 | | struct cil_symtab_datum *d; |
869 | | ebitmap_t *types; |
870 | | }; |
871 | | |
872 | | static int cil_check_attribute_in_symtab(__attribute__((unused))hashtab_key_t k, hashtab_datum_t d, void *args) |
873 | 16.8M | { |
874 | 16.8M | struct attr_symtab_map_data *data = args; |
875 | | |
876 | 16.8M | if (FLAVOR(d) == CIL_TYPEATTRIBUTE) { |
877 | 13.1M | struct cil_typeattribute *attr = (struct cil_typeattribute *)d; |
878 | 13.1M | if (ebitmap_cmp(data->types, attr->types)) { |
879 | 170k | data->d = d; |
880 | 170k | } |
881 | 13.1M | } |
882 | 16.8M | return SEPOL_OK; |
883 | 16.8M | } |
884 | | |
885 | | static struct cil_symtab_datum *cil_check_for_previously_defined_attribute(struct cil_db *db, ebitmap_t *types, struct cil_symtab_datum *d) |
886 | 184k | { |
887 | 184k | symtab_t *local_symtab, *root_symtab; |
888 | 184k | struct attr_symtab_map_data data; |
889 | 184k | int rc; |
890 | | |
891 | 184k | data.d = NULL; |
892 | 184k | data.types = types; |
893 | | |
894 | 184k | local_symtab = d->symtab; |
895 | 184k | root_symtab = &((struct cil_root *)db->ast->root->data)->symtab[CIL_SYM_TYPES]; |
896 | | |
897 | 184k | if (local_symtab != root_symtab) { |
898 | 66.5k | rc = cil_symtab_map(local_symtab, cil_check_attribute_in_symtab, &data); |
899 | 66.5k | if (rc != SEPOL_OK) { |
900 | 0 | return NULL; |
901 | 0 | } |
902 | 66.5k | } |
903 | | |
904 | 184k | if (!data.d) { |
905 | 130k | rc = cil_symtab_map(root_symtab, cil_check_attribute_in_symtab, &data); |
906 | 130k | if (rc != SEPOL_OK) { |
907 | 0 | return NULL; |
908 | 0 | } |
909 | 130k | } |
910 | | |
911 | 184k | return data.d; |
912 | 184k | } |
913 | | |
914 | | static int cil_create_attribute_all_and_not_d(struct cil_db *db, struct cil_symtab_datum *d, struct cil_symtab_datum **d3) |
915 | 20.9k | { |
916 | 20.9k | struct cil_list *str_expr; |
917 | 20.9k | struct cil_list *datum_expr; |
918 | 20.9k | ebitmap_t *types; |
919 | 20.9k | int rc; |
920 | | |
921 | 20.9k | *d3 = NULL; |
922 | | |
923 | 20.9k | if (!d) { |
924 | 0 | return SEPOL_ERR; |
925 | 0 | } |
926 | | |
927 | 20.9k | str_expr = cil_create_andnot_expr_list(CIL_OP, (void *)CIL_ALL, CIL_STRING, d->fqn); |
928 | 20.9k | datum_expr = cil_create_andnot_expr_list(CIL_OP, (void *)CIL_ALL, CIL_DATUM, d); |
929 | | |
930 | 20.9k | types = cil_malloc(sizeof(*types)); |
931 | 20.9k | rc = cil_datum_not(types, d, db->num_types); |
932 | 20.9k | if (rc != SEPOL_OK) { |
933 | 0 | goto exit; |
934 | 0 | } |
935 | | |
936 | 20.9k | if (ebitmap_is_empty(types)) { |
937 | 513 | rc = SEPOL_OK; |
938 | 513 | goto exit; |
939 | 513 | } |
940 | | |
941 | 20.4k | if (ebitmap_cardinality(types) == 1) { |
942 | 195 | unsigned i = ebitmap_highest_set_bit(types); |
943 | 195 | *d3 = DATUM(db->val_to_type[i]); |
944 | 195 | ebitmap_destroy(types); |
945 | 195 | rc = SEPOL_OK; |
946 | 195 | goto exit; |
947 | 195 | } |
948 | | |
949 | 20.2k | *d3 = cil_check_for_previously_defined_attribute(db, types, d); |
950 | 20.2k | if (*d3) { |
951 | 18.7k | ebitmap_destroy(types); |
952 | 18.7k | rc = SEPOL_OK; |
953 | 18.7k | goto exit; |
954 | 18.7k | } |
955 | | |
956 | 1.54k | rc = cil_create_and_insert_attribute_and_set(db, NODE(d), str_expr, datum_expr, types, d3); |
957 | 1.54k | if (rc != SEPOL_OK) { |
958 | 0 | goto exit; |
959 | 0 | } |
960 | | |
961 | 1.54k | return SEPOL_OK; |
962 | | |
963 | 19.4k | exit: |
964 | 19.4k | cil_list_destroy(&str_expr, CIL_FALSE); |
965 | 19.4k | cil_list_destroy(&datum_expr, CIL_FALSE); |
966 | 19.4k | free(types); |
967 | 19.4k | return rc; |
968 | 1.54k | } |
969 | | |
970 | | static int cil_create_attribute_d1_and_not_d2(struct cil_db *db, struct cil_symtab_datum *d1, struct cil_symtab_datum *d2, struct cil_symtab_datum **d3) |
971 | 215k | { |
972 | 215k | struct cil_list *str_expr; |
973 | 215k | struct cil_list *datum_expr; |
974 | 215k | ebitmap_t *types; |
975 | 215k | int rc; |
976 | | |
977 | 215k | if (!d2) { |
978 | 0 | *d3 = d1; |
979 | 0 | return SEPOL_OK; |
980 | 0 | } |
981 | | |
982 | 215k | *d3 = NULL; |
983 | | |
984 | 215k | if (!d1 || d1 == d2) { |
985 | 27.4k | return SEPOL_OK; |
986 | 27.4k | } |
987 | | |
988 | 188k | str_expr = cil_create_andnot_expr_list(CIL_STRING, d1->fqn, CIL_STRING, d2->fqn); |
989 | 188k | datum_expr = cil_create_andnot_expr_list(CIL_DATUM, d1, CIL_DATUM, d2); |
990 | | |
991 | 188k | types = cil_malloc(sizeof(*types)); |
992 | 188k | rc = cil_datums_andnot(types, d1, d2); |
993 | 188k | if (rc != SEPOL_OK) { |
994 | 0 | goto exit; |
995 | 0 | } |
996 | 188k | if (ebitmap_is_empty(types)) { |
997 | 62.9k | rc = SEPOL_OK; |
998 | 62.9k | goto exit; |
999 | 62.9k | } |
1000 | | |
1001 | 125k | if (ebitmap_cardinality(types) == 1) { |
1002 | 14.4k | unsigned i = ebitmap_highest_set_bit(types); |
1003 | 14.4k | *d3 = DATUM(db->val_to_type[i]); |
1004 | 14.4k | ebitmap_destroy(types); |
1005 | 14.4k | rc = SEPOL_OK; |
1006 | 14.4k | goto exit; |
1007 | 14.4k | } |
1008 | | |
1009 | 110k | *d3 = cil_check_for_previously_defined_attribute(db, types, d1); |
1010 | 110k | if (*d3) { |
1011 | 98.4k | ebitmap_destroy(types); |
1012 | 98.4k | rc = SEPOL_OK; |
1013 | 98.4k | goto exit; |
1014 | 98.4k | } |
1015 | | |
1016 | 12.3k | rc = cil_create_and_insert_attribute_and_set(db, NODE(d1), str_expr, datum_expr, types, d3); |
1017 | 12.3k | if (rc != SEPOL_OK) { |
1018 | 0 | goto exit; |
1019 | 0 | } |
1020 | | |
1021 | 12.3k | return SEPOL_OK; |
1022 | | |
1023 | 175k | exit: |
1024 | 175k | cil_list_destroy(&str_expr, CIL_FALSE); |
1025 | 175k | cil_list_destroy(&datum_expr, CIL_FALSE); |
1026 | 175k | free(types); |
1027 | 175k | return rc; |
1028 | 12.3k | } |
1029 | | |
1030 | | static int cil_create_attribute_d1_and_d2(struct cil_db *db, struct cil_symtab_datum *d1, struct cil_symtab_datum *d2, struct cil_symtab_datum **d3) |
1031 | 122k | { |
1032 | 122k | struct cil_list *str_expr; |
1033 | 122k | struct cil_list *datum_expr; |
1034 | 122k | ebitmap_t *types; |
1035 | 122k | int rc; |
1036 | | |
1037 | 122k | if (d1 == d2) { |
1038 | 13.5k | *d3 = d1; |
1039 | 13.5k | return SEPOL_OK; |
1040 | 13.5k | } |
1041 | | |
1042 | 109k | *d3 = NULL; |
1043 | | |
1044 | 109k | if (!d1 || !d2) { |
1045 | 0 | return SEPOL_OK; |
1046 | 0 | } |
1047 | | |
1048 | 109k | str_expr = cil_create_and_expr_list(CIL_STRING, d1->fqn, CIL_STRING, d2->fqn); |
1049 | 109k | datum_expr = cil_create_and_expr_list(CIL_DATUM, d1, CIL_DATUM, d2); |
1050 | | |
1051 | 109k | types = cil_malloc(sizeof(*types)); |
1052 | 109k | rc = cil_datums_and(types, d1, d2); |
1053 | 109k | if (rc != SEPOL_OK) { |
1054 | 0 | goto exit; |
1055 | 0 | } |
1056 | 109k | if (ebitmap_is_empty(types)) { |
1057 | 13.0k | rc = SEPOL_OK; |
1058 | 13.0k | goto exit; |
1059 | 13.0k | } |
1060 | | |
1061 | 95.9k | if (ebitmap_cardinality(types) == 1) { |
1062 | 42.5k | unsigned i = ebitmap_highest_set_bit(types); |
1063 | 42.5k | *d3 = DATUM(db->val_to_type[i]); |
1064 | 42.5k | ebitmap_destroy(types); |
1065 | 42.5k | rc = SEPOL_OK; |
1066 | 42.5k | goto exit; |
1067 | 42.5k | } |
1068 | | |
1069 | 53.3k | *d3 = cil_check_for_previously_defined_attribute(db, types, d1); |
1070 | 53.3k | if (*d3) { |
1071 | 51.2k | ebitmap_destroy(types); |
1072 | 51.2k | rc = SEPOL_OK; |
1073 | 51.2k | goto exit; |
1074 | 51.2k | } |
1075 | | |
1076 | 2.07k | rc = cil_create_and_insert_attribute_and_set(db, NODE(d1), str_expr, datum_expr, types, d3); |
1077 | 2.07k | if (rc != SEPOL_OK) { |
1078 | 0 | goto exit; |
1079 | 0 | } |
1080 | | |
1081 | 2.07k | return SEPOL_OK; |
1082 | | |
1083 | 106k | exit: |
1084 | 106k | cil_list_destroy(&str_expr, CIL_FALSE); |
1085 | 106k | cil_list_destroy(&datum_expr, CIL_FALSE); |
1086 | 106k | free(types); |
1087 | 106k | return rc; |
1088 | 2.07k | } |
1089 | | |
1090 | | static struct cil_avrule *cil_create_avrule(struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms) |
1091 | 137k | { |
1092 | 137k | struct cil_avrule *new; |
1093 | | |
1094 | 137k | cil_avrule_init(&new); |
1095 | 137k | new->is_extended = CIL_FALSE; |
1096 | 137k | new->rule_kind = CIL_AVRULE_ALLOWED; |
1097 | 137k | new->src_str = src->name; |
1098 | 137k | new->src = src; |
1099 | 137k | new->tgt_str = tgt->name; |
1100 | 137k | new->tgt = tgt; |
1101 | 137k | new->perms.classperms = classperms; |
1102 | | |
1103 | 137k | return new; |
1104 | 137k | } |
1105 | | |
1106 | | static struct cil_tree_node *cil_create_and_add_avrule(struct cil_tree_node *curr, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_list *classperms) |
1107 | 246k | { |
1108 | 246k | struct cil_avrule *new_avrule; |
1109 | 246k | struct cil_list *new_cp_list; |
1110 | | |
1111 | 246k | if (!src || !tgt) { |
1112 | 109k | return curr; |
1113 | 109k | } |
1114 | | |
1115 | 137k | cil_classperms_list_copy(&new_cp_list, classperms); |
1116 | 137k | new_avrule = cil_create_avrule(src, tgt, new_cp_list); |
1117 | 137k | return cil_create_and_insert_node(curr, CIL_AVRULE, new_avrule); |
1118 | 246k | } |
1119 | | |
1120 | | static int cil_remove_permissions_from_special_rule(struct cil_db *db, struct cil_tree_node *curr, struct cil_symtab_datum *s1, struct cil_symtab_datum *t1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2, struct cil_list *p4, struct cil_symtab_datum *s3, struct cil_symtab_datum *s4) |
1121 | 33.6k | { |
1122 | 33.6k | int rc; |
1123 | | |
1124 | 33.6k | if (t1 == DATUM(db->notselftype)) { |
1125 | 20.9k | if (t2 == DATUM(db->othertype)) { |
1126 | 7.91k | struct cil_symtab_datum *t; |
1127 | 7.91k | rc = cil_create_attribute_all_and_not_d(db, s2, &t); |
1128 | 7.91k | if (rc != SEPOL_OK) { |
1129 | 0 | goto exit; |
1130 | 0 | } |
1131 | 7.91k | curr = cil_create_and_add_avrule(curr, s4, t, p4); |
1132 | 13.0k | } else { |
1133 | 13.0k | struct cil_symtab_datum *s5, *s6, *ta, *tb; |
1134 | 13.0k | rc = cil_create_attribute_d1_and_not_d2(db, s4, t2, &s5); |
1135 | 13.0k | if (rc != SEPOL_OK) { |
1136 | 0 | goto exit; |
1137 | 0 | } |
1138 | 13.0k | rc = cil_create_attribute_d1_and_d2(db, s4, t2, &s6); |
1139 | 13.0k | if (rc != SEPOL_OK) { |
1140 | 0 | goto exit; |
1141 | 0 | } |
1142 | 13.0k | rc = cil_create_attribute_all_and_not_d(db, t2, &ta); |
1143 | 13.0k | if (rc != SEPOL_OK) { |
1144 | 0 | goto exit; |
1145 | 0 | } |
1146 | 13.0k | rc = cil_create_attribute_d1_and_not_d2(db, ta, s4, &tb); |
1147 | 13.0k | if (rc != SEPOL_OK) { |
1148 | 0 | goto exit; |
1149 | 0 | } |
1150 | 13.0k | curr = cil_create_and_add_avrule(curr, s6, ta, p4); |
1151 | 13.0k | curr = cil_create_and_add_avrule(curr, s5, tb, p4); |
1152 | 13.0k | if (cil_datum_cardinality(s5) > 1) { |
1153 | 4.75k | curr = cil_create_and_add_avrule(curr, s5, DATUM(db->othertype), p4); |
1154 | 4.75k | } |
1155 | 13.0k | } |
1156 | 20.9k | } else if (t1 == DATUM(db->othertype)) { |
1157 | 10.2k | curr = cil_create_and_add_avrule(curr, s3, s4, p4); |
1158 | 10.2k | if (t2 == DATUM(db->notselftype)) { |
1159 | | /* Nothing else is needed */ |
1160 | 9.62k | } else if (t2 == DATUM(db->othertype)) { |
1161 | 3.66k | curr = cil_create_and_add_avrule(curr, s4, s3, p4); |
1162 | 5.95k | } else { |
1163 | 5.95k | struct cil_symtab_datum *s5, *s6, *tc, *td; |
1164 | 5.95k | rc = cil_create_attribute_d1_and_not_d2(db, s4, t2, &s5); |
1165 | 5.95k | if (rc != SEPOL_OK) { |
1166 | 0 | goto exit; |
1167 | 0 | } |
1168 | 5.95k | rc = cil_create_attribute_d1_and_d2(db, s4, t2, &s6); |
1169 | 5.95k | if (rc != SEPOL_OK) { |
1170 | 0 | goto exit; |
1171 | 0 | } |
1172 | 5.95k | rc = cil_create_attribute_d1_and_not_d2(db, s1, t2, &tc); |
1173 | 5.95k | if (rc != SEPOL_OK) { |
1174 | 0 | goto exit; |
1175 | 0 | } |
1176 | 5.95k | rc = cil_create_attribute_d1_and_not_d2(db, s3, t2, &td); |
1177 | 5.95k | if (rc != SEPOL_OK) { |
1178 | 0 | goto exit; |
1179 | 0 | } |
1180 | 5.95k | curr = cil_create_and_add_avrule(curr, s6, tc, p4); |
1181 | 5.95k | curr = cil_create_and_add_avrule(curr, s5, td, p4); |
1182 | 5.95k | if (cil_datum_cardinality(s5) > 1) { |
1183 | 3.78k | curr = cil_create_and_add_avrule(curr, s5, DATUM(db->othertype), p4); |
1184 | 3.78k | } |
1185 | 5.95k | } |
1186 | 10.2k | } else { |
1187 | 2.43k | struct cil_symtab_datum *s8; |
1188 | 2.43k | rc = cil_create_attribute_d1_and_d2(db, s4, t1, &s8); |
1189 | 2.43k | if (rc != SEPOL_OK) { |
1190 | 0 | goto exit; |
1191 | 0 | } |
1192 | 2.43k | curr = cil_create_and_add_avrule(curr, s8, DATUM(db->selftype), p4); |
1193 | 2.43k | if (t2 == DATUM(db->notselftype)) { |
1194 | | /* Nothing else is needed */ |
1195 | 1.34k | } else { /* t2 == DATUM(db->othertype) */ |
1196 | 1.34k | struct cil_symtab_datum *t; |
1197 | 1.34k | rc = cil_create_attribute_d1_and_not_d2(db, t1, s2, &t); |
1198 | 1.34k | if (rc != SEPOL_OK) { |
1199 | 0 | goto exit; |
1200 | 0 | } |
1201 | 1.34k | curr = cil_create_and_add_avrule(curr, s4, t, p4); |
1202 | 1.34k | } |
1203 | 2.43k | } |
1204 | 33.6k | return SEPOL_OK; |
1205 | | |
1206 | 0 | exit: |
1207 | 0 | return rc; |
1208 | 33.6k | } |
1209 | | |
1210 | | static int cil_remove_permissions_from_rule(struct cil_db *db, struct cil_tree_node *allow_node, const struct cil_tree_node *deny_node) |
1211 | 102k | { |
1212 | 102k | struct cil_avrule *allow_rule = allow_node->data; |
1213 | 102k | struct cil_deny_rule *deny_rule = deny_node->data; |
1214 | 102k | struct cil_symtab_datum *s1 = allow_rule->src; |
1215 | 102k | struct cil_symtab_datum *t1 = allow_rule->tgt; |
1216 | 102k | struct cil_list *p1 = allow_rule->perms.classperms; |
1217 | 102k | struct cil_symtab_datum *s2 = deny_rule->src; |
1218 | 102k | struct cil_symtab_datum *t2 = deny_rule->tgt; |
1219 | 102k | struct cil_list *p2 = deny_rule->classperms; |
1220 | 102k | struct cil_list *p3 = NULL; |
1221 | 102k | struct cil_list *p4 = NULL; |
1222 | 102k | struct cil_symtab_datum *s3, *s4; |
1223 | 102k | struct cil_tree_node *curr = allow_node; |
1224 | 102k | int rc; |
1225 | | |
1226 | 102k | cil_classperms_list_andnot(&p3, p1, p2); |
1227 | 102k | if (!cil_list_is_empty(p3)) {; |
1228 | 4.21k | curr = cil_create_and_add_avrule(curr, s1, t1, p3); |
1229 | 4.21k | } |
1230 | 102k | cil_destroy_classperms_list(&p3); |
1231 | 102k | p3 = NULL; |
1232 | | |
1233 | 102k | cil_classperms_list_and(&p4, p1, p2); |
1234 | 102k | if (cil_list_is_empty(p4)) { |
1235 | 0 | cil_tree_log(allow_node, CIL_ERR, "Allow rule did not match deny rule: No matching class and permissions"); |
1236 | 0 | cil_tree_log((struct cil_tree_node *)deny_node, CIL_ERR, "Deny rule"); |
1237 | 0 | rc = SEPOL_ERR; |
1238 | 0 | goto exit; |
1239 | 0 | } |
1240 | | |
1241 | 102k | rc = cil_create_attribute_d1_and_not_d2(db, s1, s2, &s3); |
1242 | 102k | if (rc != SEPOL_OK) { |
1243 | 0 | goto exit; |
1244 | 0 | } |
1245 | 102k | curr = cil_create_and_add_avrule(curr, s3, t1, p4); |
1246 | | |
1247 | 102k | if ((t1 == DATUM(db->selftype) && t2 == DATUM(db->selftype)) || |
1248 | 101k | (t1 == DATUM(db->notselftype) && t2 == DATUM(db->notselftype))) { |
1249 | | /* Nothing more needs to be done */ |
1250 | 2.26k | rc = SEPOL_OK; |
1251 | 2.26k | goto exit; |
1252 | 2.26k | } |
1253 | | |
1254 | 100k | rc = cil_create_attribute_d1_and_d2(db, s1, s2, &s4); |
1255 | 100k | if (rc != SEPOL_OK) { |
1256 | 0 | goto exit; |
1257 | 0 | } |
1258 | | |
1259 | 100k | if (t1 == DATUM(db->notselftype) || t1 == DATUM(db->othertype) || |
1260 | 69.3k | t2 == DATUM(db->notselftype) || t2 == DATUM(db->othertype)) { |
1261 | 33.6k | rc = cil_remove_permissions_from_special_rule(db, curr, s1, t1, s2, t2, p4, s3, s4); |
1262 | 33.6k | goto exit; |
1263 | 33.6k | } |
1264 | | |
1265 | 66.9k | if (t1 == DATUM(db->selftype) && t2 != DATUM(db->selftype)) { |
1266 | 581 | struct cil_symtab_datum *s5; |
1267 | 581 | rc = cil_create_attribute_d1_and_not_d2(db, s4, t2, &s5); |
1268 | 581 | if (rc != SEPOL_OK) { |
1269 | 0 | goto exit; |
1270 | 0 | } |
1271 | 581 | curr = cil_create_and_add_avrule(curr, s5, DATUM(db->selftype), p4); |
1272 | 66.3k | } else if (t1 != DATUM(db->selftype) && t2 == DATUM(db->selftype)) { |
1273 | 505 | struct cil_symtab_datum *s7, *s8, *t8; |
1274 | 505 | rc = cil_create_attribute_d1_and_not_d2(db, s4, t1, &s7); |
1275 | 505 | if (rc != SEPOL_OK) { |
1276 | 0 | goto exit; |
1277 | 0 | } |
1278 | 505 | rc = cil_create_attribute_d1_and_d2(db, s4, t1, &s8); |
1279 | 505 | if (rc != SEPOL_OK) { |
1280 | 0 | goto exit; |
1281 | 0 | } |
1282 | 505 | rc = cil_create_attribute_d1_and_not_d2(db, t1, s4, &t8); |
1283 | 505 | if (rc != SEPOL_OK) { |
1284 | 0 | goto exit; |
1285 | 0 | } |
1286 | 505 | curr = cil_create_and_add_avrule(curr, s7, t1, p4); |
1287 | 505 | curr = cil_create_and_add_avrule(curr, s8, t8, p4); |
1288 | 505 | if (cil_datum_cardinality(s8) > 1) { |
1289 | 231 | curr = cil_create_and_add_avrule(curr, s8, DATUM(db->othertype), p4); |
1290 | 231 | } |
1291 | 65.8k | } else { |
1292 | 65.8k | struct cil_symtab_datum *t3; |
1293 | 65.8k | rc = cil_create_attribute_d1_and_not_d2(db, t1, t2, &t3); |
1294 | 65.8k | if (rc != SEPOL_OK) { |
1295 | 0 | goto exit; |
1296 | 0 | } |
1297 | 65.8k | curr = cil_create_and_add_avrule(curr, s4, t3, p4); |
1298 | 65.8k | } |
1299 | | |
1300 | 102k | exit: |
1301 | 102k | if (p4) { |
1302 | 102k | cil_destroy_classperms_list(&p4); |
1303 | 102k | } |
1304 | 102k | return rc; |
1305 | 66.9k | } |
1306 | | |
1307 | | static int cil_find_matching_allow_rules(struct cil_list *matching, struct cil_tree_node *start, struct cil_tree_node *deny_node) |
1308 | 28.0k | { |
1309 | 28.0k | struct cil_deny_rule *deny_rule = deny_node->data; |
1310 | 28.0k | struct cil_avrule target; |
1311 | | |
1312 | 28.0k | target.rule_kind = CIL_AVRULE_ALLOWED; |
1313 | 28.0k | target.is_extended = CIL_FALSE; |
1314 | 28.0k | target.src = deny_rule->src; |
1315 | 28.0k | target.tgt = deny_rule->tgt; |
1316 | 28.0k | target.perms.classperms = deny_rule->classperms; |
1317 | | |
1318 | 28.0k | return cil_find_matching_avrule_in_ast(start, CIL_AVRULE, &target, matching, CIL_FALSE); |
1319 | 28.0k | } |
1320 | | |
1321 | | static int cil_process_deny_rule(struct cil_db *db, struct cil_tree_node *start, struct cil_tree_node *deny_node) |
1322 | 28.0k | { |
1323 | 28.0k | struct cil_list *matching; |
1324 | 28.0k | struct cil_list_item *item; |
1325 | 28.0k | int rc; |
1326 | | |
1327 | 28.0k | cil_list_init(&matching, CIL_NODE); |
1328 | | |
1329 | 28.0k | rc = cil_find_matching_allow_rules(matching, start, deny_node); |
1330 | 28.0k | if (rc != SEPOL_OK) { |
1331 | 0 | goto exit; |
1332 | 0 | } |
1333 | | |
1334 | 102k | cil_list_for_each(item, matching) { |
1335 | 102k | struct cil_tree_node *allow_node = item->data; |
1336 | 102k | rc = cil_remove_permissions_from_rule(db, allow_node, deny_node); |
1337 | 102k | cil_tree_node_remove(allow_node); |
1338 | 102k | if (rc != SEPOL_OK) { |
1339 | 0 | goto exit; |
1340 | 0 | } |
1341 | | |
1342 | 102k | } |
1343 | | |
1344 | 28.0k | exit: |
1345 | 28.0k | cil_list_destroy(&matching, CIL_FALSE); |
1346 | 28.0k | return rc; |
1347 | 28.0k | } |
1348 | | |
1349 | | static int cil_process_deny_rules(struct cil_db *db, struct cil_tree_node *start, struct cil_list *deny_rules) |
1350 | 5.41k | { |
1351 | 5.41k | struct cil_list_item *item; |
1352 | 5.41k | int rc = SEPOL_OK; |
1353 | | |
1354 | 28.0k | cil_list_for_each(item, deny_rules) { |
1355 | 28.0k | struct cil_tree_node *deny_node = item->data; |
1356 | 28.0k | rc = cil_process_deny_rule(db, start, deny_node); |
1357 | 28.0k | if (rc != SEPOL_OK) { |
1358 | 0 | goto exit; |
1359 | 0 | } |
1360 | 28.0k | cil_tree_node_remove(deny_node); |
1361 | 28.0k | } |
1362 | | |
1363 | 5.41k | exit: |
1364 | 5.41k | return rc; |
1365 | 5.41k | } |
1366 | | |
1367 | | static int __cil_find_deny_rules(struct cil_tree_node *node, uint32_t *finished, void *extra_args) |
1368 | 3.46M | { |
1369 | 3.46M | struct cil_list *deny_rules = extra_args; |
1370 | | |
1371 | 3.46M | if (node->flavor == CIL_BLOCK) { |
1372 | 365k | struct cil_block *block = node->data; |
1373 | 365k | if (block->is_abstract == CIL_TRUE) { |
1374 | 520 | *finished = CIL_TREE_SKIP_HEAD; |
1375 | 520 | } |
1376 | 3.09M | } else if (node->flavor == CIL_MACRO) { |
1377 | 10.7k | *finished = CIL_TREE_SKIP_HEAD; |
1378 | 3.08M | } else if (node->flavor == CIL_DENY_RULE) { |
1379 | 28.0k | cil_list_append(deny_rules, CIL_DENY_RULE, node); |
1380 | 28.0k | } |
1381 | 3.46M | return SEPOL_OK; |
1382 | 3.46M | } |
1383 | | |
1384 | | int cil_process_deny_rules_in_ast(struct cil_db *db) |
1385 | 5.41k | { |
1386 | 5.41k | struct cil_tree_node *start; |
1387 | 5.41k | struct cil_list *deny_rules; |
1388 | 5.41k | int rc = SEPOL_ERR; |
1389 | | |
1390 | 5.41k | cil_list_init(&deny_rules, CIL_DENY_RULE); |
1391 | | |
1392 | 5.41k | if (!db) { |
1393 | 0 | cil_log(CIL_ERR, "No CIL db provided to process deny rules\n"); |
1394 | 0 | goto exit; |
1395 | 0 | } |
1396 | | |
1397 | 5.41k | start = db->ast->root; |
1398 | 5.41k | rc = cil_tree_walk(start, __cil_find_deny_rules, NULL, NULL, deny_rules); |
1399 | 5.41k | if (rc != SEPOL_OK) { |
1400 | 0 | cil_log(CIL_ERR, "An error occurred while getting deny rules\n"); |
1401 | 0 | goto exit; |
1402 | 0 | } |
1403 | | |
1404 | 5.41k | rc = cil_process_deny_rules(db, start, deny_rules); |
1405 | 5.41k | if (rc != SEPOL_OK) { |
1406 | 0 | cil_log(CIL_ERR, "An error occurred while processing deny rules\n"); |
1407 | 0 | goto exit; |
1408 | 0 | } |
1409 | | |
1410 | 5.41k | exit: |
1411 | 5.41k | cil_list_destroy(&deny_rules, CIL_FALSE); |
1412 | 5.41k | return rc; |
1413 | 5.41k | } |