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 "debug.h"
29
check_assertion_helper(sepol_handle_t * handle,policydb_t * p,avtab_t * te_avtab,avtab_t * te_cond_avtab,unsigned int stype,unsigned int ttype,class_perm_node_t * perm,unsigned long line)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
check_assertions(sepol_handle_t * handle,policydb_t * p,avrule_t * avrules)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