1 /* Authors: Joshua Brindle <jbrindle@tresys.com>
2 *
3 * Assertion checker for avtab entries, taken from
4 * checkpolicy.c by Stephen Smalley <stephen.smalley.work@gmail.com>
5 *
6 * Copyright (C) 2005 Tresys Technology, LLC
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <sepol/policydb/avtab.h>
24 #include <sepol/policydb/policydb.h>
25 #include <sepol/policydb/expand.h>
26 #include <sepol/policydb/util.h>
27
28 #include "private.h"
29 #include "debug.h"
30
31 struct avtab_match_args {
32 sepol_handle_t *handle;
33 policydb_t *p;
34 avrule_t *avrule;
35 avtab_t *avtab;
36 unsigned long errors;
37 };
38
policy_name(policydb_t * p)39 static const char* policy_name(policydb_t *p) {
40 const char *policy_file = "policy.conf";
41 if (p->name) {
42 policy_file = p->name;
43 }
44 return policy_file;
45 }
46
report_failure(sepol_handle_t * handle,policydb_t * p,const avrule_t * avrule,unsigned int stype,unsigned int ttype,const class_perm_node_t * curperm,uint32_t perms)47 static void report_failure(sepol_handle_t *handle, policydb_t *p, const avrule_t *avrule,
48 unsigned int stype, unsigned int ttype,
49 const class_perm_node_t *curperm, uint32_t perms)
50 {
51 char *permstr = sepol_av_to_string(p, curperm->tclass, perms);
52
53 if (avrule->source_filename) {
54 ERR(handle, "neverallow on line %lu of %s (or line %lu of %s) violated by allow %s %s:%s {%s };",
55 avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
56 p->p_type_val_to_name[stype],
57 p->p_type_val_to_name[ttype],
58 p->p_class_val_to_name[curperm->tclass - 1],
59 permstr ?: "<format-failure>");
60 } else if (avrule->line) {
61 ERR(handle, "neverallow on line %lu violated by allow %s %s:%s {%s };",
62 avrule->line, p->p_type_val_to_name[stype],
63 p->p_type_val_to_name[ttype],
64 p->p_class_val_to_name[curperm->tclass - 1],
65 permstr ?: "<format-failure>");
66 } else {
67 ERR(handle, "neverallow violated by allow %s %s:%s {%s };",
68 p->p_type_val_to_name[stype],
69 p->p_type_val_to_name[ttype],
70 p->p_class_val_to_name[curperm->tclass - 1],
71 permstr ?: "<format-failure>");
72 }
73
74 free(permstr);
75 }
76
match_any_class_permissions(class_perm_node_t * cp,uint32_t class,uint32_t data)77 static int match_any_class_permissions(class_perm_node_t *cp, uint32_t class, uint32_t data)
78 {
79 for (; cp; cp = cp->next) {
80 if ((cp->tclass == class) && (cp->data & data))
81 return 1;
82 }
83
84 return 0;
85 }
86
extended_permissions_and(uint32_t * perms1,uint32_t * perms2)87 static int extended_permissions_and(uint32_t *perms1, uint32_t *perms2) {
88 size_t i;
89 for (i = 0; i < EXTENDED_PERMS_LEN; i++) {
90 if (perms1[i] & perms2[i])
91 return 1;
92 }
93
94 return 0;
95 }
96
check_extended_permissions(av_extended_perms_t * neverallow,avtab_extended_perms_t * allow)97 static int check_extended_permissions(av_extended_perms_t *neverallow, avtab_extended_perms_t *allow)
98 {
99 int rc = 0;
100 if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
101 && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
102 if (neverallow->driver == allow->driver)
103 rc = extended_permissions_and(neverallow->perms, allow->perms);
104 } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
105 && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
106 rc = xperm_test(neverallow->driver, allow->perms);
107 } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
108 && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
109 rc = xperm_test(allow->driver, neverallow->perms);
110 } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
111 && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
112 rc = extended_permissions_and(neverallow->perms, allow->perms);
113 }
114
115 return rc;
116 }
117
118 /* Compute which allowed extended permissions violate the neverallow rule */
extended_permissions_violated(avtab_extended_perms_t * result,av_extended_perms_t * neverallow,avtab_extended_perms_t * allow)119 static void extended_permissions_violated(avtab_extended_perms_t *result,
120 av_extended_perms_t *neverallow,
121 avtab_extended_perms_t *allow)
122 {
123 size_t i;
124 if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
125 && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
126 result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
127 result->driver = allow->driver;
128 for (i = 0; i < EXTENDED_PERMS_LEN; i++)
129 result->perms[i] = neverallow->perms[i] & allow->perms[i];
130 } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
131 && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
132 result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
133 result->driver = neverallow->driver;
134 memcpy(result->perms, neverallow->perms, sizeof(result->perms));
135 } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
136 && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
137 result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
138 result->driver = allow->driver;
139 memcpy(result->perms, allow->perms, sizeof(result->perms));
140 } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
141 && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
142 result->specified = AVTAB_XPERMS_IOCTLDRIVER;
143 for (i = 0; i < EXTENDED_PERMS_LEN; i++)
144 result->perms[i] = neverallow->perms[i] & allow->perms[i];
145 }
146 }
147
148 /* Same scenarios of interest as check_assertion_extended_permissions */
report_assertion_extended_permissions(sepol_handle_t * handle,policydb_t * p,const avrule_t * avrule,unsigned int stype,unsigned int ttype,const class_perm_node_t * curperm,uint32_t perms,avtab_key_t * k,avtab_t * avtab)149 static int report_assertion_extended_permissions(sepol_handle_t *handle,
150 policydb_t *p, const avrule_t *avrule,
151 unsigned int stype, unsigned int ttype,
152 const class_perm_node_t *curperm, uint32_t perms,
153 avtab_key_t *k, avtab_t *avtab)
154 {
155 avtab_ptr_t node;
156 avtab_key_t tmp_key;
157 avtab_extended_perms_t *xperms;
158 avtab_extended_perms_t error;
159 ebitmap_t *sattr = &p->type_attr_map[stype];
160 ebitmap_t *tattr = &p->type_attr_map[ttype];
161 ebitmap_node_t *snode, *tnode;
162 unsigned int i, j;
163 int rc;
164 int found_xperm = 0;
165 int errors = 0;
166
167 memcpy(&tmp_key, k, sizeof(avtab_key_t));
168 tmp_key.specified = AVTAB_XPERMS_ALLOWED;
169
170 ebitmap_for_each_positive_bit(sattr, snode, i) {
171 tmp_key.source_type = i + 1;
172 ebitmap_for_each_positive_bit(tattr, tnode, j) {
173 tmp_key.target_type = j + 1;
174 for (node = avtab_search_node(avtab, &tmp_key);
175 node;
176 node = avtab_search_node_next(node, tmp_key.specified)) {
177 xperms = node->datum.xperms;
178 if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
179 && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
180 continue;
181 found_xperm = 1;
182 rc = check_extended_permissions(avrule->xperms, xperms);
183 /* failure on the extended permission check_extended_permissions */
184 if (rc) {
185 char *permstring;
186
187 extended_permissions_violated(&error, avrule->xperms, xperms);
188 permstring = sepol_extended_perms_to_string(&error);
189
190 ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
191 "allowxperm %s %s:%s %s;",
192 avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
193 p->p_type_val_to_name[i],
194 p->p_type_val_to_name[j],
195 p->p_class_val_to_name[curperm->tclass - 1],
196 permstring ?: "<format-failure>");
197
198 free(permstring);
199 errors++;
200 }
201 }
202 }
203 }
204
205 /* failure on the regular permissions */
206 if (!found_xperm) {
207 char *permstr = sepol_av_to_string(p, curperm->tclass, perms);
208
209 ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
210 "allow %s %s:%s {%s };",
211 avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
212 p->p_type_val_to_name[stype],
213 p->p_type_val_to_name[ttype],
214 p->p_class_val_to_name[curperm->tclass - 1],
215 permstr ?: "<format-failure>");
216
217 free(permstr);
218 errors++;
219
220 }
221
222 return errors;
223 }
224
report_assertion_avtab_matches(avtab_key_t * k,avtab_datum_t * d,void * args)225 static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void *args)
226 {
227 int rc = 0;
228 struct avtab_match_args *a = (struct avtab_match_args *)args;
229 sepol_handle_t *handle = a->handle;
230 policydb_t *p = a->p;
231 avtab_t *avtab = a->avtab;
232 avrule_t *avrule = a->avrule;
233 class_perm_node_t *cp;
234 uint32_t perms;
235 ebitmap_t src_matches, tgt_matches, self_matches;
236 ebitmap_node_t *snode, *tnode;
237 unsigned int i, j;
238 const int is_avrule_self = (avrule->flags & RULE_SELF) != 0;
239 const int is_avrule_notself = (avrule->flags & RULE_NOTSELF) != 0;
240
241 if ((k->specified & AVTAB_ALLOWED) == 0)
242 return 0;
243
244 if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
245 return 0;
246
247 ebitmap_init(&src_matches);
248 ebitmap_init(&tgt_matches);
249 ebitmap_init(&self_matches);
250
251 rc = ebitmap_and(&src_matches, &avrule->stypes.types,
252 &p->attr_type_map[k->source_type - 1]);
253 if (rc < 0)
254 goto oom;
255
256 if (ebitmap_is_empty(&src_matches))
257 goto exit;
258
259 if (is_avrule_notself) {
260 if (ebitmap_is_empty(&avrule->ttypes.types)) {
261 /* avrule tgt is of the form ~self */
262 rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type -1]);
263 } else {
264 /* avrule tgt is of the form {ATTR -self} */
265 rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type - 1]);
266 }
267 if (rc)
268 goto oom;
269 } else {
270 rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]);
271 if (rc < 0)
272 goto oom;
273
274 if (is_avrule_self) {
275 rc = ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]);
276 if (rc < 0)
277 goto oom;
278
279 if (!ebitmap_is_empty(&self_matches)) {
280 rc = ebitmap_union(&tgt_matches, &self_matches);
281 if (rc < 0)
282 goto oom;
283 }
284 }
285 }
286
287 if (ebitmap_is_empty(&tgt_matches))
288 goto exit;
289
290 for (cp = avrule->perms; cp; cp = cp->next) {
291
292 perms = cp->data & d->data;
293 if ((cp->tclass != k->target_class) || !perms) {
294 continue;
295 }
296
297 ebitmap_for_each_positive_bit(&src_matches, snode, i) {
298 ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) {
299 if (is_avrule_self && i != j)
300 continue;
301 if (is_avrule_notself && i == j)
302 continue;
303 if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
304 a->errors += report_assertion_extended_permissions(handle,p, avrule,
305 i, j, cp, perms, k, avtab);
306 } else {
307 a->errors++;
308 report_failure(handle, p, avrule, i, j, cp, perms);
309 }
310 }
311 }
312 }
313
314 oom:
315 exit:
316 ebitmap_destroy(&src_matches);
317 ebitmap_destroy(&tgt_matches);
318 ebitmap_destroy(&self_matches);
319 return rc;
320 }
321
report_assertion_failures(sepol_handle_t * handle,policydb_t * p,avrule_t * avrule)322 static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule)
323 {
324 int rc;
325 struct avtab_match_args args;
326
327 args.handle = handle;
328 args.p = p;
329 args.avrule = avrule;
330 args.errors = 0;
331
332 args.avtab = &p->te_avtab;
333 rc = avtab_map(&p->te_avtab, report_assertion_avtab_matches, &args);
334 if (rc < 0)
335 goto oom;
336
337 args.avtab = &p->te_cond_avtab;
338 rc = avtab_map(&p->te_cond_avtab, report_assertion_avtab_matches, &args);
339 if (rc < 0)
340 goto oom;
341
342 return args.errors;
343
344 oom:
345 return rc;
346 }
347
348 /*
349 * Look up the extended permissions in avtab and verify that neverallowed
350 * permissions are not granted.
351 */
check_assertion_extended_permissions_avtab(avrule_t * avrule,avtab_t * avtab,unsigned int stype,unsigned int ttype,avtab_key_t * k,policydb_t * p)352 static int check_assertion_extended_permissions_avtab(avrule_t *avrule, avtab_t *avtab,
353 unsigned int stype, unsigned int ttype,
354 avtab_key_t *k, policydb_t *p)
355 {
356 avtab_ptr_t node;
357 avtab_key_t tmp_key;
358 avtab_extended_perms_t *xperms;
359 av_extended_perms_t *neverallow_xperms = avrule->xperms;
360 ebitmap_t *sattr = &p->type_attr_map[stype];
361 ebitmap_t *tattr = &p->type_attr_map[ttype];
362 ebitmap_node_t *snode, *tnode;
363 unsigned int i, j;
364 int rc = 1;
365
366 memcpy(&tmp_key, k, sizeof(avtab_key_t));
367 tmp_key.specified = AVTAB_XPERMS_ALLOWED;
368
369 ebitmap_for_each_positive_bit(sattr, snode, i) {
370 tmp_key.source_type = i + 1;
371 ebitmap_for_each_positive_bit(tattr, tnode, j) {
372 tmp_key.target_type = j + 1;
373 for (node = avtab_search_node(avtab, &tmp_key);
374 node;
375 node = avtab_search_node_next(node, tmp_key.specified)) {
376 xperms = node->datum.xperms;
377
378 if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
379 && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
380 continue;
381 rc = check_extended_permissions(neverallow_xperms, xperms);
382 if (rc)
383 return rc;
384 }
385 }
386 }
387
388 return rc;
389 }
390
391 /*
392 * When the ioctl permission is granted on an avtab entry that matches an
393 * avrule neverallowxperm entry, enumerate over the matching
394 * source/target/class sets to determine if the extended permissions exist
395 * and if the neverallowed ioctls are granted.
396 *
397 * Four scenarios of interest:
398 * 1. PASS - the ioctl permission is not granted for this source/target/class
399 * This case is handled in check_assertion_avtab_match
400 * 2. PASS - The ioctl permission is granted AND the extended permission
401 * is NOT granted
402 * 3. FAIL - The ioctl permission is granted AND no extended permissions
403 * exist
404 * 4. FAIL - The ioctl permission is granted AND the extended permission is
405 * granted
406 */
check_assertion_extended_permissions(avrule_t * avrule,avtab_t * avtab,avtab_key_t * k,policydb_t * p)407 static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab,
408 avtab_key_t *k, policydb_t *p)
409 {
410 ebitmap_t src_matches, tgt_matches, self_matches;
411 unsigned int i, j;
412 ebitmap_node_t *snode, *tnode;
413 const int is_avrule_self = (avrule->flags & RULE_SELF) != 0;
414 const int is_avrule_notself = (avrule->flags & RULE_NOTSELF) != 0;
415 int rc;
416
417 ebitmap_init(&src_matches);
418 ebitmap_init(&tgt_matches);
419 ebitmap_init(&self_matches);
420
421 rc = ebitmap_and(&src_matches, &avrule->stypes.types,
422 &p->attr_type_map[k->source_type - 1]);
423 if (rc < 0)
424 goto oom;
425
426 if (ebitmap_is_empty(&src_matches)) {
427 rc = 0;
428 goto exit;
429 }
430
431 if (is_avrule_notself) {
432 if (ebitmap_is_empty(&avrule->ttypes.types)) {
433 /* avrule tgt is of the form ~self */
434 rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type -1]);
435 } else {
436 /* avrule tgt is of the form {ATTR -self} */
437 rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type - 1]);
438 }
439 if (rc < 0)
440 goto oom;
441 } else {
442 rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]);
443 if (rc < 0)
444 goto oom;
445
446 if (is_avrule_self) {
447 rc = ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]);
448 if (rc < 0)
449 goto oom;
450
451 if (!ebitmap_is_empty(&self_matches)) {
452 rc = ebitmap_union(&tgt_matches, &self_matches);
453 if (rc < 0)
454 goto oom;
455 }
456 }
457 }
458
459 if (ebitmap_is_empty(&tgt_matches)) {
460 rc = 0;
461 goto exit;
462 }
463
464 ebitmap_for_each_positive_bit(&src_matches, snode, i) {
465 ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) {
466 if (is_avrule_self && i != j)
467 continue;
468 if (is_avrule_notself && i == j)
469 continue;
470 if (check_assertion_extended_permissions_avtab(avrule, avtab, i, j, k, p)) {
471 rc = 1;
472 goto exit;
473 }
474 }
475 }
476
477 rc = 0;
478
479 oom:
480 exit:
481 ebitmap_destroy(&src_matches);
482 ebitmap_destroy(&tgt_matches);
483 ebitmap_destroy(&self_matches);
484 return rc;
485 }
486
check_assertion_notself_match(avtab_key_t * k,avrule_t * avrule,policydb_t * p)487 static int check_assertion_notself_match(avtab_key_t *k, avrule_t *avrule, policydb_t *p)
488 {
489 ebitmap_t src_matches, tgt_matches;
490 unsigned int num_src_matches, num_tgt_matches;
491 int rc;
492
493 ebitmap_init(&src_matches);
494 ebitmap_init(&tgt_matches);
495
496 rc = ebitmap_and(&src_matches, &avrule->stypes.types, &p->attr_type_map[k->source_type - 1]);
497 if (rc < 0)
498 goto oom;
499
500 if (ebitmap_is_empty(&avrule->ttypes.types)) {
501 /* avrule tgt is of the form ~self */
502 rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type - 1]);
503 } else {
504 /* avrule tgt is of the form {ATTR -self} */
505 rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type - 1]);
506 }
507 if (rc < 0)
508 goto oom;
509
510 num_src_matches = ebitmap_cardinality(&src_matches);
511 num_tgt_matches = ebitmap_cardinality(&tgt_matches);
512 if (num_src_matches == 0 || num_tgt_matches == 0) {
513 rc = 0;
514 goto nomatch;
515 }
516 if (num_src_matches == 1 && num_tgt_matches == 1) {
517 ebitmap_t matches;
518 unsigned int num_matches;
519 rc = ebitmap_and(&matches, &src_matches, &tgt_matches);
520 if (rc < 0) {
521 ebitmap_destroy(&matches);
522 goto oom;
523 }
524 num_matches = ebitmap_cardinality(&matches);
525 ebitmap_destroy(&matches);
526 if (num_matches == 1) {
527 /* The only non-match is of the form TYPE TYPE */
528 rc = 0;
529 goto nomatch;
530 }
531 }
532
533 rc = 1;
534
535 oom:
536 nomatch:
537 ebitmap_destroy(&src_matches);
538 ebitmap_destroy(&tgt_matches);
539 return rc;
540 }
541
check_assertion_self_match(avtab_key_t * k,avrule_t * avrule,policydb_t * p)542 static int check_assertion_self_match(avtab_key_t *k, avrule_t *avrule, policydb_t *p)
543 {
544 ebitmap_t src_matches;
545 int rc;
546
547 /* The key's target must match something in the matches of the avrule's source
548 * and the key's source.
549 */
550
551 rc = ebitmap_and(&src_matches, &avrule->stypes.types, &p->attr_type_map[k->source_type - 1]);
552 if (rc < 0)
553 goto oom;
554
555 if (!ebitmap_match_any(&src_matches, &p->attr_type_map[k->target_type - 1])) {
556 rc = 0;
557 goto nomatch;
558 }
559
560 rc = 1;
561
562 oom:
563 nomatch:
564 ebitmap_destroy(&src_matches);
565 return rc;
566 }
567
check_assertion_avtab_match(avtab_key_t * k,avtab_datum_t * d,void * args)568 static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *args)
569 {
570 int rc;
571 struct avtab_match_args *a = (struct avtab_match_args *)args;
572 policydb_t *p = a->p;
573 avrule_t *avrule = a->avrule;
574 avtab_t *avtab = a->avtab;
575
576 if ((k->specified & AVTAB_ALLOWED) == 0)
577 goto nomatch;
578
579 if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
580 goto nomatch;
581
582 if (!ebitmap_match_any(&avrule->stypes.types, &p->attr_type_map[k->source_type - 1]))
583 goto nomatch;
584
585 if (avrule->flags & RULE_NOTSELF) {
586 rc = check_assertion_notself_match(k, avrule, p);
587 if (rc < 0)
588 goto oom;
589 if (rc == 0)
590 goto nomatch;
591 } else {
592 /* neverallow may have tgts even if it uses SELF */
593 if (!ebitmap_match_any(&avrule->ttypes.types, &p->attr_type_map[k->target_type -1])) {
594 if (avrule->flags == RULE_SELF) {
595 rc = check_assertion_self_match(k, avrule, p);
596 if (rc < 0)
597 goto oom;
598 if (rc == 0)
599 goto nomatch;
600 } else {
601 goto nomatch;
602 }
603 }
604 }
605
606 if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
607 rc = check_assertion_extended_permissions(avrule, avtab, k, p);
608 if (rc < 0)
609 goto oom;
610 if (rc == 0)
611 goto nomatch;
612 }
613 return 1;
614
615 nomatch:
616 return 0;
617
618 oom:
619 return rc;
620 }
621
check_assertion(policydb_t * p,avrule_t * avrule)622 int check_assertion(policydb_t *p, avrule_t *avrule)
623 {
624 int rc;
625 struct avtab_match_args args;
626
627 args.handle = NULL;
628 args.p = p;
629 args.avrule = avrule;
630 args.errors = 0;
631 args.avtab = &p->te_avtab;
632
633 rc = avtab_map(&p->te_avtab, check_assertion_avtab_match, &args);
634
635 if (rc == 0) {
636 args.avtab = &p->te_cond_avtab;
637 rc = avtab_map(&p->te_cond_avtab, check_assertion_avtab_match, &args);
638 }
639
640 return rc;
641 }
642
check_assertions(sepol_handle_t * handle,policydb_t * p,avrule_t * avrules)643 int check_assertions(sepol_handle_t * handle, policydb_t * p,
644 avrule_t * avrules)
645 {
646 int rc;
647 avrule_t *a;
648 unsigned long errors = 0;
649
650 if (!avrules) {
651 /* Since assertions are stored in avrules, if it is NULL
652 there won't be any to check. This also prevents an invalid
653 free if the avtabs are never initialized */
654 return 0;
655 }
656
657 for (a = avrules; a != NULL; a = a->next) {
658 if (!(a->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW)))
659 continue;
660 rc = check_assertion(p, a);
661 if (rc < 0) {
662 ERR(handle, "Error occurred while checking neverallows");
663 return -1;
664 }
665 if (rc) {
666 rc = report_assertion_failures(handle, p, a);
667 if (rc < 0) {
668 ERR(handle, "Error occurred while checking neverallows");
669 return -1;
670 }
671 errors += rc;
672 }
673 }
674
675 if (errors)
676 ERR(handle, "%lu neverallow failures occurred", errors);
677
678 return errors ? -1 : 0;
679 }
680