1*2d543d20SAndroid Build Coastguard Worker /* Authors: Joshua Brindle <[email protected]>
2*2d543d20SAndroid Build Coastguard Worker *
3*2d543d20SAndroid Build Coastguard Worker * Assertion checker for avtab entries, taken from
4*2d543d20SAndroid Build Coastguard Worker * checkpolicy.c by Stephen Smalley <[email protected]>
5*2d543d20SAndroid Build Coastguard Worker *
6*2d543d20SAndroid Build Coastguard Worker * Copyright (C) 2005 Tresys Technology, LLC
7*2d543d20SAndroid Build Coastguard Worker *
8*2d543d20SAndroid Build Coastguard Worker * This library is free software; you can redistribute it and/or
9*2d543d20SAndroid Build Coastguard Worker * modify it under the terms of the GNU Lesser General Public
10*2d543d20SAndroid Build Coastguard Worker * License as published by the Free Software Foundation; either
11*2d543d20SAndroid Build Coastguard Worker * version 2.1 of the License, or (at your option) any later version.
12*2d543d20SAndroid Build Coastguard Worker *
13*2d543d20SAndroid Build Coastguard Worker * This library is distributed in the hope that it will be useful,
14*2d543d20SAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
15*2d543d20SAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16*2d543d20SAndroid Build Coastguard Worker * Lesser General Public License for more details.
17*2d543d20SAndroid Build Coastguard Worker *
18*2d543d20SAndroid Build Coastguard Worker * You should have received a copy of the GNU Lesser General Public
19*2d543d20SAndroid Build Coastguard Worker * License along with this library; if not, write to the Free Software
20*2d543d20SAndroid Build Coastguard Worker * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21*2d543d20SAndroid Build Coastguard Worker */
22*2d543d20SAndroid Build Coastguard Worker
23*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/avtab.h>
24*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
25*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/expand.h>
26*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/util.h>
27*2d543d20SAndroid Build Coastguard Worker
28*2d543d20SAndroid Build Coastguard Worker #include "private.h"
29*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
30*2d543d20SAndroid Build Coastguard Worker
31*2d543d20SAndroid Build Coastguard Worker struct avtab_match_args {
32*2d543d20SAndroid Build Coastguard Worker sepol_handle_t *handle;
33*2d543d20SAndroid Build Coastguard Worker policydb_t *p;
34*2d543d20SAndroid Build Coastguard Worker avrule_t *avrule;
35*2d543d20SAndroid Build Coastguard Worker avtab_t *avtab;
36*2d543d20SAndroid Build Coastguard Worker unsigned long errors;
37*2d543d20SAndroid Build Coastguard Worker };
38*2d543d20SAndroid Build Coastguard Worker
policy_name(policydb_t * p)39*2d543d20SAndroid Build Coastguard Worker static const char* policy_name(policydb_t *p) {
40*2d543d20SAndroid Build Coastguard Worker const char *policy_file = "policy.conf";
41*2d543d20SAndroid Build Coastguard Worker if (p->name) {
42*2d543d20SAndroid Build Coastguard Worker policy_file = p->name;
43*2d543d20SAndroid Build Coastguard Worker }
44*2d543d20SAndroid Build Coastguard Worker return policy_file;
45*2d543d20SAndroid Build Coastguard Worker }
46*2d543d20SAndroid Build Coastguard Worker
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)47*2d543d20SAndroid Build Coastguard Worker static void report_failure(sepol_handle_t *handle, policydb_t *p, const avrule_t *avrule,
48*2d543d20SAndroid Build Coastguard Worker unsigned int stype, unsigned int ttype,
49*2d543d20SAndroid Build Coastguard Worker const class_perm_node_t *curperm, uint32_t perms)
50*2d543d20SAndroid Build Coastguard Worker {
51*2d543d20SAndroid Build Coastguard Worker char *permstr = sepol_av_to_string(p, curperm->tclass, perms);
52*2d543d20SAndroid Build Coastguard Worker
53*2d543d20SAndroid Build Coastguard Worker if (avrule->source_filename) {
54*2d543d20SAndroid Build Coastguard Worker ERR(handle, "neverallow on line %lu of %s (or line %lu of %s) violated by allow %s %s:%s {%s };",
55*2d543d20SAndroid Build Coastguard Worker avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
56*2d543d20SAndroid Build Coastguard Worker p->p_type_val_to_name[stype],
57*2d543d20SAndroid Build Coastguard Worker p->p_type_val_to_name[ttype],
58*2d543d20SAndroid Build Coastguard Worker p->p_class_val_to_name[curperm->tclass - 1],
59*2d543d20SAndroid Build Coastguard Worker permstr ?: "<format-failure>");
60*2d543d20SAndroid Build Coastguard Worker } else if (avrule->line) {
61*2d543d20SAndroid Build Coastguard Worker ERR(handle, "neverallow on line %lu violated by allow %s %s:%s {%s };",
62*2d543d20SAndroid Build Coastguard Worker avrule->line, p->p_type_val_to_name[stype],
63*2d543d20SAndroid Build Coastguard Worker p->p_type_val_to_name[ttype],
64*2d543d20SAndroid Build Coastguard Worker p->p_class_val_to_name[curperm->tclass - 1],
65*2d543d20SAndroid Build Coastguard Worker permstr ?: "<format-failure>");
66*2d543d20SAndroid Build Coastguard Worker } else {
67*2d543d20SAndroid Build Coastguard Worker ERR(handle, "neverallow violated by allow %s %s:%s {%s };",
68*2d543d20SAndroid Build Coastguard Worker p->p_type_val_to_name[stype],
69*2d543d20SAndroid Build Coastguard Worker p->p_type_val_to_name[ttype],
70*2d543d20SAndroid Build Coastguard Worker p->p_class_val_to_name[curperm->tclass - 1],
71*2d543d20SAndroid Build Coastguard Worker permstr ?: "<format-failure>");
72*2d543d20SAndroid Build Coastguard Worker }
73*2d543d20SAndroid Build Coastguard Worker
74*2d543d20SAndroid Build Coastguard Worker free(permstr);
75*2d543d20SAndroid Build Coastguard Worker }
76*2d543d20SAndroid Build Coastguard Worker
match_any_class_permissions(class_perm_node_t * cp,uint32_t class,uint32_t data)77*2d543d20SAndroid Build Coastguard Worker static int match_any_class_permissions(class_perm_node_t *cp, uint32_t class, uint32_t data)
78*2d543d20SAndroid Build Coastguard Worker {
79*2d543d20SAndroid Build Coastguard Worker for (; cp; cp = cp->next) {
80*2d543d20SAndroid Build Coastguard Worker if ((cp->tclass == class) && (cp->data & data))
81*2d543d20SAndroid Build Coastguard Worker return 1;
82*2d543d20SAndroid Build Coastguard Worker }
83*2d543d20SAndroid Build Coastguard Worker
84*2d543d20SAndroid Build Coastguard Worker return 0;
85*2d543d20SAndroid Build Coastguard Worker }
86*2d543d20SAndroid Build Coastguard Worker
extended_permissions_and(uint32_t * perms1,uint32_t * perms2)87*2d543d20SAndroid Build Coastguard Worker static int extended_permissions_and(uint32_t *perms1, uint32_t *perms2) {
88*2d543d20SAndroid Build Coastguard Worker size_t i;
89*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < EXTENDED_PERMS_LEN; i++) {
90*2d543d20SAndroid Build Coastguard Worker if (perms1[i] & perms2[i])
91*2d543d20SAndroid Build Coastguard Worker return 1;
92*2d543d20SAndroid Build Coastguard Worker }
93*2d543d20SAndroid Build Coastguard Worker
94*2d543d20SAndroid Build Coastguard Worker return 0;
95*2d543d20SAndroid Build Coastguard Worker }
96*2d543d20SAndroid Build Coastguard Worker
check_extended_permissions(av_extended_perms_t * neverallow,avtab_extended_perms_t * allow)97*2d543d20SAndroid Build Coastguard Worker static int check_extended_permissions(av_extended_perms_t *neverallow, avtab_extended_perms_t *allow)
98*2d543d20SAndroid Build Coastguard Worker {
99*2d543d20SAndroid Build Coastguard Worker int rc = 0;
100*2d543d20SAndroid Build Coastguard Worker if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
101*2d543d20SAndroid Build Coastguard Worker && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
102*2d543d20SAndroid Build Coastguard Worker if (neverallow->driver == allow->driver)
103*2d543d20SAndroid Build Coastguard Worker rc = extended_permissions_and(neverallow->perms, allow->perms);
104*2d543d20SAndroid Build Coastguard Worker } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
105*2d543d20SAndroid Build Coastguard Worker && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
106*2d543d20SAndroid Build Coastguard Worker rc = xperm_test(neverallow->driver, allow->perms);
107*2d543d20SAndroid Build Coastguard Worker } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
108*2d543d20SAndroid Build Coastguard Worker && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
109*2d543d20SAndroid Build Coastguard Worker rc = xperm_test(allow->driver, neverallow->perms);
110*2d543d20SAndroid Build Coastguard Worker } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
111*2d543d20SAndroid Build Coastguard Worker && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
112*2d543d20SAndroid Build Coastguard Worker rc = extended_permissions_and(neverallow->perms, allow->perms);
113*2d543d20SAndroid Build Coastguard Worker } else if ((neverallow->specified == AVRULE_XPERMS_NLMSG)
114*2d543d20SAndroid Build Coastguard Worker && (allow->specified == AVTAB_XPERMS_NLMSG)) {
115*2d543d20SAndroid Build Coastguard Worker if (neverallow->driver == allow->driver)
116*2d543d20SAndroid Build Coastguard Worker rc = extended_permissions_and(neverallow->perms, allow->perms);
117*2d543d20SAndroid Build Coastguard Worker }
118*2d543d20SAndroid Build Coastguard Worker
119*2d543d20SAndroid Build Coastguard Worker return rc;
120*2d543d20SAndroid Build Coastguard Worker }
121*2d543d20SAndroid Build Coastguard Worker
122*2d543d20SAndroid Build Coastguard Worker /* 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)123*2d543d20SAndroid Build Coastguard Worker static void extended_permissions_violated(avtab_extended_perms_t *result,
124*2d543d20SAndroid Build Coastguard Worker av_extended_perms_t *neverallow,
125*2d543d20SAndroid Build Coastguard Worker avtab_extended_perms_t *allow)
126*2d543d20SAndroid Build Coastguard Worker {
127*2d543d20SAndroid Build Coastguard Worker size_t i;
128*2d543d20SAndroid Build Coastguard Worker if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
129*2d543d20SAndroid Build Coastguard Worker && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
130*2d543d20SAndroid Build Coastguard Worker result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
131*2d543d20SAndroid Build Coastguard Worker result->driver = allow->driver;
132*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < EXTENDED_PERMS_LEN; i++)
133*2d543d20SAndroid Build Coastguard Worker result->perms[i] = neverallow->perms[i] & allow->perms[i];
134*2d543d20SAndroid Build Coastguard Worker } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
135*2d543d20SAndroid Build Coastguard Worker && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
136*2d543d20SAndroid Build Coastguard Worker result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
137*2d543d20SAndroid Build Coastguard Worker result->driver = neverallow->driver;
138*2d543d20SAndroid Build Coastguard Worker memcpy(result->perms, neverallow->perms, sizeof(result->perms));
139*2d543d20SAndroid Build Coastguard Worker } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
140*2d543d20SAndroid Build Coastguard Worker && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
141*2d543d20SAndroid Build Coastguard Worker result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
142*2d543d20SAndroid Build Coastguard Worker result->driver = allow->driver;
143*2d543d20SAndroid Build Coastguard Worker memcpy(result->perms, allow->perms, sizeof(result->perms));
144*2d543d20SAndroid Build Coastguard Worker } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
145*2d543d20SAndroid Build Coastguard Worker && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
146*2d543d20SAndroid Build Coastguard Worker result->specified = AVTAB_XPERMS_IOCTLDRIVER;
147*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < EXTENDED_PERMS_LEN; i++)
148*2d543d20SAndroid Build Coastguard Worker result->perms[i] = neverallow->perms[i] & allow->perms[i];
149*2d543d20SAndroid Build Coastguard Worker } else if ((neverallow->specified == AVRULE_XPERMS_NLMSG)
150*2d543d20SAndroid Build Coastguard Worker && (allow->specified == AVTAB_XPERMS_NLMSG)) {
151*2d543d20SAndroid Build Coastguard Worker result->specified = AVTAB_XPERMS_NLMSG;
152*2d543d20SAndroid Build Coastguard Worker result->driver = allow->driver;
153*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < EXTENDED_PERMS_LEN; i++)
154*2d543d20SAndroid Build Coastguard Worker result->perms[i] = neverallow->perms[i] & allow->perms[i];
155*2d543d20SAndroid Build Coastguard Worker }
156*2d543d20SAndroid Build Coastguard Worker }
157*2d543d20SAndroid Build Coastguard Worker
158*2d543d20SAndroid Build Coastguard Worker /* 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)159*2d543d20SAndroid Build Coastguard Worker static int report_assertion_extended_permissions(sepol_handle_t *handle,
160*2d543d20SAndroid Build Coastguard Worker policydb_t *p, const avrule_t *avrule,
161*2d543d20SAndroid Build Coastguard Worker unsigned int stype, unsigned int ttype,
162*2d543d20SAndroid Build Coastguard Worker const class_perm_node_t *curperm, uint32_t perms,
163*2d543d20SAndroid Build Coastguard Worker avtab_key_t *k, avtab_t *avtab)
164*2d543d20SAndroid Build Coastguard Worker {
165*2d543d20SAndroid Build Coastguard Worker avtab_ptr_t node;
166*2d543d20SAndroid Build Coastguard Worker avtab_key_t tmp_key;
167*2d543d20SAndroid Build Coastguard Worker avtab_extended_perms_t *xperms;
168*2d543d20SAndroid Build Coastguard Worker avtab_extended_perms_t error;
169*2d543d20SAndroid Build Coastguard Worker ebitmap_t *sattr = &p->type_attr_map[stype];
170*2d543d20SAndroid Build Coastguard Worker ebitmap_t *tattr = &p->type_attr_map[ttype];
171*2d543d20SAndroid Build Coastguard Worker ebitmap_node_t *snode, *tnode;
172*2d543d20SAndroid Build Coastguard Worker unsigned int i, j;
173*2d543d20SAndroid Build Coastguard Worker int rc;
174*2d543d20SAndroid Build Coastguard Worker int found_xperm = 0;
175*2d543d20SAndroid Build Coastguard Worker int errors = 0;
176*2d543d20SAndroid Build Coastguard Worker
177*2d543d20SAndroid Build Coastguard Worker memcpy(&tmp_key, k, sizeof(avtab_key_t));
178*2d543d20SAndroid Build Coastguard Worker tmp_key.specified = AVTAB_XPERMS_ALLOWED;
179*2d543d20SAndroid Build Coastguard Worker
180*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(sattr, snode, i) {
181*2d543d20SAndroid Build Coastguard Worker tmp_key.source_type = i + 1;
182*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(tattr, tnode, j) {
183*2d543d20SAndroid Build Coastguard Worker tmp_key.target_type = j + 1;
184*2d543d20SAndroid Build Coastguard Worker for (node = avtab_search_node(avtab, &tmp_key);
185*2d543d20SAndroid Build Coastguard Worker node;
186*2d543d20SAndroid Build Coastguard Worker node = avtab_search_node_next(node, tmp_key.specified)) {
187*2d543d20SAndroid Build Coastguard Worker xperms = node->datum.xperms;
188*2d543d20SAndroid Build Coastguard Worker if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
189*2d543d20SAndroid Build Coastguard Worker && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
190*2d543d20SAndroid Build Coastguard Worker && (xperms->specified != AVTAB_XPERMS_NLMSG))
191*2d543d20SAndroid Build Coastguard Worker continue;
192*2d543d20SAndroid Build Coastguard Worker found_xperm = 1;
193*2d543d20SAndroid Build Coastguard Worker rc = check_extended_permissions(avrule->xperms, xperms);
194*2d543d20SAndroid Build Coastguard Worker /* failure on the extended permission check_extended_permissions */
195*2d543d20SAndroid Build Coastguard Worker if (rc) {
196*2d543d20SAndroid Build Coastguard Worker char *permstring;
197*2d543d20SAndroid Build Coastguard Worker
198*2d543d20SAndroid Build Coastguard Worker extended_permissions_violated(&error, avrule->xperms, xperms);
199*2d543d20SAndroid Build Coastguard Worker permstring = sepol_extended_perms_to_string(&error);
200*2d543d20SAndroid Build Coastguard Worker
201*2d543d20SAndroid Build Coastguard Worker ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
202*2d543d20SAndroid Build Coastguard Worker "allowxperm %s %s:%s %s;",
203*2d543d20SAndroid Build Coastguard Worker avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
204*2d543d20SAndroid Build Coastguard Worker p->p_type_val_to_name[i],
205*2d543d20SAndroid Build Coastguard Worker p->p_type_val_to_name[j],
206*2d543d20SAndroid Build Coastguard Worker p->p_class_val_to_name[curperm->tclass - 1],
207*2d543d20SAndroid Build Coastguard Worker permstring ?: "<format-failure>");
208*2d543d20SAndroid Build Coastguard Worker
209*2d543d20SAndroid Build Coastguard Worker free(permstring);
210*2d543d20SAndroid Build Coastguard Worker errors++;
211*2d543d20SAndroid Build Coastguard Worker }
212*2d543d20SAndroid Build Coastguard Worker }
213*2d543d20SAndroid Build Coastguard Worker }
214*2d543d20SAndroid Build Coastguard Worker }
215*2d543d20SAndroid Build Coastguard Worker
216*2d543d20SAndroid Build Coastguard Worker /* failure on the regular permissions */
217*2d543d20SAndroid Build Coastguard Worker if (!found_xperm) {
218*2d543d20SAndroid Build Coastguard Worker char *permstr = sepol_av_to_string(p, curperm->tclass, perms);
219*2d543d20SAndroid Build Coastguard Worker
220*2d543d20SAndroid Build Coastguard Worker ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
221*2d543d20SAndroid Build Coastguard Worker "allow %s %s:%s {%s };",
222*2d543d20SAndroid Build Coastguard Worker avrule->source_line, avrule->source_filename, avrule->line, policy_name(p),
223*2d543d20SAndroid Build Coastguard Worker p->p_type_val_to_name[stype],
224*2d543d20SAndroid Build Coastguard Worker p->p_type_val_to_name[ttype],
225*2d543d20SAndroid Build Coastguard Worker p->p_class_val_to_name[curperm->tclass - 1],
226*2d543d20SAndroid Build Coastguard Worker permstr ?: "<format-failure>");
227*2d543d20SAndroid Build Coastguard Worker
228*2d543d20SAndroid Build Coastguard Worker free(permstr);
229*2d543d20SAndroid Build Coastguard Worker errors++;
230*2d543d20SAndroid Build Coastguard Worker
231*2d543d20SAndroid Build Coastguard Worker }
232*2d543d20SAndroid Build Coastguard Worker
233*2d543d20SAndroid Build Coastguard Worker return errors;
234*2d543d20SAndroid Build Coastguard Worker }
235*2d543d20SAndroid Build Coastguard Worker
report_assertion_avtab_matches(avtab_key_t * k,avtab_datum_t * d,void * args)236*2d543d20SAndroid Build Coastguard Worker static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void *args)
237*2d543d20SAndroid Build Coastguard Worker {
238*2d543d20SAndroid Build Coastguard Worker int rc = 0;
239*2d543d20SAndroid Build Coastguard Worker struct avtab_match_args *a = (struct avtab_match_args *)args;
240*2d543d20SAndroid Build Coastguard Worker sepol_handle_t *handle = a->handle;
241*2d543d20SAndroid Build Coastguard Worker policydb_t *p = a->p;
242*2d543d20SAndroid Build Coastguard Worker avtab_t *avtab = a->avtab;
243*2d543d20SAndroid Build Coastguard Worker avrule_t *avrule = a->avrule;
244*2d543d20SAndroid Build Coastguard Worker class_perm_node_t *cp;
245*2d543d20SAndroid Build Coastguard Worker uint32_t perms;
246*2d543d20SAndroid Build Coastguard Worker ebitmap_t src_matches, tgt_matches, self_matches;
247*2d543d20SAndroid Build Coastguard Worker ebitmap_node_t *snode, *tnode;
248*2d543d20SAndroid Build Coastguard Worker unsigned int i, j;
249*2d543d20SAndroid Build Coastguard Worker const int is_avrule_self = (avrule->flags & RULE_SELF) != 0;
250*2d543d20SAndroid Build Coastguard Worker const int is_avrule_notself = (avrule->flags & RULE_NOTSELF) != 0;
251*2d543d20SAndroid Build Coastguard Worker
252*2d543d20SAndroid Build Coastguard Worker if ((k->specified & AVTAB_ALLOWED) == 0)
253*2d543d20SAndroid Build Coastguard Worker return 0;
254*2d543d20SAndroid Build Coastguard Worker
255*2d543d20SAndroid Build Coastguard Worker if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
256*2d543d20SAndroid Build Coastguard Worker return 0;
257*2d543d20SAndroid Build Coastguard Worker
258*2d543d20SAndroid Build Coastguard Worker ebitmap_init(&src_matches);
259*2d543d20SAndroid Build Coastguard Worker ebitmap_init(&tgt_matches);
260*2d543d20SAndroid Build Coastguard Worker ebitmap_init(&self_matches);
261*2d543d20SAndroid Build Coastguard Worker
262*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(&src_matches, &avrule->stypes.types,
263*2d543d20SAndroid Build Coastguard Worker &p->attr_type_map[k->source_type - 1]);
264*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
265*2d543d20SAndroid Build Coastguard Worker goto oom;
266*2d543d20SAndroid Build Coastguard Worker
267*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&src_matches))
268*2d543d20SAndroid Build Coastguard Worker goto exit;
269*2d543d20SAndroid Build Coastguard Worker
270*2d543d20SAndroid Build Coastguard Worker if (is_avrule_notself) {
271*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&avrule->ttypes.types)) {
272*2d543d20SAndroid Build Coastguard Worker /* avrule tgt is of the form ~self */
273*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type -1]);
274*2d543d20SAndroid Build Coastguard Worker } else {
275*2d543d20SAndroid Build Coastguard Worker /* avrule tgt is of the form {ATTR -self} */
276*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type - 1]);
277*2d543d20SAndroid Build Coastguard Worker }
278*2d543d20SAndroid Build Coastguard Worker if (rc)
279*2d543d20SAndroid Build Coastguard Worker goto oom;
280*2d543d20SAndroid Build Coastguard Worker } else {
281*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]);
282*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
283*2d543d20SAndroid Build Coastguard Worker goto oom;
284*2d543d20SAndroid Build Coastguard Worker
285*2d543d20SAndroid Build Coastguard Worker if (is_avrule_self) {
286*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]);
287*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
288*2d543d20SAndroid Build Coastguard Worker goto oom;
289*2d543d20SAndroid Build Coastguard Worker
290*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&self_matches)) {
291*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_union(&tgt_matches, &self_matches);
292*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
293*2d543d20SAndroid Build Coastguard Worker goto oom;
294*2d543d20SAndroid Build Coastguard Worker }
295*2d543d20SAndroid Build Coastguard Worker }
296*2d543d20SAndroid Build Coastguard Worker }
297*2d543d20SAndroid Build Coastguard Worker
298*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&tgt_matches))
299*2d543d20SAndroid Build Coastguard Worker goto exit;
300*2d543d20SAndroid Build Coastguard Worker
301*2d543d20SAndroid Build Coastguard Worker for (cp = avrule->perms; cp; cp = cp->next) {
302*2d543d20SAndroid Build Coastguard Worker
303*2d543d20SAndroid Build Coastguard Worker perms = cp->data & d->data;
304*2d543d20SAndroid Build Coastguard Worker if ((cp->tclass != k->target_class) || !perms) {
305*2d543d20SAndroid Build Coastguard Worker continue;
306*2d543d20SAndroid Build Coastguard Worker }
307*2d543d20SAndroid Build Coastguard Worker
308*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&src_matches, snode, i) {
309*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) {
310*2d543d20SAndroid Build Coastguard Worker if (is_avrule_self && i != j)
311*2d543d20SAndroid Build Coastguard Worker continue;
312*2d543d20SAndroid Build Coastguard Worker if (is_avrule_notself && i == j)
313*2d543d20SAndroid Build Coastguard Worker continue;
314*2d543d20SAndroid Build Coastguard Worker if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
315*2d543d20SAndroid Build Coastguard Worker a->errors += report_assertion_extended_permissions(handle,p, avrule,
316*2d543d20SAndroid Build Coastguard Worker i, j, cp, perms, k, avtab);
317*2d543d20SAndroid Build Coastguard Worker } else {
318*2d543d20SAndroid Build Coastguard Worker a->errors++;
319*2d543d20SAndroid Build Coastguard Worker report_failure(handle, p, avrule, i, j, cp, perms);
320*2d543d20SAndroid Build Coastguard Worker }
321*2d543d20SAndroid Build Coastguard Worker }
322*2d543d20SAndroid Build Coastguard Worker }
323*2d543d20SAndroid Build Coastguard Worker }
324*2d543d20SAndroid Build Coastguard Worker
325*2d543d20SAndroid Build Coastguard Worker oom:
326*2d543d20SAndroid Build Coastguard Worker exit:
327*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&src_matches);
328*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&tgt_matches);
329*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&self_matches);
330*2d543d20SAndroid Build Coastguard Worker return rc;
331*2d543d20SAndroid Build Coastguard Worker }
332*2d543d20SAndroid Build Coastguard Worker
report_assertion_failures(sepol_handle_t * handle,policydb_t * p,avrule_t * avrule)333*2d543d20SAndroid Build Coastguard Worker static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule)
334*2d543d20SAndroid Build Coastguard Worker {
335*2d543d20SAndroid Build Coastguard Worker int rc;
336*2d543d20SAndroid Build Coastguard Worker struct avtab_match_args args;
337*2d543d20SAndroid Build Coastguard Worker
338*2d543d20SAndroid Build Coastguard Worker args.handle = handle;
339*2d543d20SAndroid Build Coastguard Worker args.p = p;
340*2d543d20SAndroid Build Coastguard Worker args.avrule = avrule;
341*2d543d20SAndroid Build Coastguard Worker args.errors = 0;
342*2d543d20SAndroid Build Coastguard Worker
343*2d543d20SAndroid Build Coastguard Worker args.avtab = &p->te_avtab;
344*2d543d20SAndroid Build Coastguard Worker rc = avtab_map(&p->te_avtab, report_assertion_avtab_matches, &args);
345*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
346*2d543d20SAndroid Build Coastguard Worker goto oom;
347*2d543d20SAndroid Build Coastguard Worker
348*2d543d20SAndroid Build Coastguard Worker args.avtab = &p->te_cond_avtab;
349*2d543d20SAndroid Build Coastguard Worker rc = avtab_map(&p->te_cond_avtab, report_assertion_avtab_matches, &args);
350*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
351*2d543d20SAndroid Build Coastguard Worker goto oom;
352*2d543d20SAndroid Build Coastguard Worker
353*2d543d20SAndroid Build Coastguard Worker return args.errors;
354*2d543d20SAndroid Build Coastguard Worker
355*2d543d20SAndroid Build Coastguard Worker oom:
356*2d543d20SAndroid Build Coastguard Worker return rc;
357*2d543d20SAndroid Build Coastguard Worker }
358*2d543d20SAndroid Build Coastguard Worker
359*2d543d20SAndroid Build Coastguard Worker /*
360*2d543d20SAndroid Build Coastguard Worker * Look up the extended permissions in avtab and verify that neverallowed
361*2d543d20SAndroid Build Coastguard Worker * permissions are not granted.
362*2d543d20SAndroid Build Coastguard Worker */
check_assertion_extended_permissions_avtab(avrule_t * avrule,avtab_t * avtab,unsigned int stype,unsigned int ttype,avtab_key_t * k,policydb_t * p)363*2d543d20SAndroid Build Coastguard Worker static int check_assertion_extended_permissions_avtab(avrule_t *avrule, avtab_t *avtab,
364*2d543d20SAndroid Build Coastguard Worker unsigned int stype, unsigned int ttype,
365*2d543d20SAndroid Build Coastguard Worker avtab_key_t *k, policydb_t *p)
366*2d543d20SAndroid Build Coastguard Worker {
367*2d543d20SAndroid Build Coastguard Worker avtab_ptr_t node;
368*2d543d20SAndroid Build Coastguard Worker avtab_key_t tmp_key;
369*2d543d20SAndroid Build Coastguard Worker avtab_extended_perms_t *xperms;
370*2d543d20SAndroid Build Coastguard Worker av_extended_perms_t *neverallow_xperms = avrule->xperms;
371*2d543d20SAndroid Build Coastguard Worker ebitmap_t *sattr = &p->type_attr_map[stype];
372*2d543d20SAndroid Build Coastguard Worker ebitmap_t *tattr = &p->type_attr_map[ttype];
373*2d543d20SAndroid Build Coastguard Worker ebitmap_node_t *snode, *tnode;
374*2d543d20SAndroid Build Coastguard Worker unsigned int i, j;
375*2d543d20SAndroid Build Coastguard Worker int rc = 1;
376*2d543d20SAndroid Build Coastguard Worker
377*2d543d20SAndroid Build Coastguard Worker memcpy(&tmp_key, k, sizeof(avtab_key_t));
378*2d543d20SAndroid Build Coastguard Worker tmp_key.specified = AVTAB_XPERMS_ALLOWED;
379*2d543d20SAndroid Build Coastguard Worker
380*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(sattr, snode, i) {
381*2d543d20SAndroid Build Coastguard Worker tmp_key.source_type = i + 1;
382*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(tattr, tnode, j) {
383*2d543d20SAndroid Build Coastguard Worker tmp_key.target_type = j + 1;
384*2d543d20SAndroid Build Coastguard Worker for (node = avtab_search_node(avtab, &tmp_key);
385*2d543d20SAndroid Build Coastguard Worker node;
386*2d543d20SAndroid Build Coastguard Worker node = avtab_search_node_next(node, tmp_key.specified)) {
387*2d543d20SAndroid Build Coastguard Worker xperms = node->datum.xperms;
388*2d543d20SAndroid Build Coastguard Worker
389*2d543d20SAndroid Build Coastguard Worker if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
390*2d543d20SAndroid Build Coastguard Worker && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
391*2d543d20SAndroid Build Coastguard Worker && (xperms->specified != AVTAB_XPERMS_NLMSG))
392*2d543d20SAndroid Build Coastguard Worker continue;
393*2d543d20SAndroid Build Coastguard Worker rc = check_extended_permissions(neverallow_xperms, xperms);
394*2d543d20SAndroid Build Coastguard Worker if (rc)
395*2d543d20SAndroid Build Coastguard Worker return rc;
396*2d543d20SAndroid Build Coastguard Worker }
397*2d543d20SAndroid Build Coastguard Worker }
398*2d543d20SAndroid Build Coastguard Worker }
399*2d543d20SAndroid Build Coastguard Worker
400*2d543d20SAndroid Build Coastguard Worker return rc;
401*2d543d20SAndroid Build Coastguard Worker }
402*2d543d20SAndroid Build Coastguard Worker
403*2d543d20SAndroid Build Coastguard Worker /*
404*2d543d20SAndroid Build Coastguard Worker * When the ioctl permission is granted on an avtab entry that matches an
405*2d543d20SAndroid Build Coastguard Worker * avrule neverallowxperm entry, enumerate over the matching
406*2d543d20SAndroid Build Coastguard Worker * source/target/class sets to determine if the extended permissions exist
407*2d543d20SAndroid Build Coastguard Worker * and if the neverallowed ioctls are granted.
408*2d543d20SAndroid Build Coastguard Worker *
409*2d543d20SAndroid Build Coastguard Worker * Four scenarios of interest:
410*2d543d20SAndroid Build Coastguard Worker * 1. PASS - the ioctl permission is not granted for this source/target/class
411*2d543d20SAndroid Build Coastguard Worker * This case is handled in check_assertion_avtab_match
412*2d543d20SAndroid Build Coastguard Worker * 2. PASS - The ioctl permission is granted AND the extended permission
413*2d543d20SAndroid Build Coastguard Worker * is NOT granted
414*2d543d20SAndroid Build Coastguard Worker * 3. FAIL - The ioctl permission is granted AND no extended permissions
415*2d543d20SAndroid Build Coastguard Worker * exist
416*2d543d20SAndroid Build Coastguard Worker * 4. FAIL - The ioctl permission is granted AND the extended permission is
417*2d543d20SAndroid Build Coastguard Worker * granted
418*2d543d20SAndroid Build Coastguard Worker */
check_assertion_extended_permissions(avrule_t * avrule,avtab_t * avtab,avtab_key_t * k,policydb_t * p)419*2d543d20SAndroid Build Coastguard Worker static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab,
420*2d543d20SAndroid Build Coastguard Worker avtab_key_t *k, policydb_t *p)
421*2d543d20SAndroid Build Coastguard Worker {
422*2d543d20SAndroid Build Coastguard Worker ebitmap_t src_matches, tgt_matches, self_matches;
423*2d543d20SAndroid Build Coastguard Worker unsigned int i, j;
424*2d543d20SAndroid Build Coastguard Worker ebitmap_node_t *snode, *tnode;
425*2d543d20SAndroid Build Coastguard Worker const int is_avrule_self = (avrule->flags & RULE_SELF) != 0;
426*2d543d20SAndroid Build Coastguard Worker const int is_avrule_notself = (avrule->flags & RULE_NOTSELF) != 0;
427*2d543d20SAndroid Build Coastguard Worker int rc;
428*2d543d20SAndroid Build Coastguard Worker
429*2d543d20SAndroid Build Coastguard Worker ebitmap_init(&src_matches);
430*2d543d20SAndroid Build Coastguard Worker ebitmap_init(&tgt_matches);
431*2d543d20SAndroid Build Coastguard Worker ebitmap_init(&self_matches);
432*2d543d20SAndroid Build Coastguard Worker
433*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(&src_matches, &avrule->stypes.types,
434*2d543d20SAndroid Build Coastguard Worker &p->attr_type_map[k->source_type - 1]);
435*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
436*2d543d20SAndroid Build Coastguard Worker goto oom;
437*2d543d20SAndroid Build Coastguard Worker
438*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&src_matches)) {
439*2d543d20SAndroid Build Coastguard Worker rc = 0;
440*2d543d20SAndroid Build Coastguard Worker goto exit;
441*2d543d20SAndroid Build Coastguard Worker }
442*2d543d20SAndroid Build Coastguard Worker
443*2d543d20SAndroid Build Coastguard Worker if (is_avrule_notself) {
444*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&avrule->ttypes.types)) {
445*2d543d20SAndroid Build Coastguard Worker /* avrule tgt is of the form ~self */
446*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type -1]);
447*2d543d20SAndroid Build Coastguard Worker } else {
448*2d543d20SAndroid Build Coastguard Worker /* avrule tgt is of the form {ATTR -self} */
449*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type - 1]);
450*2d543d20SAndroid Build Coastguard Worker }
451*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
452*2d543d20SAndroid Build Coastguard Worker goto oom;
453*2d543d20SAndroid Build Coastguard Worker } else {
454*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]);
455*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
456*2d543d20SAndroid Build Coastguard Worker goto oom;
457*2d543d20SAndroid Build Coastguard Worker
458*2d543d20SAndroid Build Coastguard Worker if (is_avrule_self) {
459*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]);
460*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
461*2d543d20SAndroid Build Coastguard Worker goto oom;
462*2d543d20SAndroid Build Coastguard Worker
463*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&self_matches)) {
464*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_union(&tgt_matches, &self_matches);
465*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
466*2d543d20SAndroid Build Coastguard Worker goto oom;
467*2d543d20SAndroid Build Coastguard Worker }
468*2d543d20SAndroid Build Coastguard Worker }
469*2d543d20SAndroid Build Coastguard Worker }
470*2d543d20SAndroid Build Coastguard Worker
471*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&tgt_matches)) {
472*2d543d20SAndroid Build Coastguard Worker rc = 0;
473*2d543d20SAndroid Build Coastguard Worker goto exit;
474*2d543d20SAndroid Build Coastguard Worker }
475*2d543d20SAndroid Build Coastguard Worker
476*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&src_matches, snode, i) {
477*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) {
478*2d543d20SAndroid Build Coastguard Worker if (is_avrule_self && i != j)
479*2d543d20SAndroid Build Coastguard Worker continue;
480*2d543d20SAndroid Build Coastguard Worker if (is_avrule_notself && i == j)
481*2d543d20SAndroid Build Coastguard Worker continue;
482*2d543d20SAndroid Build Coastguard Worker if (check_assertion_extended_permissions_avtab(avrule, avtab, i, j, k, p)) {
483*2d543d20SAndroid Build Coastguard Worker rc = 1;
484*2d543d20SAndroid Build Coastguard Worker goto exit;
485*2d543d20SAndroid Build Coastguard Worker }
486*2d543d20SAndroid Build Coastguard Worker }
487*2d543d20SAndroid Build Coastguard Worker }
488*2d543d20SAndroid Build Coastguard Worker
489*2d543d20SAndroid Build Coastguard Worker rc = 0;
490*2d543d20SAndroid Build Coastguard Worker
491*2d543d20SAndroid Build Coastguard Worker oom:
492*2d543d20SAndroid Build Coastguard Worker exit:
493*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&src_matches);
494*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&tgt_matches);
495*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&self_matches);
496*2d543d20SAndroid Build Coastguard Worker return rc;
497*2d543d20SAndroid Build Coastguard Worker }
498*2d543d20SAndroid Build Coastguard Worker
check_assertion_notself_match(avtab_key_t * k,avrule_t * avrule,policydb_t * p)499*2d543d20SAndroid Build Coastguard Worker static int check_assertion_notself_match(avtab_key_t *k, avrule_t *avrule, policydb_t *p)
500*2d543d20SAndroid Build Coastguard Worker {
501*2d543d20SAndroid Build Coastguard Worker ebitmap_t src_matches, tgt_matches;
502*2d543d20SAndroid Build Coastguard Worker unsigned int num_src_matches, num_tgt_matches;
503*2d543d20SAndroid Build Coastguard Worker int rc;
504*2d543d20SAndroid Build Coastguard Worker
505*2d543d20SAndroid Build Coastguard Worker ebitmap_init(&src_matches);
506*2d543d20SAndroid Build Coastguard Worker ebitmap_init(&tgt_matches);
507*2d543d20SAndroid Build Coastguard Worker
508*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(&src_matches, &avrule->stypes.types, &p->attr_type_map[k->source_type - 1]);
509*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
510*2d543d20SAndroid Build Coastguard Worker goto oom;
511*2d543d20SAndroid Build Coastguard Worker
512*2d543d20SAndroid Build Coastguard Worker if (ebitmap_is_empty(&avrule->ttypes.types)) {
513*2d543d20SAndroid Build Coastguard Worker /* avrule tgt is of the form ~self */
514*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type - 1]);
515*2d543d20SAndroid Build Coastguard Worker } else {
516*2d543d20SAndroid Build Coastguard Worker /* avrule tgt is of the form {ATTR -self} */
517*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type - 1]);
518*2d543d20SAndroid Build Coastguard Worker }
519*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
520*2d543d20SAndroid Build Coastguard Worker goto oom;
521*2d543d20SAndroid Build Coastguard Worker
522*2d543d20SAndroid Build Coastguard Worker num_src_matches = ebitmap_cardinality(&src_matches);
523*2d543d20SAndroid Build Coastguard Worker num_tgt_matches = ebitmap_cardinality(&tgt_matches);
524*2d543d20SAndroid Build Coastguard Worker if (num_src_matches == 0 || num_tgt_matches == 0) {
525*2d543d20SAndroid Build Coastguard Worker rc = 0;
526*2d543d20SAndroid Build Coastguard Worker goto nomatch;
527*2d543d20SAndroid Build Coastguard Worker }
528*2d543d20SAndroid Build Coastguard Worker if (num_src_matches == 1 && num_tgt_matches == 1) {
529*2d543d20SAndroid Build Coastguard Worker ebitmap_t matches;
530*2d543d20SAndroid Build Coastguard Worker unsigned int num_matches;
531*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(&matches, &src_matches, &tgt_matches);
532*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
533*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&matches);
534*2d543d20SAndroid Build Coastguard Worker goto oom;
535*2d543d20SAndroid Build Coastguard Worker }
536*2d543d20SAndroid Build Coastguard Worker num_matches = ebitmap_cardinality(&matches);
537*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&matches);
538*2d543d20SAndroid Build Coastguard Worker if (num_matches == 1) {
539*2d543d20SAndroid Build Coastguard Worker /* The only non-match is of the form TYPE TYPE */
540*2d543d20SAndroid Build Coastguard Worker rc = 0;
541*2d543d20SAndroid Build Coastguard Worker goto nomatch;
542*2d543d20SAndroid Build Coastguard Worker }
543*2d543d20SAndroid Build Coastguard Worker }
544*2d543d20SAndroid Build Coastguard Worker
545*2d543d20SAndroid Build Coastguard Worker rc = 1;
546*2d543d20SAndroid Build Coastguard Worker
547*2d543d20SAndroid Build Coastguard Worker oom:
548*2d543d20SAndroid Build Coastguard Worker nomatch:
549*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&src_matches);
550*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&tgt_matches);
551*2d543d20SAndroid Build Coastguard Worker return rc;
552*2d543d20SAndroid Build Coastguard Worker }
553*2d543d20SAndroid Build Coastguard Worker
check_assertion_self_match(avtab_key_t * k,avrule_t * avrule,policydb_t * p)554*2d543d20SAndroid Build Coastguard Worker static int check_assertion_self_match(avtab_key_t *k, avrule_t *avrule, policydb_t *p)
555*2d543d20SAndroid Build Coastguard Worker {
556*2d543d20SAndroid Build Coastguard Worker ebitmap_t src_matches;
557*2d543d20SAndroid Build Coastguard Worker int rc;
558*2d543d20SAndroid Build Coastguard Worker
559*2d543d20SAndroid Build Coastguard Worker /* The key's target must match something in the matches of the avrule's source
560*2d543d20SAndroid Build Coastguard Worker * and the key's source.
561*2d543d20SAndroid Build Coastguard Worker */
562*2d543d20SAndroid Build Coastguard Worker
563*2d543d20SAndroid Build Coastguard Worker rc = ebitmap_and(&src_matches, &avrule->stypes.types, &p->attr_type_map[k->source_type - 1]);
564*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
565*2d543d20SAndroid Build Coastguard Worker goto oom;
566*2d543d20SAndroid Build Coastguard Worker
567*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_match_any(&src_matches, &p->attr_type_map[k->target_type - 1])) {
568*2d543d20SAndroid Build Coastguard Worker rc = 0;
569*2d543d20SAndroid Build Coastguard Worker goto nomatch;
570*2d543d20SAndroid Build Coastguard Worker }
571*2d543d20SAndroid Build Coastguard Worker
572*2d543d20SAndroid Build Coastguard Worker rc = 1;
573*2d543d20SAndroid Build Coastguard Worker
574*2d543d20SAndroid Build Coastguard Worker oom:
575*2d543d20SAndroid Build Coastguard Worker nomatch:
576*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&src_matches);
577*2d543d20SAndroid Build Coastguard Worker return rc;
578*2d543d20SAndroid Build Coastguard Worker }
579*2d543d20SAndroid Build Coastguard Worker
check_assertion_avtab_match(avtab_key_t * k,avtab_datum_t * d,void * args)580*2d543d20SAndroid Build Coastguard Worker static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *args)
581*2d543d20SAndroid Build Coastguard Worker {
582*2d543d20SAndroid Build Coastguard Worker int rc;
583*2d543d20SAndroid Build Coastguard Worker struct avtab_match_args *a = (struct avtab_match_args *)args;
584*2d543d20SAndroid Build Coastguard Worker policydb_t *p = a->p;
585*2d543d20SAndroid Build Coastguard Worker avrule_t *avrule = a->avrule;
586*2d543d20SAndroid Build Coastguard Worker avtab_t *avtab = a->avtab;
587*2d543d20SAndroid Build Coastguard Worker
588*2d543d20SAndroid Build Coastguard Worker if ((k->specified & AVTAB_ALLOWED) == 0)
589*2d543d20SAndroid Build Coastguard Worker goto nomatch;
590*2d543d20SAndroid Build Coastguard Worker
591*2d543d20SAndroid Build Coastguard Worker if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
592*2d543d20SAndroid Build Coastguard Worker goto nomatch;
593*2d543d20SAndroid Build Coastguard Worker
594*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_match_any(&avrule->stypes.types, &p->attr_type_map[k->source_type - 1]))
595*2d543d20SAndroid Build Coastguard Worker goto nomatch;
596*2d543d20SAndroid Build Coastguard Worker
597*2d543d20SAndroid Build Coastguard Worker if (avrule->flags & RULE_NOTSELF) {
598*2d543d20SAndroid Build Coastguard Worker rc = check_assertion_notself_match(k, avrule, p);
599*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
600*2d543d20SAndroid Build Coastguard Worker goto oom;
601*2d543d20SAndroid Build Coastguard Worker if (rc == 0)
602*2d543d20SAndroid Build Coastguard Worker goto nomatch;
603*2d543d20SAndroid Build Coastguard Worker } else {
604*2d543d20SAndroid Build Coastguard Worker /* neverallow may have tgts even if it uses SELF */
605*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_match_any(&avrule->ttypes.types, &p->attr_type_map[k->target_type -1])) {
606*2d543d20SAndroid Build Coastguard Worker if (avrule->flags == RULE_SELF) {
607*2d543d20SAndroid Build Coastguard Worker rc = check_assertion_self_match(k, avrule, p);
608*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
609*2d543d20SAndroid Build Coastguard Worker goto oom;
610*2d543d20SAndroid Build Coastguard Worker if (rc == 0)
611*2d543d20SAndroid Build Coastguard Worker goto nomatch;
612*2d543d20SAndroid Build Coastguard Worker } else {
613*2d543d20SAndroid Build Coastguard Worker goto nomatch;
614*2d543d20SAndroid Build Coastguard Worker }
615*2d543d20SAndroid Build Coastguard Worker }
616*2d543d20SAndroid Build Coastguard Worker }
617*2d543d20SAndroid Build Coastguard Worker
618*2d543d20SAndroid Build Coastguard Worker if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
619*2d543d20SAndroid Build Coastguard Worker rc = check_assertion_extended_permissions(avrule, avtab, k, p);
620*2d543d20SAndroid Build Coastguard Worker if (rc < 0)
621*2d543d20SAndroid Build Coastguard Worker goto oom;
622*2d543d20SAndroid Build Coastguard Worker if (rc == 0)
623*2d543d20SAndroid Build Coastguard Worker goto nomatch;
624*2d543d20SAndroid Build Coastguard Worker }
625*2d543d20SAndroid Build Coastguard Worker return 1;
626*2d543d20SAndroid Build Coastguard Worker
627*2d543d20SAndroid Build Coastguard Worker nomatch:
628*2d543d20SAndroid Build Coastguard Worker return 0;
629*2d543d20SAndroid Build Coastguard Worker
630*2d543d20SAndroid Build Coastguard Worker oom:
631*2d543d20SAndroid Build Coastguard Worker return rc;
632*2d543d20SAndroid Build Coastguard Worker }
633*2d543d20SAndroid Build Coastguard Worker
check_assertion(policydb_t * p,avrule_t * avrule)634*2d543d20SAndroid Build Coastguard Worker int check_assertion(policydb_t *p, avrule_t *avrule)
635*2d543d20SAndroid Build Coastguard Worker {
636*2d543d20SAndroid Build Coastguard Worker int rc;
637*2d543d20SAndroid Build Coastguard Worker struct avtab_match_args args;
638*2d543d20SAndroid Build Coastguard Worker
639*2d543d20SAndroid Build Coastguard Worker args.handle = NULL;
640*2d543d20SAndroid Build Coastguard Worker args.p = p;
641*2d543d20SAndroid Build Coastguard Worker args.avrule = avrule;
642*2d543d20SAndroid Build Coastguard Worker args.errors = 0;
643*2d543d20SAndroid Build Coastguard Worker args.avtab = &p->te_avtab;
644*2d543d20SAndroid Build Coastguard Worker
645*2d543d20SAndroid Build Coastguard Worker rc = avtab_map(&p->te_avtab, check_assertion_avtab_match, &args);
646*2d543d20SAndroid Build Coastguard Worker
647*2d543d20SAndroid Build Coastguard Worker if (rc == 0) {
648*2d543d20SAndroid Build Coastguard Worker args.avtab = &p->te_cond_avtab;
649*2d543d20SAndroid Build Coastguard Worker rc = avtab_map(&p->te_cond_avtab, check_assertion_avtab_match, &args);
650*2d543d20SAndroid Build Coastguard Worker }
651*2d543d20SAndroid Build Coastguard Worker
652*2d543d20SAndroid Build Coastguard Worker return rc;
653*2d543d20SAndroid Build Coastguard Worker }
654*2d543d20SAndroid Build Coastguard Worker
check_assertions(sepol_handle_t * handle,policydb_t * p,avrule_t * avrules)655*2d543d20SAndroid Build Coastguard Worker int check_assertions(sepol_handle_t * handle, policydb_t * p,
656*2d543d20SAndroid Build Coastguard Worker avrule_t * avrules)
657*2d543d20SAndroid Build Coastguard Worker {
658*2d543d20SAndroid Build Coastguard Worker int rc;
659*2d543d20SAndroid Build Coastguard Worker avrule_t *a;
660*2d543d20SAndroid Build Coastguard Worker unsigned long errors = 0;
661*2d543d20SAndroid Build Coastguard Worker
662*2d543d20SAndroid Build Coastguard Worker if (!avrules) {
663*2d543d20SAndroid Build Coastguard Worker /* Since assertions are stored in avrules, if it is NULL
664*2d543d20SAndroid Build Coastguard Worker there won't be any to check. This also prevents an invalid
665*2d543d20SAndroid Build Coastguard Worker free if the avtabs are never initialized */
666*2d543d20SAndroid Build Coastguard Worker return 0;
667*2d543d20SAndroid Build Coastguard Worker }
668*2d543d20SAndroid Build Coastguard Worker
669*2d543d20SAndroid Build Coastguard Worker for (a = avrules; a != NULL; a = a->next) {
670*2d543d20SAndroid Build Coastguard Worker if (!(a->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW)))
671*2d543d20SAndroid Build Coastguard Worker continue;
672*2d543d20SAndroid Build Coastguard Worker rc = check_assertion(p, a);
673*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
674*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Error occurred while checking neverallows");
675*2d543d20SAndroid Build Coastguard Worker return -1;
676*2d543d20SAndroid Build Coastguard Worker }
677*2d543d20SAndroid Build Coastguard Worker if (rc) {
678*2d543d20SAndroid Build Coastguard Worker rc = report_assertion_failures(handle, p, a);
679*2d543d20SAndroid Build Coastguard Worker if (rc < 0) {
680*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Error occurred while checking neverallows");
681*2d543d20SAndroid Build Coastguard Worker return -1;
682*2d543d20SAndroid Build Coastguard Worker }
683*2d543d20SAndroid Build Coastguard Worker errors += rc;
684*2d543d20SAndroid Build Coastguard Worker }
685*2d543d20SAndroid Build Coastguard Worker }
686*2d543d20SAndroid Build Coastguard Worker
687*2d543d20SAndroid Build Coastguard Worker if (errors)
688*2d543d20SAndroid Build Coastguard Worker ERR(handle, "%lu neverallow failures occurred", errors);
689*2d543d20SAndroid Build Coastguard Worker
690*2d543d20SAndroid Build Coastguard Worker return errors ? -1 : 0;
691*2d543d20SAndroid Build Coastguard Worker }
692