• 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 <sds@tycho.nsa.gov>
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 	if (avrule->source_filename) {
52 		ERR(handle, "neverallow on line %lu of %s (or line %lu of %s) violated by allow %s %s:%s {%s };",
53 		    avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
54 		    p->p_type_val_to_name[stype],
55 		    p->p_type_val_to_name[ttype],
56 		    p->p_class_val_to_name[curperm->tclass - 1],
57 		    sepol_av_to_string(p, curperm->tclass, perms));
58 	} else if (avrule->line) {
59 		ERR(handle, "neverallow on line %lu violated by allow %s %s:%s {%s };",
60 		    avrule->line, p->p_type_val_to_name[stype],
61 		    p->p_type_val_to_name[ttype],
62 		    p->p_class_val_to_name[curperm->tclass - 1],
63 		    sepol_av_to_string(p, curperm->tclass, perms));
64 	} else {
65 		ERR(handle, "neverallow violated by allow %s %s:%s {%s };",
66 		    p->p_type_val_to_name[stype],
67 		    p->p_type_val_to_name[ttype],
68 		    p->p_class_val_to_name[curperm->tclass - 1],
69 		    sepol_av_to_string(p, curperm->tclass, perms));
70 	}
71 }
72 
match_any_class_permissions(class_perm_node_t * cp,uint32_t class,uint32_t data)73 static int match_any_class_permissions(class_perm_node_t *cp, uint32_t class, uint32_t data)
74 {
75 	for (; cp; cp = cp->next) {
76 		if ((cp->tclass == class) && (cp->data & data))
77 			return 1;
78 	}
79 
80 	return 0;
81 }
82 
extended_permissions_and(uint32_t * perms1,uint32_t * perms2)83 static int extended_permissions_and(uint32_t *perms1, uint32_t *perms2) {
84 	size_t i;
85 	for (i = 0; i < EXTENDED_PERMS_LEN; i++) {
86 		if (perms1[i] & perms2[i])
87 			return 1;
88 	}
89 
90 	return 0;
91 }
92 
check_extended_permissions(av_extended_perms_t * neverallow,avtab_extended_perms_t * allow)93 static int check_extended_permissions(av_extended_perms_t *neverallow, avtab_extended_perms_t *allow)
94 {
95 	int rc = 0;
96 	if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
97 			&& (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
98 		if (neverallow->driver == allow->driver)
99 			rc = extended_permissions_and(neverallow->perms, allow->perms);
100 	} else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
101 			&& (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
102 		rc = xperm_test(neverallow->driver, allow->perms);
103 	} else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
104 			&& (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
105 		rc = xperm_test(allow->driver, neverallow->perms);
106 	} else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
107 			&& (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
108 		rc = extended_permissions_and(neverallow->perms, allow->perms);
109 	}
110 
111 	return rc;
112 }
113 
114 /* 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)115 static void extended_permissions_violated(avtab_extended_perms_t *result,
116 					av_extended_perms_t *neverallow,
117 					avtab_extended_perms_t *allow)
118 {
119 	size_t i;
120 	if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
121 			&& (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
122 		result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
123 		result->driver = allow->driver;
124 		for (i = 0; i < EXTENDED_PERMS_LEN; i++)
125 			result->perms[i] = neverallow->perms[i] & allow->perms[i];
126 	} else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
127 			&& (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
128 		result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
129 		result->driver = neverallow->driver;
130 		memcpy(result->perms, neverallow->perms, sizeof(result->perms));
131 	} else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
132 			&& (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
133 		result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
134 		result->driver = allow->driver;
135 		memcpy(result->perms, allow->perms, sizeof(result->perms));
136 	} else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
137 			&& (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
138 		result->specified = AVTAB_XPERMS_IOCTLDRIVER;
139 		for (i = 0; i < EXTENDED_PERMS_LEN; i++)
140 			result->perms[i] = neverallow->perms[i] & allow->perms[i];
141 	}
142 }
143 
144 /* 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)145 static int report_assertion_extended_permissions(sepol_handle_t *handle,
146 				policydb_t *p, const avrule_t *avrule,
147 				unsigned int stype, unsigned int ttype,
148 				const class_perm_node_t *curperm, uint32_t perms,
149 				avtab_key_t *k, avtab_t *avtab)
150 {
151 	avtab_ptr_t node;
152 	avtab_key_t tmp_key;
153 	avtab_extended_perms_t *xperms;
154 	avtab_extended_perms_t error;
155 	ebitmap_t *sattr = &p->type_attr_map[stype];
156 	ebitmap_t *tattr = &p->type_attr_map[ttype];
157 	ebitmap_node_t *snode, *tnode;
158 	unsigned int i, j;
159 	int rc;
160 	int found_xperm = 0;
161 	int errors = 0;
162 
163 	memcpy(&tmp_key, k, sizeof(avtab_key_t));
164 	tmp_key.specified = AVTAB_XPERMS_ALLOWED;
165 
166 	ebitmap_for_each_positive_bit(sattr, snode, i) {
167 		tmp_key.source_type = i + 1;
168 		ebitmap_for_each_positive_bit(tattr, tnode, j) {
169 			tmp_key.target_type = j + 1;
170 			for (node = avtab_search_node(avtab, &tmp_key);
171 			     node;
172 			     node = avtab_search_node_next(node, tmp_key.specified)) {
173 				xperms = node->datum.xperms;
174 				if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
175 						&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
176 					continue;
177 				found_xperm = 1;
178 				rc = check_extended_permissions(avrule->xperms, xperms);
179 				/* failure on the extended permission check_extended_permissions */
180 				if (rc) {
181 					extended_permissions_violated(&error, avrule->xperms, xperms);
182 					ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
183 							"allowxperm %s %s:%s %s;",
184 							avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
185 							p->p_type_val_to_name[i],
186 							p->p_type_val_to_name[j],
187 							p->p_class_val_to_name[curperm->tclass - 1],
188 							sepol_extended_perms_to_string(&error));
189 
190 					errors++;
191 				}
192 			}
193 		}
194 	}
195 
196 	/* failure on the regular permissions */
197 	if (!found_xperm) {
198 		ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
199 				"allow %s %s:%s {%s };",
200 				avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
201 				p->p_type_val_to_name[stype],
202 				p->p_type_val_to_name[ttype],
203 				p->p_class_val_to_name[curperm->tclass - 1],
204 				sepol_av_to_string(p, curperm->tclass, perms));
205 		errors++;
206 
207 	}
208 
209 	return errors;
210 }
211 
report_assertion_avtab_matches(avtab_key_t * k,avtab_datum_t * d,void * args)212 static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void *args)
213 {
214 	int rc = 0;
215 	struct avtab_match_args *a = (struct avtab_match_args *)args;
216 	sepol_handle_t *handle = a->handle;
217 	policydb_t *p = a->p;
218 	avtab_t *avtab = a->avtab;
219 	avrule_t *avrule = a->avrule;
220 	class_perm_node_t *cp;
221 	uint32_t perms;
222 	ebitmap_t src_matches, tgt_matches, self_matches;
223 	ebitmap_node_t *snode, *tnode;
224 	unsigned int i, j;
225 	const int is_avrule_self = (avrule->flags & RULE_SELF) != 0;
226 
227 	if ((k->specified & AVTAB_ALLOWED) == 0)
228 		return 0;
229 
230 	if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
231 		return 0;
232 
233 	ebitmap_init(&src_matches);
234 	ebitmap_init(&tgt_matches);
235 	ebitmap_init(&self_matches);
236 
237 	rc = ebitmap_and(&src_matches, &avrule->stypes.types,
238 			 &p->attr_type_map[k->source_type - 1]);
239 	if (rc < 0)
240 		goto oom;
241 
242 	if (ebitmap_is_empty(&src_matches))
243 		goto exit;
244 
245 	rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]);
246 	if (rc < 0)
247 		goto oom;
248 
249 	if (is_avrule_self) {
250 		rc = ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]);
251 		if (rc < 0)
252 			goto oom;
253 
254 		if (!ebitmap_is_empty(&self_matches)) {
255 			rc = ebitmap_union(&tgt_matches, &self_matches);
256 			if (rc < 0)
257 				goto oom;
258 		}
259 	}
260 
261 	if (ebitmap_is_empty(&tgt_matches))
262 		goto exit;
263 
264 	for (cp = avrule->perms; cp; cp = cp->next) {
265 
266 		perms = cp->data & d->data;
267 		if ((cp->tclass != k->target_class) || !perms) {
268 			continue;
269 		}
270 
271 		ebitmap_for_each_positive_bit(&src_matches, snode, i) {
272 			ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) {
273 				if (is_avrule_self && i != j)
274 					continue;
275 				if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
276 					a->errors += report_assertion_extended_permissions(handle,p, avrule,
277 											i, j, cp, perms, k, avtab);
278 				} else {
279 					a->errors++;
280 					report_failure(handle, p, avrule, i, j, cp, perms);
281 				}
282 			}
283 		}
284 	}
285 
286 oom:
287 exit:
288 	ebitmap_destroy(&src_matches);
289 	ebitmap_destroy(&tgt_matches);
290 	ebitmap_destroy(&self_matches);
291 	return rc;
292 }
293 
report_assertion_failures(sepol_handle_t * handle,policydb_t * p,avrule_t * avrule)294 static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule)
295 {
296 	int rc;
297 	struct avtab_match_args args;
298 
299 	args.handle = handle;
300 	args.p = p;
301 	args.avrule = avrule;
302 	args.errors = 0;
303 
304 	args.avtab =  &p->te_avtab;
305 	rc = avtab_map(&p->te_avtab, report_assertion_avtab_matches, &args);
306 	if (rc < 0)
307 		goto oom;
308 
309 	args.avtab =  &p->te_cond_avtab;
310 	rc = avtab_map(&p->te_cond_avtab, report_assertion_avtab_matches, &args);
311 	if (rc < 0)
312 		goto oom;
313 
314 	return args.errors;
315 
316 oom:
317 	return rc;
318 }
319 
320 /*
321  * Look up the extended permissions in avtab and verify that neverallowed
322  * permissions are not granted.
323  */
check_assertion_extended_permissions_avtab(avrule_t * avrule,avtab_t * avtab,unsigned int stype,unsigned int ttype,avtab_key_t * k,policydb_t * p)324 static int check_assertion_extended_permissions_avtab(avrule_t *avrule, avtab_t *avtab,
325 						unsigned int stype, unsigned int ttype,
326 						avtab_key_t *k, policydb_t *p)
327 {
328 	avtab_ptr_t node;
329 	avtab_key_t tmp_key;
330 	avtab_extended_perms_t *xperms;
331 	av_extended_perms_t *neverallow_xperms = avrule->xperms;
332 	ebitmap_t *sattr = &p->type_attr_map[stype];
333 	ebitmap_t *tattr = &p->type_attr_map[ttype];
334 	ebitmap_node_t *snode, *tnode;
335 	unsigned int i, j;
336 	int rc = 1;
337 
338 	memcpy(&tmp_key, k, sizeof(avtab_key_t));
339 	tmp_key.specified = AVTAB_XPERMS_ALLOWED;
340 
341 	ebitmap_for_each_positive_bit(sattr, snode, i) {
342 		tmp_key.source_type = i + 1;
343 		ebitmap_for_each_positive_bit(tattr, tnode, j) {
344 			tmp_key.target_type = j + 1;
345 			for (node = avtab_search_node(avtab, &tmp_key);
346 			     node;
347 			     node = avtab_search_node_next(node, tmp_key.specified)) {
348 				xperms = node->datum.xperms;
349 
350 				if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
351 						&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
352 					continue;
353 				rc = check_extended_permissions(neverallow_xperms, xperms);
354 				if (rc)
355 					return rc;
356 			}
357 		}
358 	}
359 
360 	return rc;
361 }
362 
363 /*
364  * When the ioctl permission is granted on an avtab entry that matches an
365  * avrule neverallowxperm entry, enumerate over the matching
366  * source/target/class sets to determine if the extended permissions exist
367  * and if the neverallowed ioctls are granted.
368  *
369  * Four scenarios of interest:
370  * 1. PASS - the ioctl permission is not granted for this source/target/class
371  *    This case is handled in check_assertion_avtab_match
372  * 2. PASS - The ioctl permission is granted AND the extended permission
373  *    is NOT granted
374  * 3. FAIL - The ioctl permission is granted AND no extended permissions
375  *    exist
376  * 4. FAIL - The ioctl permission is granted AND the extended permission is
377  *    granted
378  */
check_assertion_extended_permissions(avrule_t * avrule,avtab_t * avtab,avtab_key_t * k,policydb_t * p)379 static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab,
380 						avtab_key_t *k, policydb_t *p)
381 {
382 	ebitmap_t src_matches, tgt_matches, self_matches;
383 	unsigned int i, j;
384 	ebitmap_node_t *snode, *tnode;
385 	const int is_avrule_self = (avrule->flags & RULE_SELF) != 0;
386 	int rc;
387 
388 	ebitmap_init(&src_matches);
389 	ebitmap_init(&tgt_matches);
390 	ebitmap_init(&self_matches);
391 
392 	rc = ebitmap_and(&src_matches, &avrule->stypes.types,
393 			 &p->attr_type_map[k->source_type - 1]);
394 	if (rc < 0)
395 		goto oom;
396 
397 	if (ebitmap_is_empty(&src_matches)) {
398 		rc = 0;
399 		goto exit;
400 	}
401 
402 	rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types,
403 			 &p->attr_type_map[k->target_type -1]);
404 	if (rc < 0)
405 		goto oom;
406 
407 	if (is_avrule_self) {
408 		rc = ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]);
409 		if (rc < 0)
410 			goto oom;
411 
412 		if (!ebitmap_is_empty(&self_matches)) {
413 			rc = ebitmap_union(&tgt_matches, &self_matches);
414 			if (rc < 0)
415 				goto oom;
416 		}
417 	}
418 
419 	if (ebitmap_is_empty(&tgt_matches)) {
420 		rc = 0;
421 		goto exit;
422 	}
423 
424 	ebitmap_for_each_positive_bit(&src_matches, snode, i) {
425 		ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) {
426 			if (is_avrule_self && i != j)
427 				continue;
428 			if (check_assertion_extended_permissions_avtab(avrule, avtab, i, j, k, p)) {
429 				rc = 1;
430 				goto exit;
431 			}
432 		}
433 	}
434 
435 	rc = 0;
436 
437 oom:
438 exit:
439 	ebitmap_destroy(&src_matches);
440 	ebitmap_destroy(&tgt_matches);
441 	ebitmap_destroy(&self_matches);
442 	return rc;
443 }
444 
check_assertion_self_match(avtab_key_t * k,avrule_t * avrule,policydb_t * p)445 static int check_assertion_self_match(avtab_key_t *k, avrule_t *avrule, policydb_t *p)
446 {
447 	ebitmap_t src_matches;
448 	int rc;
449 
450 	/* The key's target must match something in the matches of the avrule's source
451 	 * and the key's source.
452 	 */
453 
454 	rc = ebitmap_and(&src_matches, &avrule->stypes.types, &p->attr_type_map[k->source_type - 1]);
455 	if (rc < 0)
456 		goto oom;
457 
458 	if (!ebitmap_match_any(&src_matches, &p->attr_type_map[k->target_type - 1])) {
459 		rc = 0;
460 		goto nomatch;
461 	}
462 
463 	rc = 1;
464 
465 oom:
466 nomatch:
467 	ebitmap_destroy(&src_matches);
468 	return rc;
469 }
470 
check_assertion_avtab_match(avtab_key_t * k,avtab_datum_t * d,void * args)471 static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *args)
472 {
473 	int rc;
474 	struct avtab_match_args *a = (struct avtab_match_args *)args;
475 	policydb_t *p = a->p;
476 	avrule_t *avrule = a->avrule;
477 	avtab_t *avtab = a->avtab;
478 
479 	if ((k->specified & AVTAB_ALLOWED) == 0)
480 		goto nomatch;
481 
482 	if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
483 		goto nomatch;
484 
485 	if (!ebitmap_match_any(&avrule->stypes.types, &p->attr_type_map[k->source_type - 1]))
486 		goto nomatch;
487 
488 	/* neverallow may have tgts even if it uses SELF */
489 	if (!ebitmap_match_any(&avrule->ttypes.types, &p->attr_type_map[k->target_type -1])) {
490 		if (avrule->flags == RULE_SELF) {
491 			rc = check_assertion_self_match(k, avrule, p);
492 			if (rc < 0)
493 				goto oom;
494 			if (rc == 0)
495 				goto nomatch;
496 		} else {
497 			goto nomatch;
498 		}
499 	}
500 
501 	if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
502 		rc = check_assertion_extended_permissions(avrule, avtab, k, p);
503 		if (rc < 0)
504 			goto oom;
505 		if (rc == 0)
506 			goto nomatch;
507 	}
508 	return 1;
509 
510 nomatch:
511 	return 0;
512 
513 oom:
514 	return rc;
515 }
516 
check_assertion(policydb_t * p,avrule_t * avrule)517 int check_assertion(policydb_t *p, avrule_t *avrule)
518 {
519 	int rc;
520 	struct avtab_match_args args;
521 
522 	args.handle = NULL;
523 	args.p = p;
524 	args.avrule = avrule;
525 	args.errors = 0;
526 	args.avtab = &p->te_avtab;
527 
528 	rc = avtab_map(&p->te_avtab, check_assertion_avtab_match, &args);
529 
530 	if (rc == 0) {
531 		args.avtab = &p->te_cond_avtab;
532 		rc = avtab_map(&p->te_cond_avtab, check_assertion_avtab_match, &args);
533 	}
534 
535 	return rc;
536 }
537 
check_assertions(sepol_handle_t * handle,policydb_t * p,avrule_t * avrules)538 int check_assertions(sepol_handle_t * handle, policydb_t * p,
539 		     avrule_t * avrules)
540 {
541 	int rc;
542 	avrule_t *a;
543 	unsigned long errors = 0;
544 
545 	if (!avrules) {
546 		/* Since assertions are stored in avrules, if it is NULL
547 		   there won't be any to check. This also prevents an invalid
548 		   free if the avtabs are never initialized */
549 		return 0;
550 	}
551 
552 	for (a = avrules; a != NULL; a = a->next) {
553 		if (!(a->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW)))
554 			continue;
555 		rc = check_assertion(p, a);
556 		if (rc < 0) {
557 			ERR(handle, "Error occurred while checking neverallows");
558 			return -1;
559 		}
560 		if (rc) {
561 			rc = report_assertion_failures(handle, p, a);
562 			if (rc < 0) {
563 				ERR(handle, "Error occurred while checking neverallows");
564 				return -1;
565 			}
566 			errors += rc;
567 		}
568 	}
569 
570 	if (errors)
571 		ERR(handle, "%lu neverallow failures occurred", errors);
572 
573 	return errors ? -1 : 0;
574 }
575