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