1 /* Authors: Joshua Brindle <[email protected]>
2 *
3 * Assertion checker for avtab entries, taken from
4 * checkpolicy.c by Stephen Smalley <[email protected]>
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 } else if ((neverallow->specified == AVRULE_XPERMS_NLMSG)
114 && (allow->specified == AVTAB_XPERMS_NLMSG)) {
115 if (neverallow->driver == allow->driver)
116 rc = extended_permissions_and(neverallow->perms, allow->perms);
117 }
118
119 return rc;
120 }
121
122 /* 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)123 static void extended_permissions_violated(avtab_extended_perms_t *result,
124 av_extended_perms_t *neverallow,
125 avtab_extended_perms_t *allow)
126 {
127 size_t i;
128 if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
129 && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
130 result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
131 result->driver = allow->driver;
132 for (i = 0; i < EXTENDED_PERMS_LEN; i++)
133 result->perms[i] = neverallow->perms[i] & allow->perms[i];
134 } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
135 && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
136 result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
137 result->driver = neverallow->driver;
138 memcpy(result->perms, neverallow->perms, sizeof(result->perms));
139 } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
140 && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
141 result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
142 result->driver = allow->driver;
143 memcpy(result->perms, allow->perms, sizeof(result->perms));
144 } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
145 && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
146 result->specified = AVTAB_XPERMS_IOCTLDRIVER;
147 for (i = 0; i < EXTENDED_PERMS_LEN; i++)
148 result->perms[i] = neverallow->perms[i] & allow->perms[i];
149 } else if ((neverallow->specified == AVRULE_XPERMS_NLMSG)
150 && (allow->specified == AVTAB_XPERMS_NLMSG)) {
151 result->specified = AVTAB_XPERMS_NLMSG;
152 result->driver = allow->driver;
153 for (i = 0; i < EXTENDED_PERMS_LEN; i++)
154 result->perms[i] = neverallow->perms[i] & allow->perms[i];
155 }
156 }
157
158 /* 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)159 static int report_assertion_extended_permissions(sepol_handle_t *handle,
160 policydb_t *p, const avrule_t *avrule,
161 unsigned int stype, unsigned int ttype,
162 const class_perm_node_t *curperm, uint32_t perms,
163 avtab_key_t *k, avtab_t *avtab)
164 {
165 avtab_ptr_t node;
166 avtab_key_t tmp_key;
167 avtab_extended_perms_t *xperms;
168 avtab_extended_perms_t error;
169 ebitmap_t *sattr = &p->type_attr_map[stype];
170 ebitmap_t *tattr = &p->type_attr_map[ttype];
171 ebitmap_node_t *snode, *tnode;
172 unsigned int i, j;
173 int rc;
174 int found_xperm = 0;
175 int errors = 0;
176
177 memcpy(&tmp_key, k, sizeof(avtab_key_t));
178 tmp_key.specified = AVTAB_XPERMS_ALLOWED;
179
180 ebitmap_for_each_positive_bit(sattr, snode, i) {
181 tmp_key.source_type = i + 1;
182 ebitmap_for_each_positive_bit(tattr, tnode, j) {
183 tmp_key.target_type = j + 1;
184 for (node = avtab_search_node(avtab, &tmp_key);
185 node;
186 node = avtab_search_node_next(node, tmp_key.specified)) {
187 xperms = node->datum.xperms;
188 if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
189 && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
190 && (xperms->specified != AVTAB_XPERMS_NLMSG))
191 continue;
192 found_xperm = 1;
193 rc = check_extended_permissions(avrule->xperms, xperms);
194 /* failure on the extended permission check_extended_permissions */
195 if (rc) {
196 char *permstring;
197
198 extended_permissions_violated(&error, avrule->xperms, xperms);
199 permstring = sepol_extended_perms_to_string(&error);
200
201 ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
202 "allowxperm %s %s:%s %s;",
203 avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
204 p->p_type_val_to_name[i],
205 p->p_type_val_to_name[j],
206 p->p_class_val_to_name[curperm->tclass - 1],
207 permstring ?: "<format-failure>");
208
209 free(permstring);
210 errors++;
211 }
212 }
213 }
214 }
215
216 /* failure on the regular permissions */
217 if (!found_xperm) {
218 char *permstr = sepol_av_to_string(p, curperm->tclass, perms);
219
220 ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
221 "allow %s %s:%s {%s };",
222 avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
223 p->p_type_val_to_name[stype],
224 p->p_type_val_to_name[ttype],
225 p->p_class_val_to_name[curperm->tclass - 1],
226 permstr ?: "<format-failure>");
227
228 free(permstr);
229 errors++;
230
231 }
232
233 return errors;
234 }
235
report_assertion_avtab_matches(avtab_key_t * k,avtab_datum_t * d,void * args)236 static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void *args)
237 {
238 int rc = 0;
239 struct avtab_match_args *a = (struct avtab_match_args *)args;
240 sepol_handle_t *handle = a->handle;
241 policydb_t *p = a->p;
242 avtab_t *avtab = a->avtab;
243 avrule_t *avrule = a->avrule;
244 class_perm_node_t *cp;
245 uint32_t perms;
246 ebitmap_t src_matches, tgt_matches, self_matches;
247 ebitmap_node_t *snode, *tnode;
248 unsigned int i, j;
249 const int is_avrule_self = (avrule->flags & RULE_SELF) != 0;
250 const int is_avrule_notself = (avrule->flags & RULE_NOTSELF) != 0;
251
252 if ((k->specified & AVTAB_ALLOWED) == 0)
253 return 0;
254
255 if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
256 return 0;
257
258 ebitmap_init(&src_matches);
259 ebitmap_init(&tgt_matches);
260 ebitmap_init(&self_matches);
261
262 rc = ebitmap_and(&src_matches, &avrule->stypes.types,
263 &p->attr_type_map[k->source_type - 1]);
264 if (rc < 0)
265 goto oom;
266
267 if (ebitmap_is_empty(&src_matches))
268 goto exit;
269
270 if (is_avrule_notself) {
271 if (ebitmap_is_empty(&avrule->ttypes.types)) {
272 /* avrule tgt is of the form ~self */
273 rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type -1]);
274 } else {
275 /* avrule tgt is of the form {ATTR -self} */
276 rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type - 1]);
277 }
278 if (rc)
279 goto oom;
280 } else {
281 rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]);
282 if (rc < 0)
283 goto oom;
284
285 if (is_avrule_self) {
286 rc = ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]);
287 if (rc < 0)
288 goto oom;
289
290 if (!ebitmap_is_empty(&self_matches)) {
291 rc = ebitmap_union(&tgt_matches, &self_matches);
292 if (rc < 0)
293 goto oom;
294 }
295 }
296 }
297
298 if (ebitmap_is_empty(&tgt_matches))
299 goto exit;
300
301 for (cp = avrule->perms; cp; cp = cp->next) {
302
303 perms = cp->data & d->data;
304 if ((cp->tclass != k->target_class) || !perms) {
305 continue;
306 }
307
308 ebitmap_for_each_positive_bit(&src_matches, snode, i) {
309 ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) {
310 if (is_avrule_self && i != j)
311 continue;
312 if (is_avrule_notself && i == j)
313 continue;
314 if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
315 a->errors += report_assertion_extended_permissions(handle,p, avrule,
316 i, j, cp, perms, k, avtab);
317 } else {
318 a->errors++;
319 report_failure(handle, p, avrule, i, j, cp, perms);
320 }
321 }
322 }
323 }
324
325 oom:
326 exit:
327 ebitmap_destroy(&src_matches);
328 ebitmap_destroy(&tgt_matches);
329 ebitmap_destroy(&self_matches);
330 return rc;
331 }
332
report_assertion_failures(sepol_handle_t * handle,policydb_t * p,avrule_t * avrule)333 static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule)
334 {
335 int rc;
336 struct avtab_match_args args;
337
338 args.handle = handle;
339 args.p = p;
340 args.avrule = avrule;
341 args.errors = 0;
342
343 args.avtab = &p->te_avtab;
344 rc = avtab_map(&p->te_avtab, report_assertion_avtab_matches, &args);
345 if (rc < 0)
346 goto oom;
347
348 args.avtab = &p->te_cond_avtab;
349 rc = avtab_map(&p->te_cond_avtab, report_assertion_avtab_matches, &args);
350 if (rc < 0)
351 goto oom;
352
353 return args.errors;
354
355 oom:
356 return rc;
357 }
358
359 /*
360 * Look up the extended permissions in avtab and verify that neverallowed
361 * permissions are not granted.
362 */
check_assertion_extended_permissions_avtab(avrule_t * avrule,avtab_t * avtab,unsigned int stype,unsigned int ttype,avtab_key_t * k,policydb_t * p)363 static int check_assertion_extended_permissions_avtab(avrule_t *avrule, avtab_t *avtab,
364 unsigned int stype, unsigned int ttype,
365 avtab_key_t *k, policydb_t *p)
366 {
367 avtab_ptr_t node;
368 avtab_key_t tmp_key;
369 avtab_extended_perms_t *xperms;
370 av_extended_perms_t *neverallow_xperms = avrule->xperms;
371 ebitmap_t *sattr = &p->type_attr_map[stype];
372 ebitmap_t *tattr = &p->type_attr_map[ttype];
373 ebitmap_node_t *snode, *tnode;
374 unsigned int i, j;
375 int rc = 1;
376
377 memcpy(&tmp_key, k, sizeof(avtab_key_t));
378 tmp_key.specified = AVTAB_XPERMS_ALLOWED;
379
380 ebitmap_for_each_positive_bit(sattr, snode, i) {
381 tmp_key.source_type = i + 1;
382 ebitmap_for_each_positive_bit(tattr, tnode, j) {
383 tmp_key.target_type = j + 1;
384 for (node = avtab_search_node(avtab, &tmp_key);
385 node;
386 node = avtab_search_node_next(node, tmp_key.specified)) {
387 xperms = node->datum.xperms;
388
389 if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
390 && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
391 && (xperms->specified != AVTAB_XPERMS_NLMSG))
392 continue;
393 rc = check_extended_permissions(neverallow_xperms, xperms);
394 if (rc)
395 return rc;
396 }
397 }
398 }
399
400 return rc;
401 }
402
403 /*
404 * When the ioctl permission is granted on an avtab entry that matches an
405 * avrule neverallowxperm entry, enumerate over the matching
406 * source/target/class sets to determine if the extended permissions exist
407 * and if the neverallowed ioctls are granted.
408 *
409 * Four scenarios of interest:
410 * 1. PASS - the ioctl permission is not granted for this source/target/class
411 * This case is handled in check_assertion_avtab_match
412 * 2. PASS - The ioctl permission is granted AND the extended permission
413 * is NOT granted
414 * 3. FAIL - The ioctl permission is granted AND no extended permissions
415 * exist
416 * 4. FAIL - The ioctl permission is granted AND the extended permission is
417 * granted
418 */
check_assertion_extended_permissions(avrule_t * avrule,avtab_t * avtab,avtab_key_t * k,policydb_t * p)419 static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab,
420 avtab_key_t *k, policydb_t *p)
421 {
422 ebitmap_t src_matches, tgt_matches, self_matches;
423 unsigned int i, j;
424 ebitmap_node_t *snode, *tnode;
425 const int is_avrule_self = (avrule->flags & RULE_SELF) != 0;
426 const int is_avrule_notself = (avrule->flags & RULE_NOTSELF) != 0;
427 int rc;
428
429 ebitmap_init(&src_matches);
430 ebitmap_init(&tgt_matches);
431 ebitmap_init(&self_matches);
432
433 rc = ebitmap_and(&src_matches, &avrule->stypes.types,
434 &p->attr_type_map[k->source_type - 1]);
435 if (rc < 0)
436 goto oom;
437
438 if (ebitmap_is_empty(&src_matches)) {
439 rc = 0;
440 goto exit;
441 }
442
443 if (is_avrule_notself) {
444 if (ebitmap_is_empty(&avrule->ttypes.types)) {
445 /* avrule tgt is of the form ~self */
446 rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type -1]);
447 } else {
448 /* avrule tgt is of the form {ATTR -self} */
449 rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type - 1]);
450 }
451 if (rc < 0)
452 goto oom;
453 } else {
454 rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]);
455 if (rc < 0)
456 goto oom;
457
458 if (is_avrule_self) {
459 rc = ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]);
460 if (rc < 0)
461 goto oom;
462
463 if (!ebitmap_is_empty(&self_matches)) {
464 rc = ebitmap_union(&tgt_matches, &self_matches);
465 if (rc < 0)
466 goto oom;
467 }
468 }
469 }
470
471 if (ebitmap_is_empty(&tgt_matches)) {
472 rc = 0;
473 goto exit;
474 }
475
476 ebitmap_for_each_positive_bit(&src_matches, snode, i) {
477 ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) {
478 if (is_avrule_self && i != j)
479 continue;
480 if (is_avrule_notself && i == j)
481 continue;
482 if (check_assertion_extended_permissions_avtab(avrule, avtab, i, j, k, p)) {
483 rc = 1;
484 goto exit;
485 }
486 }
487 }
488
489 rc = 0;
490
491 oom:
492 exit:
493 ebitmap_destroy(&src_matches);
494 ebitmap_destroy(&tgt_matches);
495 ebitmap_destroy(&self_matches);
496 return rc;
497 }
498
check_assertion_notself_match(avtab_key_t * k,avrule_t * avrule,policydb_t * p)499 static int check_assertion_notself_match(avtab_key_t *k, avrule_t *avrule, policydb_t *p)
500 {
501 ebitmap_t src_matches, tgt_matches;
502 unsigned int num_src_matches, num_tgt_matches;
503 int rc;
504
505 ebitmap_init(&src_matches);
506 ebitmap_init(&tgt_matches);
507
508 rc = ebitmap_and(&src_matches, &avrule->stypes.types, &p->attr_type_map[k->source_type - 1]);
509 if (rc < 0)
510 goto oom;
511
512 if (ebitmap_is_empty(&avrule->ttypes.types)) {
513 /* avrule tgt is of the form ~self */
514 rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type - 1]);
515 } else {
516 /* avrule tgt is of the form {ATTR -self} */
517 rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type - 1]);
518 }
519 if (rc < 0)
520 goto oom;
521
522 num_src_matches = ebitmap_cardinality(&src_matches);
523 num_tgt_matches = ebitmap_cardinality(&tgt_matches);
524 if (num_src_matches == 0 || num_tgt_matches == 0) {
525 rc = 0;
526 goto nomatch;
527 }
528 if (num_src_matches == 1 && num_tgt_matches == 1) {
529 ebitmap_t matches;
530 unsigned int num_matches;
531 rc = ebitmap_and(&matches, &src_matches, &tgt_matches);
532 if (rc < 0) {
533 ebitmap_destroy(&matches);
534 goto oom;
535 }
536 num_matches = ebitmap_cardinality(&matches);
537 ebitmap_destroy(&matches);
538 if (num_matches == 1) {
539 /* The only non-match is of the form TYPE TYPE */
540 rc = 0;
541 goto nomatch;
542 }
543 }
544
545 rc = 1;
546
547 oom:
548 nomatch:
549 ebitmap_destroy(&src_matches);
550 ebitmap_destroy(&tgt_matches);
551 return rc;
552 }
553
check_assertion_self_match(avtab_key_t * k,avrule_t * avrule,policydb_t * p)554 static int check_assertion_self_match(avtab_key_t *k, avrule_t *avrule, policydb_t *p)
555 {
556 ebitmap_t src_matches;
557 int rc;
558
559 /* The key's target must match something in the matches of the avrule's source
560 * and the key's source.
561 */
562
563 rc = ebitmap_and(&src_matches, &avrule->stypes.types, &p->attr_type_map[k->source_type - 1]);
564 if (rc < 0)
565 goto oom;
566
567 if (!ebitmap_match_any(&src_matches, &p->attr_type_map[k->target_type - 1])) {
568 rc = 0;
569 goto nomatch;
570 }
571
572 rc = 1;
573
574 oom:
575 nomatch:
576 ebitmap_destroy(&src_matches);
577 return rc;
578 }
579
check_assertion_avtab_match(avtab_key_t * k,avtab_datum_t * d,void * args)580 static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *args)
581 {
582 int rc;
583 struct avtab_match_args *a = (struct avtab_match_args *)args;
584 policydb_t *p = a->p;
585 avrule_t *avrule = a->avrule;
586 avtab_t *avtab = a->avtab;
587
588 if ((k->specified & AVTAB_ALLOWED) == 0)
589 goto nomatch;
590
591 if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
592 goto nomatch;
593
594 if (!ebitmap_match_any(&avrule->stypes.types, &p->attr_type_map[k->source_type - 1]))
595 goto nomatch;
596
597 if (avrule->flags & RULE_NOTSELF) {
598 rc = check_assertion_notself_match(k, avrule, p);
599 if (rc < 0)
600 goto oom;
601 if (rc == 0)
602 goto nomatch;
603 } else {
604 /* neverallow may have tgts even if it uses SELF */
605 if (!ebitmap_match_any(&avrule->ttypes.types, &p->attr_type_map[k->target_type -1])) {
606 if (avrule->flags == RULE_SELF) {
607 rc = check_assertion_self_match(k, avrule, p);
608 if (rc < 0)
609 goto oom;
610 if (rc == 0)
611 goto nomatch;
612 } else {
613 goto nomatch;
614 }
615 }
616 }
617
618 if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
619 rc = check_assertion_extended_permissions(avrule, avtab, k, p);
620 if (rc < 0)
621 goto oom;
622 if (rc == 0)
623 goto nomatch;
624 }
625 return 1;
626
627 nomatch:
628 return 0;
629
630 oom:
631 return rc;
632 }
633
check_assertion(policydb_t * p,avrule_t * avrule)634 int check_assertion(policydb_t *p, avrule_t *avrule)
635 {
636 int rc;
637 struct avtab_match_args args;
638
639 args.handle = NULL;
640 args.p = p;
641 args.avrule = avrule;
642 args.errors = 0;
643 args.avtab = &p->te_avtab;
644
645 rc = avtab_map(&p->te_avtab, check_assertion_avtab_match, &args);
646
647 if (rc == 0) {
648 args.avtab = &p->te_cond_avtab;
649 rc = avtab_map(&p->te_cond_avtab, check_assertion_avtab_match, &args);
650 }
651
652 return rc;
653 }
654
check_assertions(sepol_handle_t * handle,policydb_t * p,avrule_t * avrules)655 int check_assertions(sepol_handle_t * handle, policydb_t * p,
656 avrule_t * avrules)
657 {
658 int rc;
659 avrule_t *a;
660 unsigned long errors = 0;
661
662 if (!avrules) {
663 /* Since assertions are stored in avrules, if it is NULL
664 there won't be any to check. This also prevents an invalid
665 free if the avtabs are never initialized */
666 return 0;
667 }
668
669 for (a = avrules; a != NULL; a = a->next) {
670 if (!(a->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW)))
671 continue;
672 rc = check_assertion(p, a);
673 if (rc < 0) {
674 ERR(handle, "Error occurred while checking neverallows");
675 return -1;
676 }
677 if (rc) {
678 rc = report_assertion_failures(handle, p, a);
679 if (rc < 0) {
680 ERR(handle, "Error occurred while checking neverallows");
681 return -1;
682 }
683 errors += rc;
684 }
685 }
686
687 if (errors)
688 ERR(handle, "%lu neverallow failures occurred", errors);
689
690 return errors ? -1 : 0;
691 }
692