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 avrule_t * avrule) 35 { 36 avtab_key_t avkey; 37 avtab_ptr_t node; 38 class_perm_node_t *curperm; 39 40 for (curperm = avrule->perms; 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 (avrule->source_filename) { 63 ERR(handle, "neverallow on line %lu of %s (or line %lu of policy.conf) violated by allow %s %s:%s {%s };", 64 avrule->source_line, avrule->source_filename, avrule->line, 65 p->p_type_val_to_name[stype], 66 p->p_type_val_to_name[ttype], 67 p->p_class_val_to_name[curperm->class - 1], 68 sepol_av_to_string(p, curperm->class, 69 node->datum.data & curperm->data)); 70 } else if (avrule->line) { 71 ERR(handle, "neverallow on line %lu violated by allow %s %s:%s {%s };", 72 avrule->line, p->p_type_val_to_name[stype], 73 p->p_type_val_to_name[ttype], 74 p->p_class_val_to_name[curperm->class - 1], 75 sepol_av_to_string(p, curperm->class, 76 node->datum.data & curperm->data)); 77 } else { 78 ERR(handle, "neverallow violated by allow %s %s:%s {%s };", 79 p->p_type_val_to_name[stype], 80 p->p_type_val_to_name[ttype], 81 p->p_class_val_to_name[curperm->class - 1], 82 sepol_av_to_string(p, curperm->class, 83 node->datum.data & curperm->data)); 84 } 85 return -1; 86 } 87 88 int check_assertions(sepol_handle_t * handle, policydb_t * p, 89 avrule_t * avrules) 90 { 91 avrule_t *a; 92 avtab_t te_avtab, te_cond_avtab; 93 ebitmap_node_t *snode, *tnode; 94 unsigned int i, j; 95 int rc; 96 97 if (!avrules) { 98 /* Since assertions are stored in avrules, if it is NULL 99 there won't be any to check. This also prevents an invalid 100 free if the avtabs are never initialized */ 101 return 0; 102 } 103 104 if (avrules) { 105 if (avtab_init(&te_avtab)) 106 goto oom; 107 if (avtab_init(&te_cond_avtab)) { 108 avtab_destroy(&te_avtab); 109 goto oom; 110 } 111 if (expand_avtab(p, &p->te_avtab, &te_avtab) || 112 expand_avtab(p, &p->te_cond_avtab, &te_cond_avtab)) { 113 avtab_destroy(&te_avtab); 114 avtab_destroy(&te_cond_avtab); 115 goto oom; 116 } 117 } 118 119 for (a = avrules; a != NULL; a = a->next) { 120 ebitmap_t *stypes = &a->stypes.types; 121 ebitmap_t *ttypes = &a->ttypes.types; 122 123 if (!(a->specified & AVRULE_NEVERALLOW)) 124 continue; 125 126 ebitmap_for_each_bit(stypes, snode, i) { 127 if (!ebitmap_node_get_bit(snode, i)) 128 continue; 129 if (a->flags & RULE_SELF) { 130 if (check_assertion_helper 131 (handle, p, &te_avtab, &te_cond_avtab, i, i, 132 a)) { 133 rc = -1; 134 goto out; 135 } 136 } 137 ebitmap_for_each_bit(ttypes, tnode, j) { 138 if (!ebitmap_node_get_bit(tnode, j)) 139 continue; 140 if (check_assertion_helper 141 (handle, p, &te_avtab, &te_cond_avtab, i, j, 142 a)) { 143 rc = -1; 144 goto out; 145 } 146 } 147 } 148 } 149 150 rc = 0; 151 out: 152 avtab_destroy(&te_avtab); 153 avtab_destroy(&te_cond_avtab); 154 return rc; 155 156 oom: 157 ERR(handle, "Out of memory - unable to check neverallows"); 158 return -1; 159 } 160