xref: /aosp_15_r20/external/selinux/libsepol/src/assertion.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
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