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