• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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