1 /* Authors: Joshua Brindle <jbrindle (at) tresys.com> 2 * 3 * Assertion checker for avtab entries, taken from 4 * checkpolicy.c by Stephen Smalley <sds (at) 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 "debug.h" 29 30 static int check_assertion_helper(sepol_handle_t * handle, 31 policydb_t * p, 32 avtab_t * te_avtab, avtab_t * te_cond_avtab, 33 unsigned int stype, unsigned int ttype, 34 class_perm_node_t * perm, unsigned long line) 35 { 36 avtab_key_t avkey; 37 avtab_ptr_t node; 38 class_perm_node_t *curperm; 39 40 for (curperm = perm; curperm != NULL; curperm = curperm->next) { 41 avkey.source_type = stype + 1; 42 avkey.target_type = ttype + 1; 43 avkey.target_class = curperm->class; 44 avkey.specified = AVTAB_ALLOWED; 45 for (node = avtab_search_node(te_avtab, &avkey); 46 node != NULL; 47 node = avtab_search_node_next(node, avkey.specified)) { 48 if (node->datum.data & curperm->data) 49 goto err; 50 } 51 for (node = avtab_search_node(te_cond_avtab, &avkey); 52 node != NULL; 53 node = avtab_search_node_next(node, avkey.specified)) { 54 if (node->datum.data & curperm->data) 55 goto err; 56 } 57 } 58 59 return 0; 60 61 err: 62 if (line) { 63 ERR(handle, "neverallow on line %lu violated by allow %s %s:%s {%s };", 64 line, p->p_type_val_to_name[stype], 65 p->p_type_val_to_name[ttype], 66 p->p_class_val_to_name[curperm->class - 1], 67 sepol_av_to_string(p, curperm->class, 68 node->datum.data & curperm->data)); 69 } else { 70 ERR(handle, "neverallow violated by allow %s %s:%s {%s };", 71 p->p_type_val_to_name[stype], 72 p->p_type_val_to_name[ttype], 73 p->p_class_val_to_name[curperm->class - 1], 74 sepol_av_to_string(p, curperm->class, 75 node->datum.data & curperm->data)); 76 } 77 return -1; 78 } 79 80 int check_assertions(sepol_handle_t * handle, policydb_t * p, 81 avrule_t * avrules) 82 { 83 avrule_t *a; 84 avtab_t te_avtab, te_cond_avtab; 85 ebitmap_node_t *snode, *tnode; 86 unsigned int i, j; 87 int rc; 88 89 if (!avrules) { 90 /* Since assertions are stored in avrules, if it is NULL 91 there won't be any to check. This also prevents an invalid 92 free if the avtabs are never initialized */ 93 return 0; 94 } 95 96 if (avrules) { 97 if (avtab_init(&te_avtab)) 98 goto oom; 99 if (avtab_init(&te_cond_avtab)) { 100 avtab_destroy(&te_avtab); 101 goto oom; 102 } 103 if (expand_avtab(p, &p->te_avtab, &te_avtab) || 104 expand_avtab(p, &p->te_cond_avtab, &te_cond_avtab)) { 105 avtab_destroy(&te_avtab); 106 avtab_destroy(&te_cond_avtab); 107 goto oom; 108 } 109 } 110 111 for (a = avrules; a != NULL; a = a->next) { 112 ebitmap_t *stypes = &a->stypes.types; 113 ebitmap_t *ttypes = &a->ttypes.types; 114 115 if (!(a->specified & AVRULE_NEVERALLOW)) 116 continue; 117 118 ebitmap_for_each_bit(stypes, snode, i) { 119 if (!ebitmap_node_get_bit(snode, i)) 120 continue; 121 if (a->flags & RULE_SELF) { 122 if (check_assertion_helper 123 (handle, p, &te_avtab, &te_cond_avtab, i, i, 124 a->perms, a->line)) { 125 rc = -1; 126 goto out; 127 } 128 } 129 ebitmap_for_each_bit(ttypes, tnode, j) { 130 if (!ebitmap_node_get_bit(tnode, j)) 131 continue; 132 if (check_assertion_helper 133 (handle, p, &te_avtab, &te_cond_avtab, i, j, 134 a->perms, a->line)) { 135 rc = -1; 136 goto out; 137 } 138 } 139 } 140 } 141 142 rc = 0; 143 out: 144 avtab_destroy(&te_avtab); 145 avtab_destroy(&te_cond_avtab); 146 return rc; 147 148 oom: 149 ERR(handle, "Out of memory - unable to check neverallows"); 150 return -1; 151 } 152