1*2d543d20SAndroid Build Coastguard Worker
2*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/conditional.h>
3*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/ebitmap.h>
4*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/polcaps.h>
5*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/policydb.h>
6*2d543d20SAndroid Build Coastguard Worker #include <sepol/policydb/services.h>
7*2d543d20SAndroid Build Coastguard Worker
8*2d543d20SAndroid Build Coastguard Worker #include "debug.h"
9*2d543d20SAndroid Build Coastguard Worker #include "kernel_to_common.h"
10*2d543d20SAndroid Build Coastguard Worker #include "policydb_validate.h"
11*2d543d20SAndroid Build Coastguard Worker
12*2d543d20SAndroid Build Coastguard Worker #define bool_xor(a, b) (!(a) != !(b))
13*2d543d20SAndroid Build Coastguard Worker #define bool_xnor(a, b) (!bool_xor(a, b))
14*2d543d20SAndroid Build Coastguard Worker #define PERMISSION_MASK(nprim) ((nprim) == PERM_SYMTAB_SIZE ? (~UINT32_C(0)) : ((UINT32_C(1) << (nprim)) - 1))
15*2d543d20SAndroid Build Coastguard Worker
16*2d543d20SAndroid Build Coastguard Worker typedef struct validate {
17*2d543d20SAndroid Build Coastguard Worker uint32_t nprim;
18*2d543d20SAndroid Build Coastguard Worker ebitmap_t gaps;
19*2d543d20SAndroid Build Coastguard Worker } validate_t;
20*2d543d20SAndroid Build Coastguard Worker
21*2d543d20SAndroid Build Coastguard Worker typedef struct map_arg {
22*2d543d20SAndroid Build Coastguard Worker validate_t *flavors;
23*2d543d20SAndroid Build Coastguard Worker sepol_handle_t *handle;
24*2d543d20SAndroid Build Coastguard Worker const policydb_t *policy;
25*2d543d20SAndroid Build Coastguard Worker } map_arg_t;
26*2d543d20SAndroid Build Coastguard Worker
27*2d543d20SAndroid Build Coastguard Worker typedef struct perm_arg {
28*2d543d20SAndroid Build Coastguard Worker uint32_t visited;
29*2d543d20SAndroid Build Coastguard Worker const uint32_t nprim;
30*2d543d20SAndroid Build Coastguard Worker const uint32_t inherited_nprim;
31*2d543d20SAndroid Build Coastguard Worker } perm_arg_t;
32*2d543d20SAndroid Build Coastguard Worker
create_gap_ebitmap(char ** val_to_name,uint32_t nprim,ebitmap_t * gaps)33*2d543d20SAndroid Build Coastguard Worker static int create_gap_ebitmap(char **val_to_name, uint32_t nprim, ebitmap_t *gaps)
34*2d543d20SAndroid Build Coastguard Worker {
35*2d543d20SAndroid Build Coastguard Worker uint32_t i;
36*2d543d20SAndroid Build Coastguard Worker
37*2d543d20SAndroid Build Coastguard Worker ebitmap_init(gaps);
38*2d543d20SAndroid Build Coastguard Worker
39*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < nprim; i++) {
40*2d543d20SAndroid Build Coastguard Worker if (!val_to_name[i]) {
41*2d543d20SAndroid Build Coastguard Worker if (ebitmap_set_bit(gaps, i, 1))
42*2d543d20SAndroid Build Coastguard Worker return -1;
43*2d543d20SAndroid Build Coastguard Worker }
44*2d543d20SAndroid Build Coastguard Worker }
45*2d543d20SAndroid Build Coastguard Worker
46*2d543d20SAndroid Build Coastguard Worker return 0;
47*2d543d20SAndroid Build Coastguard Worker }
48*2d543d20SAndroid Build Coastguard Worker
validate_init(validate_t * flavor,char ** val_to_name,uint32_t nprim)49*2d543d20SAndroid Build Coastguard Worker static int validate_init(validate_t *flavor, char **val_to_name, uint32_t nprim)
50*2d543d20SAndroid Build Coastguard Worker {
51*2d543d20SAndroid Build Coastguard Worker flavor->nprim = nprim;
52*2d543d20SAndroid Build Coastguard Worker if (create_gap_ebitmap(val_to_name, nprim, &flavor->gaps))
53*2d543d20SAndroid Build Coastguard Worker return -1;
54*2d543d20SAndroid Build Coastguard Worker
55*2d543d20SAndroid Build Coastguard Worker return 0;
56*2d543d20SAndroid Build Coastguard Worker }
57*2d543d20SAndroid Build Coastguard Worker
validate_array_init(const policydb_t * p,validate_t flavors[])58*2d543d20SAndroid Build Coastguard Worker static int validate_array_init(const policydb_t *p, validate_t flavors[])
59*2d543d20SAndroid Build Coastguard Worker {
60*2d543d20SAndroid Build Coastguard Worker if (validate_init(&flavors[SYM_COMMONS], p->p_common_val_to_name, p->p_commons.nprim))
61*2d543d20SAndroid Build Coastguard Worker goto bad;
62*2d543d20SAndroid Build Coastguard Worker if (validate_init(&flavors[SYM_CLASSES], p->p_class_val_to_name, p->p_classes.nprim))
63*2d543d20SAndroid Build Coastguard Worker goto bad;
64*2d543d20SAndroid Build Coastguard Worker if (validate_init(&flavors[SYM_ROLES], p->p_role_val_to_name, p->p_roles.nprim))
65*2d543d20SAndroid Build Coastguard Worker goto bad;
66*2d543d20SAndroid Build Coastguard Worker if (p->policy_type != POLICY_KERN || p->policyvers < POLICYDB_VERSION_AVTAB || p->policyvers > POLICYDB_VERSION_PERMISSIVE) {
67*2d543d20SAndroid Build Coastguard Worker if (validate_init(&flavors[SYM_TYPES], p->p_type_val_to_name, p->p_types.nprim))
68*2d543d20SAndroid Build Coastguard Worker goto bad;
69*2d543d20SAndroid Build Coastguard Worker } else {
70*2d543d20SAndroid Build Coastguard Worker /*
71*2d543d20SAndroid Build Coastguard Worker * For policy versions between 20 and 23, attributes exist in the policy,
72*2d543d20SAndroid Build Coastguard Worker * but they only exist in the type_attr_map, so there will be references
73*2d543d20SAndroid Build Coastguard Worker * to gaps and we just have to treat this case as if there were no gaps.
74*2d543d20SAndroid Build Coastguard Worker */
75*2d543d20SAndroid Build Coastguard Worker flavors[SYM_TYPES].nprim = p->p_types.nprim;
76*2d543d20SAndroid Build Coastguard Worker ebitmap_init(&flavors[SYM_TYPES].gaps);
77*2d543d20SAndroid Build Coastguard Worker }
78*2d543d20SAndroid Build Coastguard Worker if (validate_init(&flavors[SYM_USERS], p->p_user_val_to_name, p->p_users.nprim))
79*2d543d20SAndroid Build Coastguard Worker goto bad;
80*2d543d20SAndroid Build Coastguard Worker if (validate_init(&flavors[SYM_BOOLS], p->p_bool_val_to_name, p->p_bools.nprim))
81*2d543d20SAndroid Build Coastguard Worker goto bad;
82*2d543d20SAndroid Build Coastguard Worker if (validate_init(&flavors[SYM_LEVELS], p->p_sens_val_to_name, p->p_levels.nprim))
83*2d543d20SAndroid Build Coastguard Worker goto bad;
84*2d543d20SAndroid Build Coastguard Worker if (validate_init(&flavors[SYM_CATS], p->p_cat_val_to_name, p->p_cats.nprim))
85*2d543d20SAndroid Build Coastguard Worker goto bad;
86*2d543d20SAndroid Build Coastguard Worker
87*2d543d20SAndroid Build Coastguard Worker return 0;
88*2d543d20SAndroid Build Coastguard Worker
89*2d543d20SAndroid Build Coastguard Worker bad:
90*2d543d20SAndroid Build Coastguard Worker return -1;
91*2d543d20SAndroid Build Coastguard Worker }
92*2d543d20SAndroid Build Coastguard Worker
93*2d543d20SAndroid Build Coastguard Worker /*
94*2d543d20SAndroid Build Coastguard Worker * Functions to validate both kernel and module policydbs
95*2d543d20SAndroid Build Coastguard Worker */
96*2d543d20SAndroid Build Coastguard Worker
value_isvalid(uint32_t value,uint32_t nprim)97*2d543d20SAndroid Build Coastguard Worker int value_isvalid(uint32_t value, uint32_t nprim)
98*2d543d20SAndroid Build Coastguard Worker {
99*2d543d20SAndroid Build Coastguard Worker if (!value || value > nprim)
100*2d543d20SAndroid Build Coastguard Worker return 0;
101*2d543d20SAndroid Build Coastguard Worker
102*2d543d20SAndroid Build Coastguard Worker return 1;
103*2d543d20SAndroid Build Coastguard Worker }
104*2d543d20SAndroid Build Coastguard Worker
validate_value(uint32_t value,const validate_t * flavor)105*2d543d20SAndroid Build Coastguard Worker static int validate_value(uint32_t value, const validate_t *flavor)
106*2d543d20SAndroid Build Coastguard Worker {
107*2d543d20SAndroid Build Coastguard Worker if (!value || value > flavor->nprim)
108*2d543d20SAndroid Build Coastguard Worker goto bad;
109*2d543d20SAndroid Build Coastguard Worker if (ebitmap_get_bit(&flavor->gaps, value-1))
110*2d543d20SAndroid Build Coastguard Worker goto bad;
111*2d543d20SAndroid Build Coastguard Worker
112*2d543d20SAndroid Build Coastguard Worker return 0;
113*2d543d20SAndroid Build Coastguard Worker
114*2d543d20SAndroid Build Coastguard Worker bad:
115*2d543d20SAndroid Build Coastguard Worker return -1;
116*2d543d20SAndroid Build Coastguard Worker }
117*2d543d20SAndroid Build Coastguard Worker
validate_ebitmap(const ebitmap_t * map,const validate_t * flavor)118*2d543d20SAndroid Build Coastguard Worker static int validate_ebitmap(const ebitmap_t *map, const validate_t *flavor)
119*2d543d20SAndroid Build Coastguard Worker {
120*2d543d20SAndroid Build Coastguard Worker if (ebitmap_length(map) > 0 && ebitmap_highest_set_bit(map) >= flavor->nprim)
121*2d543d20SAndroid Build Coastguard Worker goto bad;
122*2d543d20SAndroid Build Coastguard Worker if (ebitmap_match_any(map, &flavor->gaps))
123*2d543d20SAndroid Build Coastguard Worker goto bad;
124*2d543d20SAndroid Build Coastguard Worker
125*2d543d20SAndroid Build Coastguard Worker return 0;
126*2d543d20SAndroid Build Coastguard Worker
127*2d543d20SAndroid Build Coastguard Worker bad:
128*2d543d20SAndroid Build Coastguard Worker return -1;
129*2d543d20SAndroid Build Coastguard Worker }
130*2d543d20SAndroid Build Coastguard Worker
validate_type_set(const type_set_t * type_set,const validate_t * type)131*2d543d20SAndroid Build Coastguard Worker static int validate_type_set(const type_set_t *type_set, const validate_t *type)
132*2d543d20SAndroid Build Coastguard Worker {
133*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&type_set->types, type))
134*2d543d20SAndroid Build Coastguard Worker goto bad;
135*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&type_set->negset, type))
136*2d543d20SAndroid Build Coastguard Worker goto bad;
137*2d543d20SAndroid Build Coastguard Worker
138*2d543d20SAndroid Build Coastguard Worker switch (type_set->flags) {
139*2d543d20SAndroid Build Coastguard Worker case 0:
140*2d543d20SAndroid Build Coastguard Worker case TYPE_STAR:
141*2d543d20SAndroid Build Coastguard Worker case TYPE_COMP:
142*2d543d20SAndroid Build Coastguard Worker break;
143*2d543d20SAndroid Build Coastguard Worker default:
144*2d543d20SAndroid Build Coastguard Worker goto bad;
145*2d543d20SAndroid Build Coastguard Worker }
146*2d543d20SAndroid Build Coastguard Worker
147*2d543d20SAndroid Build Coastguard Worker return 0;
148*2d543d20SAndroid Build Coastguard Worker
149*2d543d20SAndroid Build Coastguard Worker bad:
150*2d543d20SAndroid Build Coastguard Worker return -1;
151*2d543d20SAndroid Build Coastguard Worker }
152*2d543d20SAndroid Build Coastguard Worker
validate_empty_type_set(const type_set_t * type_set)153*2d543d20SAndroid Build Coastguard Worker static int validate_empty_type_set(const type_set_t *type_set)
154*2d543d20SAndroid Build Coastguard Worker {
155*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&type_set->types))
156*2d543d20SAndroid Build Coastguard Worker goto bad;
157*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&type_set->negset))
158*2d543d20SAndroid Build Coastguard Worker goto bad;
159*2d543d20SAndroid Build Coastguard Worker if (type_set->flags != 0)
160*2d543d20SAndroid Build Coastguard Worker goto bad;
161*2d543d20SAndroid Build Coastguard Worker
162*2d543d20SAndroid Build Coastguard Worker return 0;
163*2d543d20SAndroid Build Coastguard Worker
164*2d543d20SAndroid Build Coastguard Worker bad:
165*2d543d20SAndroid Build Coastguard Worker return -1;
166*2d543d20SAndroid Build Coastguard Worker }
167*2d543d20SAndroid Build Coastguard Worker
validate_role_set(const role_set_t * role_set,const validate_t * role)168*2d543d20SAndroid Build Coastguard Worker static int validate_role_set(const role_set_t *role_set, const validate_t *role)
169*2d543d20SAndroid Build Coastguard Worker {
170*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&role_set->roles, role))
171*2d543d20SAndroid Build Coastguard Worker goto bad;
172*2d543d20SAndroid Build Coastguard Worker
173*2d543d20SAndroid Build Coastguard Worker switch (role_set->flags) {
174*2d543d20SAndroid Build Coastguard Worker case 0:
175*2d543d20SAndroid Build Coastguard Worker case ROLE_STAR:
176*2d543d20SAndroid Build Coastguard Worker case ROLE_COMP:
177*2d543d20SAndroid Build Coastguard Worker break;
178*2d543d20SAndroid Build Coastguard Worker default:
179*2d543d20SAndroid Build Coastguard Worker goto bad;
180*2d543d20SAndroid Build Coastguard Worker }
181*2d543d20SAndroid Build Coastguard Worker
182*2d543d20SAndroid Build Coastguard Worker return 0;
183*2d543d20SAndroid Build Coastguard Worker
184*2d543d20SAndroid Build Coastguard Worker bad:
185*2d543d20SAndroid Build Coastguard Worker return -1;
186*2d543d20SAndroid Build Coastguard Worker }
187*2d543d20SAndroid Build Coastguard Worker
validate_scope(hashtab_key_t k,hashtab_datum_t d,void * args)188*2d543d20SAndroid Build Coastguard Worker static int validate_scope(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
189*2d543d20SAndroid Build Coastguard Worker {
190*2d543d20SAndroid Build Coastguard Worker const scope_datum_t *scope_datum = (scope_datum_t *)d;
191*2d543d20SAndroid Build Coastguard Worker const uint32_t *nprim = (uint32_t *)args;
192*2d543d20SAndroid Build Coastguard Worker uint32_t i;
193*2d543d20SAndroid Build Coastguard Worker
194*2d543d20SAndroid Build Coastguard Worker switch (scope_datum->scope) {
195*2d543d20SAndroid Build Coastguard Worker case SCOPE_REQ:
196*2d543d20SAndroid Build Coastguard Worker case SCOPE_DECL:
197*2d543d20SAndroid Build Coastguard Worker break;
198*2d543d20SAndroid Build Coastguard Worker default:
199*2d543d20SAndroid Build Coastguard Worker goto bad;
200*2d543d20SAndroid Build Coastguard Worker }
201*2d543d20SAndroid Build Coastguard Worker
202*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < scope_datum->decl_ids_len; i++) {
203*2d543d20SAndroid Build Coastguard Worker if (!value_isvalid(scope_datum->decl_ids[i], *nprim))
204*2d543d20SAndroid Build Coastguard Worker goto bad;
205*2d543d20SAndroid Build Coastguard Worker }
206*2d543d20SAndroid Build Coastguard Worker
207*2d543d20SAndroid Build Coastguard Worker return 0;
208*2d543d20SAndroid Build Coastguard Worker
209*2d543d20SAndroid Build Coastguard Worker bad:
210*2d543d20SAndroid Build Coastguard Worker return -1;
211*2d543d20SAndroid Build Coastguard Worker }
212*2d543d20SAndroid Build Coastguard Worker
validate_scopes(sepol_handle_t * handle,const symtab_t scopes[],const avrule_block_t * block)213*2d543d20SAndroid Build Coastguard Worker static int validate_scopes(sepol_handle_t *handle, const symtab_t scopes[], const avrule_block_t *block)
214*2d543d20SAndroid Build Coastguard Worker {
215*2d543d20SAndroid Build Coastguard Worker const avrule_decl_t *decl;
216*2d543d20SAndroid Build Coastguard Worker unsigned int i;
217*2d543d20SAndroid Build Coastguard Worker uint32_t num_decls = 0;
218*2d543d20SAndroid Build Coastguard Worker
219*2d543d20SAndroid Build Coastguard Worker for (; block != NULL; block = block->next) {
220*2d543d20SAndroid Build Coastguard Worker for (decl = block->branch_list; decl; decl = decl->next) {
221*2d543d20SAndroid Build Coastguard Worker num_decls++;
222*2d543d20SAndroid Build Coastguard Worker }
223*2d543d20SAndroid Build Coastguard Worker }
224*2d543d20SAndroid Build Coastguard Worker
225*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < SYM_NUM; i++) {
226*2d543d20SAndroid Build Coastguard Worker if (hashtab_map(scopes[i].table, validate_scope, &num_decls))
227*2d543d20SAndroid Build Coastguard Worker goto bad;
228*2d543d20SAndroid Build Coastguard Worker }
229*2d543d20SAndroid Build Coastguard Worker
230*2d543d20SAndroid Build Coastguard Worker return 0;
231*2d543d20SAndroid Build Coastguard Worker
232*2d543d20SAndroid Build Coastguard Worker bad:
233*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid scope");
234*2d543d20SAndroid Build Coastguard Worker return -1;
235*2d543d20SAndroid Build Coastguard Worker }
236*2d543d20SAndroid Build Coastguard Worker
validate_constraint_nodes(sepol_handle_t * handle,uint32_t nperms,const constraint_node_t * cons,validate_t flavors[])237*2d543d20SAndroid Build Coastguard Worker static int validate_constraint_nodes(sepol_handle_t *handle, uint32_t nperms, const constraint_node_t *cons, validate_t flavors[])
238*2d543d20SAndroid Build Coastguard Worker {
239*2d543d20SAndroid Build Coastguard Worker const constraint_expr_t *cexp;
240*2d543d20SAndroid Build Coastguard Worker const int is_validatetrans = (nperms == UINT32_MAX);
241*2d543d20SAndroid Build Coastguard Worker int depth;
242*2d543d20SAndroid Build Coastguard Worker
243*2d543d20SAndroid Build Coastguard Worker if (cons && nperms == 0)
244*2d543d20SAndroid Build Coastguard Worker goto bad;
245*2d543d20SAndroid Build Coastguard Worker
246*2d543d20SAndroid Build Coastguard Worker for (; cons; cons = cons->next) {
247*2d543d20SAndroid Build Coastguard Worker if (is_validatetrans && cons->permissions != 0)
248*2d543d20SAndroid Build Coastguard Worker goto bad;
249*2d543d20SAndroid Build Coastguard Worker if (!is_validatetrans && cons->permissions == 0)
250*2d543d20SAndroid Build Coastguard Worker goto bad;
251*2d543d20SAndroid Build Coastguard Worker if (!is_validatetrans && nperms != PERM_SYMTAB_SIZE && cons->permissions >= (UINT32_C(1) << nperms))
252*2d543d20SAndroid Build Coastguard Worker goto bad;
253*2d543d20SAndroid Build Coastguard Worker
254*2d543d20SAndroid Build Coastguard Worker if (!cons->expr)
255*2d543d20SAndroid Build Coastguard Worker goto bad;
256*2d543d20SAndroid Build Coastguard Worker
257*2d543d20SAndroid Build Coastguard Worker depth = -1;
258*2d543d20SAndroid Build Coastguard Worker
259*2d543d20SAndroid Build Coastguard Worker for (cexp = cons->expr; cexp; cexp = cexp->next) {
260*2d543d20SAndroid Build Coastguard Worker if (cexp->expr_type == CEXPR_NAMES) {
261*2d543d20SAndroid Build Coastguard Worker if (depth >= (CEXPR_MAXDEPTH - 1))
262*2d543d20SAndroid Build Coastguard Worker goto bad;
263*2d543d20SAndroid Build Coastguard Worker depth++;
264*2d543d20SAndroid Build Coastguard Worker
265*2d543d20SAndroid Build Coastguard Worker if (cexp->attr & CEXPR_XTARGET && !is_validatetrans)
266*2d543d20SAndroid Build Coastguard Worker goto bad;
267*2d543d20SAndroid Build Coastguard Worker if (!(cexp->attr & CEXPR_TYPE)) {
268*2d543d20SAndroid Build Coastguard Worker if (validate_empty_type_set(cexp->type_names))
269*2d543d20SAndroid Build Coastguard Worker goto bad;
270*2d543d20SAndroid Build Coastguard Worker }
271*2d543d20SAndroid Build Coastguard Worker
272*2d543d20SAndroid Build Coastguard Worker switch (cexp->op) {
273*2d543d20SAndroid Build Coastguard Worker case CEXPR_EQ:
274*2d543d20SAndroid Build Coastguard Worker case CEXPR_NEQ:
275*2d543d20SAndroid Build Coastguard Worker break;
276*2d543d20SAndroid Build Coastguard Worker default:
277*2d543d20SAndroid Build Coastguard Worker goto bad;
278*2d543d20SAndroid Build Coastguard Worker }
279*2d543d20SAndroid Build Coastguard Worker
280*2d543d20SAndroid Build Coastguard Worker switch (cexp->attr) {
281*2d543d20SAndroid Build Coastguard Worker case CEXPR_USER:
282*2d543d20SAndroid Build Coastguard Worker case CEXPR_USER | CEXPR_TARGET:
283*2d543d20SAndroid Build Coastguard Worker case CEXPR_USER | CEXPR_XTARGET:
284*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&cexp->names, &flavors[SYM_USERS]))
285*2d543d20SAndroid Build Coastguard Worker goto bad;
286*2d543d20SAndroid Build Coastguard Worker break;
287*2d543d20SAndroid Build Coastguard Worker case CEXPR_ROLE:
288*2d543d20SAndroid Build Coastguard Worker case CEXPR_ROLE | CEXPR_TARGET:
289*2d543d20SAndroid Build Coastguard Worker case CEXPR_ROLE | CEXPR_XTARGET:
290*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&cexp->names, &flavors[SYM_ROLES]))
291*2d543d20SAndroid Build Coastguard Worker goto bad;
292*2d543d20SAndroid Build Coastguard Worker break;
293*2d543d20SAndroid Build Coastguard Worker case CEXPR_TYPE:
294*2d543d20SAndroid Build Coastguard Worker case CEXPR_TYPE | CEXPR_TARGET:
295*2d543d20SAndroid Build Coastguard Worker case CEXPR_TYPE | CEXPR_XTARGET:
296*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&cexp->names, &flavors[SYM_TYPES]))
297*2d543d20SAndroid Build Coastguard Worker goto bad;
298*2d543d20SAndroid Build Coastguard Worker if (validate_type_set(cexp->type_names, &flavors[SYM_TYPES]))
299*2d543d20SAndroid Build Coastguard Worker goto bad;
300*2d543d20SAndroid Build Coastguard Worker break;
301*2d543d20SAndroid Build Coastguard Worker default:
302*2d543d20SAndroid Build Coastguard Worker goto bad;
303*2d543d20SAndroid Build Coastguard Worker }
304*2d543d20SAndroid Build Coastguard Worker } else if (cexp->expr_type == CEXPR_ATTR) {
305*2d543d20SAndroid Build Coastguard Worker if (depth >= (CEXPR_MAXDEPTH - 1))
306*2d543d20SAndroid Build Coastguard Worker goto bad;
307*2d543d20SAndroid Build Coastguard Worker depth++;
308*2d543d20SAndroid Build Coastguard Worker
309*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&cexp->names))
310*2d543d20SAndroid Build Coastguard Worker goto bad;
311*2d543d20SAndroid Build Coastguard Worker if (validate_empty_type_set(cexp->type_names))
312*2d543d20SAndroid Build Coastguard Worker goto bad;
313*2d543d20SAndroid Build Coastguard Worker
314*2d543d20SAndroid Build Coastguard Worker switch (cexp->op) {
315*2d543d20SAndroid Build Coastguard Worker case CEXPR_EQ:
316*2d543d20SAndroid Build Coastguard Worker case CEXPR_NEQ:
317*2d543d20SAndroid Build Coastguard Worker break;
318*2d543d20SAndroid Build Coastguard Worker case CEXPR_DOM:
319*2d543d20SAndroid Build Coastguard Worker case CEXPR_DOMBY:
320*2d543d20SAndroid Build Coastguard Worker case CEXPR_INCOMP:
321*2d543d20SAndroid Build Coastguard Worker if ((cexp->attr & CEXPR_USER) || (cexp->attr & CEXPR_TYPE))
322*2d543d20SAndroid Build Coastguard Worker goto bad;
323*2d543d20SAndroid Build Coastguard Worker break;
324*2d543d20SAndroid Build Coastguard Worker default:
325*2d543d20SAndroid Build Coastguard Worker goto bad;
326*2d543d20SAndroid Build Coastguard Worker }
327*2d543d20SAndroid Build Coastguard Worker
328*2d543d20SAndroid Build Coastguard Worker switch (cexp->attr) {
329*2d543d20SAndroid Build Coastguard Worker case CEXPR_USER:
330*2d543d20SAndroid Build Coastguard Worker case CEXPR_ROLE:
331*2d543d20SAndroid Build Coastguard Worker case CEXPR_TYPE:
332*2d543d20SAndroid Build Coastguard Worker case CEXPR_L1L2:
333*2d543d20SAndroid Build Coastguard Worker case CEXPR_L1H2:
334*2d543d20SAndroid Build Coastguard Worker case CEXPR_H1L2:
335*2d543d20SAndroid Build Coastguard Worker case CEXPR_H1H2:
336*2d543d20SAndroid Build Coastguard Worker case CEXPR_L1H1:
337*2d543d20SAndroid Build Coastguard Worker case CEXPR_L2H2:
338*2d543d20SAndroid Build Coastguard Worker break;
339*2d543d20SAndroid Build Coastguard Worker default:
340*2d543d20SAndroid Build Coastguard Worker goto bad;
341*2d543d20SAndroid Build Coastguard Worker }
342*2d543d20SAndroid Build Coastguard Worker } else {
343*2d543d20SAndroid Build Coastguard Worker switch (cexp->expr_type) {
344*2d543d20SAndroid Build Coastguard Worker case CEXPR_NOT:
345*2d543d20SAndroid Build Coastguard Worker if (depth < 0)
346*2d543d20SAndroid Build Coastguard Worker goto bad;
347*2d543d20SAndroid Build Coastguard Worker break;
348*2d543d20SAndroid Build Coastguard Worker case CEXPR_AND:
349*2d543d20SAndroid Build Coastguard Worker case CEXPR_OR:
350*2d543d20SAndroid Build Coastguard Worker if (depth < 1)
351*2d543d20SAndroid Build Coastguard Worker goto bad;
352*2d543d20SAndroid Build Coastguard Worker depth--;
353*2d543d20SAndroid Build Coastguard Worker break;
354*2d543d20SAndroid Build Coastguard Worker default:
355*2d543d20SAndroid Build Coastguard Worker goto bad;
356*2d543d20SAndroid Build Coastguard Worker }
357*2d543d20SAndroid Build Coastguard Worker
358*2d543d20SAndroid Build Coastguard Worker if (cexp->op != 0)
359*2d543d20SAndroid Build Coastguard Worker goto bad;
360*2d543d20SAndroid Build Coastguard Worker if (cexp->attr != 0)
361*2d543d20SAndroid Build Coastguard Worker goto bad;
362*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&cexp->names))
363*2d543d20SAndroid Build Coastguard Worker goto bad;
364*2d543d20SAndroid Build Coastguard Worker if (validate_empty_type_set(cexp->type_names))
365*2d543d20SAndroid Build Coastguard Worker goto bad;
366*2d543d20SAndroid Build Coastguard Worker }
367*2d543d20SAndroid Build Coastguard Worker }
368*2d543d20SAndroid Build Coastguard Worker
369*2d543d20SAndroid Build Coastguard Worker if (depth != 0)
370*2d543d20SAndroid Build Coastguard Worker goto bad;
371*2d543d20SAndroid Build Coastguard Worker }
372*2d543d20SAndroid Build Coastguard Worker
373*2d543d20SAndroid Build Coastguard Worker return 0;
374*2d543d20SAndroid Build Coastguard Worker
375*2d543d20SAndroid Build Coastguard Worker bad:
376*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid constraint expr");
377*2d543d20SAndroid Build Coastguard Worker return -1;
378*2d543d20SAndroid Build Coastguard Worker }
379*2d543d20SAndroid Build Coastguard Worker
perm_visit(hashtab_key_t k,hashtab_datum_t d,void * args)380*2d543d20SAndroid Build Coastguard Worker static int perm_visit(__attribute__((__unused__)) hashtab_key_t k, hashtab_datum_t d, void *args)
381*2d543d20SAndroid Build Coastguard Worker {
382*2d543d20SAndroid Build Coastguard Worker perm_arg_t *pargs = args;
383*2d543d20SAndroid Build Coastguard Worker const perm_datum_t *perdatum = d;
384*2d543d20SAndroid Build Coastguard Worker
385*2d543d20SAndroid Build Coastguard Worker if (!value_isvalid(perdatum->s.value, pargs->nprim))
386*2d543d20SAndroid Build Coastguard Worker return -1;
387*2d543d20SAndroid Build Coastguard Worker
388*2d543d20SAndroid Build Coastguard Worker if (pargs->inherited_nprim != 0 && value_isvalid(perdatum->s.value, pargs->inherited_nprim))
389*2d543d20SAndroid Build Coastguard Worker return -1;
390*2d543d20SAndroid Build Coastguard Worker
391*2d543d20SAndroid Build Coastguard Worker if ((UINT32_C(1) << (perdatum->s.value - 1)) & pargs->visited)
392*2d543d20SAndroid Build Coastguard Worker return -1;
393*2d543d20SAndroid Build Coastguard Worker
394*2d543d20SAndroid Build Coastguard Worker pargs->visited |= (UINT32_C(1) << (perdatum->s.value - 1));
395*2d543d20SAndroid Build Coastguard Worker return 0;
396*2d543d20SAndroid Build Coastguard Worker }
397*2d543d20SAndroid Build Coastguard Worker
validate_permission_symtab(sepol_handle_t * handle,const symtab_t * permissions,uint32_t inherited_nprim)398*2d543d20SAndroid Build Coastguard Worker static int validate_permission_symtab(sepol_handle_t *handle, const symtab_t *permissions, uint32_t inherited_nprim)
399*2d543d20SAndroid Build Coastguard Worker {
400*2d543d20SAndroid Build Coastguard Worker /* Check each entry has a different valid value and is not overriding an inherited one */
401*2d543d20SAndroid Build Coastguard Worker
402*2d543d20SAndroid Build Coastguard Worker perm_arg_t pargs = { .visited = 0, .nprim = permissions->nprim, .inherited_nprim = inherited_nprim };
403*2d543d20SAndroid Build Coastguard Worker
404*2d543d20SAndroid Build Coastguard Worker if (hashtab_map(permissions->table, perm_visit, &pargs))
405*2d543d20SAndroid Build Coastguard Worker goto bad;
406*2d543d20SAndroid Build Coastguard Worker
407*2d543d20SAndroid Build Coastguard Worker return 0;
408*2d543d20SAndroid Build Coastguard Worker
409*2d543d20SAndroid Build Coastguard Worker bad:
410*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid permission table");
411*2d543d20SAndroid Build Coastguard Worker return -1;
412*2d543d20SAndroid Build Coastguard Worker }
413*2d543d20SAndroid Build Coastguard Worker
validate_common_datum(sepol_handle_t * handle,const common_datum_t * common,validate_t flavors[])414*2d543d20SAndroid Build Coastguard Worker static int validate_common_datum(sepol_handle_t *handle, const common_datum_t *common, validate_t flavors[])
415*2d543d20SAndroid Build Coastguard Worker {
416*2d543d20SAndroid Build Coastguard Worker if (validate_value(common->s.value, &flavors[SYM_COMMONS]))
417*2d543d20SAndroid Build Coastguard Worker goto bad;
418*2d543d20SAndroid Build Coastguard Worker if (common->permissions.nprim == 0 || common->permissions.nprim > PERM_SYMTAB_SIZE)
419*2d543d20SAndroid Build Coastguard Worker goto bad;
420*2d543d20SAndroid Build Coastguard Worker if (common->permissions.nprim != common->permissions.table->nel)
421*2d543d20SAndroid Build Coastguard Worker goto bad;
422*2d543d20SAndroid Build Coastguard Worker if (validate_permission_symtab(handle, &common->permissions, 0))
423*2d543d20SAndroid Build Coastguard Worker goto bad;
424*2d543d20SAndroid Build Coastguard Worker
425*2d543d20SAndroid Build Coastguard Worker return 0;
426*2d543d20SAndroid Build Coastguard Worker
427*2d543d20SAndroid Build Coastguard Worker bad:
428*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid common class datum");
429*2d543d20SAndroid Build Coastguard Worker return -1;
430*2d543d20SAndroid Build Coastguard Worker }
431*2d543d20SAndroid Build Coastguard Worker
validate_common_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)432*2d543d20SAndroid Build Coastguard Worker static int validate_common_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
433*2d543d20SAndroid Build Coastguard Worker {
434*2d543d20SAndroid Build Coastguard Worker map_arg_t *margs = args;
435*2d543d20SAndroid Build Coastguard Worker
436*2d543d20SAndroid Build Coastguard Worker return validate_common_datum(margs->handle, d, margs->flavors);
437*2d543d20SAndroid Build Coastguard Worker }
438*2d543d20SAndroid Build Coastguard Worker
validate_class_datum(sepol_handle_t * handle,const class_datum_t * class,validate_t flavors[])439*2d543d20SAndroid Build Coastguard Worker static int validate_class_datum(sepol_handle_t *handle, const class_datum_t *class, validate_t flavors[])
440*2d543d20SAndroid Build Coastguard Worker {
441*2d543d20SAndroid Build Coastguard Worker if (class->s.value > UINT16_MAX || validate_value(class->s.value, &flavors[SYM_CLASSES]))
442*2d543d20SAndroid Build Coastguard Worker goto bad;
443*2d543d20SAndroid Build Coastguard Worker if (class->comdatum && validate_common_datum(handle, class->comdatum, flavors))
444*2d543d20SAndroid Build Coastguard Worker goto bad;
445*2d543d20SAndroid Build Coastguard Worker /* empty classes are permitted */
446*2d543d20SAndroid Build Coastguard Worker if (class->permissions.nprim > PERM_SYMTAB_SIZE || class->permissions.table->nel > PERM_SYMTAB_SIZE)
447*2d543d20SAndroid Build Coastguard Worker goto bad;
448*2d543d20SAndroid Build Coastguard Worker if (class->permissions.nprim !=
449*2d543d20SAndroid Build Coastguard Worker (class->permissions.table->nel + (class->comdatum ? class->comdatum->permissions.table->nel : 0)))
450*2d543d20SAndroid Build Coastguard Worker goto bad;
451*2d543d20SAndroid Build Coastguard Worker if (validate_permission_symtab(handle, &class->permissions, class->comdatum ? class->comdatum->permissions.nprim : 0))
452*2d543d20SAndroid Build Coastguard Worker goto bad;
453*2d543d20SAndroid Build Coastguard Worker if (validate_constraint_nodes(handle, class->permissions.nprim, class->constraints, flavors))
454*2d543d20SAndroid Build Coastguard Worker goto bad;
455*2d543d20SAndroid Build Coastguard Worker if (validate_constraint_nodes(handle, UINT32_MAX, class->validatetrans, flavors))
456*2d543d20SAndroid Build Coastguard Worker goto bad;
457*2d543d20SAndroid Build Coastguard Worker
458*2d543d20SAndroid Build Coastguard Worker switch (class->default_user) {
459*2d543d20SAndroid Build Coastguard Worker case 0:
460*2d543d20SAndroid Build Coastguard Worker case DEFAULT_SOURCE:
461*2d543d20SAndroid Build Coastguard Worker case DEFAULT_TARGET:
462*2d543d20SAndroid Build Coastguard Worker break;
463*2d543d20SAndroid Build Coastguard Worker default:
464*2d543d20SAndroid Build Coastguard Worker goto bad;
465*2d543d20SAndroid Build Coastguard Worker }
466*2d543d20SAndroid Build Coastguard Worker
467*2d543d20SAndroid Build Coastguard Worker switch (class->default_role) {
468*2d543d20SAndroid Build Coastguard Worker case 0:
469*2d543d20SAndroid Build Coastguard Worker case DEFAULT_SOURCE:
470*2d543d20SAndroid Build Coastguard Worker case DEFAULT_TARGET:
471*2d543d20SAndroid Build Coastguard Worker break;
472*2d543d20SAndroid Build Coastguard Worker default:
473*2d543d20SAndroid Build Coastguard Worker goto bad;
474*2d543d20SAndroid Build Coastguard Worker }
475*2d543d20SAndroid Build Coastguard Worker
476*2d543d20SAndroid Build Coastguard Worker switch (class->default_type) {
477*2d543d20SAndroid Build Coastguard Worker case 0:
478*2d543d20SAndroid Build Coastguard Worker case DEFAULT_SOURCE:
479*2d543d20SAndroid Build Coastguard Worker case DEFAULT_TARGET:
480*2d543d20SAndroid Build Coastguard Worker break;
481*2d543d20SAndroid Build Coastguard Worker default:
482*2d543d20SAndroid Build Coastguard Worker goto bad;
483*2d543d20SAndroid Build Coastguard Worker }
484*2d543d20SAndroid Build Coastguard Worker
485*2d543d20SAndroid Build Coastguard Worker switch (class->default_range) {
486*2d543d20SAndroid Build Coastguard Worker case 0:
487*2d543d20SAndroid Build Coastguard Worker case DEFAULT_SOURCE_LOW:
488*2d543d20SAndroid Build Coastguard Worker case DEFAULT_SOURCE_HIGH:
489*2d543d20SAndroid Build Coastguard Worker case DEFAULT_SOURCE_LOW_HIGH:
490*2d543d20SAndroid Build Coastguard Worker case DEFAULT_TARGET_LOW:
491*2d543d20SAndroid Build Coastguard Worker case DEFAULT_TARGET_HIGH:
492*2d543d20SAndroid Build Coastguard Worker case DEFAULT_TARGET_LOW_HIGH:
493*2d543d20SAndroid Build Coastguard Worker case DEFAULT_GLBLUB:
494*2d543d20SAndroid Build Coastguard Worker break;
495*2d543d20SAndroid Build Coastguard Worker default:
496*2d543d20SAndroid Build Coastguard Worker goto bad;
497*2d543d20SAndroid Build Coastguard Worker }
498*2d543d20SAndroid Build Coastguard Worker
499*2d543d20SAndroid Build Coastguard Worker return 0;
500*2d543d20SAndroid Build Coastguard Worker
501*2d543d20SAndroid Build Coastguard Worker bad:
502*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid class datum");
503*2d543d20SAndroid Build Coastguard Worker return -1;
504*2d543d20SAndroid Build Coastguard Worker }
505*2d543d20SAndroid Build Coastguard Worker
validate_class_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)506*2d543d20SAndroid Build Coastguard Worker static int validate_class_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
507*2d543d20SAndroid Build Coastguard Worker {
508*2d543d20SAndroid Build Coastguard Worker map_arg_t *margs = args;
509*2d543d20SAndroid Build Coastguard Worker
510*2d543d20SAndroid Build Coastguard Worker return validate_class_datum(margs->handle, d, margs->flavors);
511*2d543d20SAndroid Build Coastguard Worker }
512*2d543d20SAndroid Build Coastguard Worker
validate_role_datum(sepol_handle_t * handle,const role_datum_t * role,validate_t flavors[])513*2d543d20SAndroid Build Coastguard Worker static int validate_role_datum(sepol_handle_t *handle, const role_datum_t *role, validate_t flavors[])
514*2d543d20SAndroid Build Coastguard Worker {
515*2d543d20SAndroid Build Coastguard Worker if (validate_value(role->s.value, &flavors[SYM_ROLES]))
516*2d543d20SAndroid Build Coastguard Worker goto bad;
517*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&role->dominates, &flavors[SYM_ROLES]))
518*2d543d20SAndroid Build Coastguard Worker goto bad;
519*2d543d20SAndroid Build Coastguard Worker if (validate_type_set(&role->types, &flavors[SYM_TYPES]))
520*2d543d20SAndroid Build Coastguard Worker goto bad;
521*2d543d20SAndroid Build Coastguard Worker if (role->bounds && validate_value(role->bounds, &flavors[SYM_ROLES]))
522*2d543d20SAndroid Build Coastguard Worker goto bad;
523*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&role->roles, &flavors[SYM_ROLES]))
524*2d543d20SAndroid Build Coastguard Worker goto bad;
525*2d543d20SAndroid Build Coastguard Worker
526*2d543d20SAndroid Build Coastguard Worker switch(role->flavor) {
527*2d543d20SAndroid Build Coastguard Worker case ROLE_ROLE:
528*2d543d20SAndroid Build Coastguard Worker case ROLE_ATTRIB:
529*2d543d20SAndroid Build Coastguard Worker break;
530*2d543d20SAndroid Build Coastguard Worker default:
531*2d543d20SAndroid Build Coastguard Worker goto bad;
532*2d543d20SAndroid Build Coastguard Worker }
533*2d543d20SAndroid Build Coastguard Worker
534*2d543d20SAndroid Build Coastguard Worker return 0;
535*2d543d20SAndroid Build Coastguard Worker
536*2d543d20SAndroid Build Coastguard Worker bad:
537*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid role datum");
538*2d543d20SAndroid Build Coastguard Worker return -1;
539*2d543d20SAndroid Build Coastguard Worker }
540*2d543d20SAndroid Build Coastguard Worker
validate_role_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)541*2d543d20SAndroid Build Coastguard Worker static int validate_role_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
542*2d543d20SAndroid Build Coastguard Worker {
543*2d543d20SAndroid Build Coastguard Worker map_arg_t *margs = args;
544*2d543d20SAndroid Build Coastguard Worker
545*2d543d20SAndroid Build Coastguard Worker return validate_role_datum(margs->handle, d, margs->flavors);
546*2d543d20SAndroid Build Coastguard Worker }
547*2d543d20SAndroid Build Coastguard Worker
validate_simpletype(uint32_t value,const policydb_t * p,const validate_t flavors[SYM_NUM])548*2d543d20SAndroid Build Coastguard Worker static int validate_simpletype(uint32_t value, const policydb_t *p, const validate_t flavors[SYM_NUM])
549*2d543d20SAndroid Build Coastguard Worker {
550*2d543d20SAndroid Build Coastguard Worker const type_datum_t *type;
551*2d543d20SAndroid Build Coastguard Worker
552*2d543d20SAndroid Build Coastguard Worker if (validate_value(value, &flavors[SYM_TYPES]))
553*2d543d20SAndroid Build Coastguard Worker goto bad;
554*2d543d20SAndroid Build Coastguard Worker
555*2d543d20SAndroid Build Coastguard Worker type = p->type_val_to_struct[value - 1];
556*2d543d20SAndroid Build Coastguard Worker if (!type)
557*2d543d20SAndroid Build Coastguard Worker goto bad;
558*2d543d20SAndroid Build Coastguard Worker
559*2d543d20SAndroid Build Coastguard Worker if (type->flavor == TYPE_ATTRIB)
560*2d543d20SAndroid Build Coastguard Worker goto bad;
561*2d543d20SAndroid Build Coastguard Worker
562*2d543d20SAndroid Build Coastguard Worker return 0;
563*2d543d20SAndroid Build Coastguard Worker
564*2d543d20SAndroid Build Coastguard Worker bad:
565*2d543d20SAndroid Build Coastguard Worker return -1;
566*2d543d20SAndroid Build Coastguard Worker }
567*2d543d20SAndroid Build Coastguard Worker
validate_type_datum(sepol_handle_t * handle,const type_datum_t * type,const policydb_t * p,validate_t flavors[])568*2d543d20SAndroid Build Coastguard Worker static int validate_type_datum(sepol_handle_t *handle, const type_datum_t *type, const policydb_t *p, validate_t flavors[])
569*2d543d20SAndroid Build Coastguard Worker {
570*2d543d20SAndroid Build Coastguard Worker if (validate_value(type->s.value, &flavors[SYM_TYPES]))
571*2d543d20SAndroid Build Coastguard Worker goto bad;
572*2d543d20SAndroid Build Coastguard Worker if (type->primary && validate_value(type->primary, &flavors[SYM_TYPES]))
573*2d543d20SAndroid Build Coastguard Worker goto bad;
574*2d543d20SAndroid Build Coastguard Worker
575*2d543d20SAndroid Build Coastguard Worker switch (type->flavor) {
576*2d543d20SAndroid Build Coastguard Worker case TYPE_TYPE:
577*2d543d20SAndroid Build Coastguard Worker case TYPE_ALIAS:
578*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&type->types))
579*2d543d20SAndroid Build Coastguard Worker goto bad;
580*2d543d20SAndroid Build Coastguard Worker if (type->bounds && validate_simpletype(type->bounds, p, flavors))
581*2d543d20SAndroid Build Coastguard Worker goto bad;
582*2d543d20SAndroid Build Coastguard Worker break;
583*2d543d20SAndroid Build Coastguard Worker case TYPE_ATTRIB:
584*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&type->types, &flavors[SYM_TYPES]))
585*2d543d20SAndroid Build Coastguard Worker goto bad;
586*2d543d20SAndroid Build Coastguard Worker if (type->bounds)
587*2d543d20SAndroid Build Coastguard Worker goto bad;
588*2d543d20SAndroid Build Coastguard Worker break;
589*2d543d20SAndroid Build Coastguard Worker default:
590*2d543d20SAndroid Build Coastguard Worker goto bad;
591*2d543d20SAndroid Build Coastguard Worker }
592*2d543d20SAndroid Build Coastguard Worker
593*2d543d20SAndroid Build Coastguard Worker switch (type->flags) {
594*2d543d20SAndroid Build Coastguard Worker case 0:
595*2d543d20SAndroid Build Coastguard Worker case TYPE_FLAGS_PERMISSIVE:
596*2d543d20SAndroid Build Coastguard Worker case TYPE_FLAGS_EXPAND_ATTR_TRUE:
597*2d543d20SAndroid Build Coastguard Worker case TYPE_FLAGS_EXPAND_ATTR_FALSE:
598*2d543d20SAndroid Build Coastguard Worker case TYPE_FLAGS_EXPAND_ATTR:
599*2d543d20SAndroid Build Coastguard Worker break;
600*2d543d20SAndroid Build Coastguard Worker default:
601*2d543d20SAndroid Build Coastguard Worker goto bad;
602*2d543d20SAndroid Build Coastguard Worker }
603*2d543d20SAndroid Build Coastguard Worker
604*2d543d20SAndroid Build Coastguard Worker return 0;
605*2d543d20SAndroid Build Coastguard Worker
606*2d543d20SAndroid Build Coastguard Worker bad:
607*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid type datum");
608*2d543d20SAndroid Build Coastguard Worker return -1;
609*2d543d20SAndroid Build Coastguard Worker }
610*2d543d20SAndroid Build Coastguard Worker
validate_type_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)611*2d543d20SAndroid Build Coastguard Worker static int validate_type_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
612*2d543d20SAndroid Build Coastguard Worker {
613*2d543d20SAndroid Build Coastguard Worker map_arg_t *margs = args;
614*2d543d20SAndroid Build Coastguard Worker
615*2d543d20SAndroid Build Coastguard Worker return validate_type_datum(margs->handle, d, margs->policy, margs->flavors);
616*2d543d20SAndroid Build Coastguard Worker }
617*2d543d20SAndroid Build Coastguard Worker
validate_mls_semantic_cat(const mls_semantic_cat_t * cat,const validate_t * cats)618*2d543d20SAndroid Build Coastguard Worker static int validate_mls_semantic_cat(const mls_semantic_cat_t *cat, const validate_t *cats)
619*2d543d20SAndroid Build Coastguard Worker {
620*2d543d20SAndroid Build Coastguard Worker for (; cat; cat = cat->next) {
621*2d543d20SAndroid Build Coastguard Worker if (validate_value(cat->low, cats))
622*2d543d20SAndroid Build Coastguard Worker goto bad;
623*2d543d20SAndroid Build Coastguard Worker if (validate_value(cat->high, cats))
624*2d543d20SAndroid Build Coastguard Worker goto bad;
625*2d543d20SAndroid Build Coastguard Worker if (cat->low > cat->high)
626*2d543d20SAndroid Build Coastguard Worker goto bad;
627*2d543d20SAndroid Build Coastguard Worker }
628*2d543d20SAndroid Build Coastguard Worker
629*2d543d20SAndroid Build Coastguard Worker return 0;
630*2d543d20SAndroid Build Coastguard Worker
631*2d543d20SAndroid Build Coastguard Worker bad:
632*2d543d20SAndroid Build Coastguard Worker return -1;
633*2d543d20SAndroid Build Coastguard Worker }
634*2d543d20SAndroid Build Coastguard Worker
validate_mls_semantic_level(const mls_semantic_level_t * level,const validate_t * sens,const validate_t * cats)635*2d543d20SAndroid Build Coastguard Worker static int validate_mls_semantic_level(const mls_semantic_level_t *level, const validate_t *sens, const validate_t *cats)
636*2d543d20SAndroid Build Coastguard Worker {
637*2d543d20SAndroid Build Coastguard Worker if (level->sens == 0)
638*2d543d20SAndroid Build Coastguard Worker return 0;
639*2d543d20SAndroid Build Coastguard Worker if (validate_value(level->sens, sens))
640*2d543d20SAndroid Build Coastguard Worker goto bad;
641*2d543d20SAndroid Build Coastguard Worker if (validate_mls_semantic_cat(level->cat, cats))
642*2d543d20SAndroid Build Coastguard Worker goto bad;
643*2d543d20SAndroid Build Coastguard Worker
644*2d543d20SAndroid Build Coastguard Worker return 0;
645*2d543d20SAndroid Build Coastguard Worker
646*2d543d20SAndroid Build Coastguard Worker bad:
647*2d543d20SAndroid Build Coastguard Worker return -1;
648*2d543d20SAndroid Build Coastguard Worker }
649*2d543d20SAndroid Build Coastguard Worker
validate_mls_semantic_range(const mls_semantic_range_t * range,const validate_t * sens,const validate_t * cats)650*2d543d20SAndroid Build Coastguard Worker static int validate_mls_semantic_range(const mls_semantic_range_t *range, const validate_t *sens, const validate_t *cats)
651*2d543d20SAndroid Build Coastguard Worker {
652*2d543d20SAndroid Build Coastguard Worker if (validate_mls_semantic_level(&range->level[0], sens, cats))
653*2d543d20SAndroid Build Coastguard Worker goto bad;
654*2d543d20SAndroid Build Coastguard Worker if (validate_mls_semantic_level(&range->level[1], sens, cats))
655*2d543d20SAndroid Build Coastguard Worker goto bad;
656*2d543d20SAndroid Build Coastguard Worker
657*2d543d20SAndroid Build Coastguard Worker return 0;
658*2d543d20SAndroid Build Coastguard Worker
659*2d543d20SAndroid Build Coastguard Worker bad:
660*2d543d20SAndroid Build Coastguard Worker return -1;
661*2d543d20SAndroid Build Coastguard Worker }
662*2d543d20SAndroid Build Coastguard Worker
validate_mls_level(const mls_level_t * level,const validate_t * sens,const validate_t * cats)663*2d543d20SAndroid Build Coastguard Worker static int validate_mls_level(const mls_level_t *level, const validate_t *sens, const validate_t *cats)
664*2d543d20SAndroid Build Coastguard Worker {
665*2d543d20SAndroid Build Coastguard Worker if (validate_value(level->sens, sens))
666*2d543d20SAndroid Build Coastguard Worker goto bad;
667*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&level->cat, cats))
668*2d543d20SAndroid Build Coastguard Worker goto bad;
669*2d543d20SAndroid Build Coastguard Worker
670*2d543d20SAndroid Build Coastguard Worker return 0;
671*2d543d20SAndroid Build Coastguard Worker
672*2d543d20SAndroid Build Coastguard Worker bad:
673*2d543d20SAndroid Build Coastguard Worker return -1;
674*2d543d20SAndroid Build Coastguard Worker }
675*2d543d20SAndroid Build Coastguard Worker
validate_level_datum(sepol_handle_t * handle,const level_datum_t * level,validate_t flavors[],const policydb_t * p)676*2d543d20SAndroid Build Coastguard Worker static int validate_level_datum(sepol_handle_t *handle, const level_datum_t *level, validate_t flavors[], const policydb_t *p)
677*2d543d20SAndroid Build Coastguard Worker {
678*2d543d20SAndroid Build Coastguard Worker if (level->notdefined != 0)
679*2d543d20SAndroid Build Coastguard Worker goto bad;
680*2d543d20SAndroid Build Coastguard Worker
681*2d543d20SAndroid Build Coastguard Worker if (validate_mls_level(level->level, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
682*2d543d20SAndroid Build Coastguard Worker goto bad;
683*2d543d20SAndroid Build Coastguard Worker
684*2d543d20SAndroid Build Coastguard Worker if (level->isalias) {
685*2d543d20SAndroid Build Coastguard Worker const mls_level_t *l1 = level->level;
686*2d543d20SAndroid Build Coastguard Worker const mls_level_t *l2;
687*2d543d20SAndroid Build Coastguard Worker const level_datum_t *actual = (level_datum_t *) hashtab_search(p->p_levels.table, p->p_sens_val_to_name[l1->sens - 1]);
688*2d543d20SAndroid Build Coastguard Worker if (!actual)
689*2d543d20SAndroid Build Coastguard Worker goto bad;
690*2d543d20SAndroid Build Coastguard Worker l2 = actual->level;
691*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_cmp(&l1->cat, &l2->cat))
692*2d543d20SAndroid Build Coastguard Worker goto bad;
693*2d543d20SAndroid Build Coastguard Worker }
694*2d543d20SAndroid Build Coastguard Worker
695*2d543d20SAndroid Build Coastguard Worker return 0;
696*2d543d20SAndroid Build Coastguard Worker
697*2d543d20SAndroid Build Coastguard Worker bad:
698*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid level datum");
699*2d543d20SAndroid Build Coastguard Worker return -1;
700*2d543d20SAndroid Build Coastguard Worker }
701*2d543d20SAndroid Build Coastguard Worker
validate_level_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)702*2d543d20SAndroid Build Coastguard Worker static int validate_level_datum_wrapper(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
703*2d543d20SAndroid Build Coastguard Worker {
704*2d543d20SAndroid Build Coastguard Worker map_arg_t *margs = args;
705*2d543d20SAndroid Build Coastguard Worker
706*2d543d20SAndroid Build Coastguard Worker return validate_level_datum(margs->handle, d, margs->flavors, margs->policy);
707*2d543d20SAndroid Build Coastguard Worker }
708*2d543d20SAndroid Build Coastguard Worker
validate_mls_range(const mls_range_t * range,const validate_t * sens,const validate_t * cats)709*2d543d20SAndroid Build Coastguard Worker static int validate_mls_range(const mls_range_t *range, const validate_t *sens, const validate_t *cats)
710*2d543d20SAndroid Build Coastguard Worker {
711*2d543d20SAndroid Build Coastguard Worker if (validate_mls_level(&range->level[0], sens, cats))
712*2d543d20SAndroid Build Coastguard Worker goto bad;
713*2d543d20SAndroid Build Coastguard Worker if (validate_mls_level(&range->level[1], sens, cats))
714*2d543d20SAndroid Build Coastguard Worker goto bad;
715*2d543d20SAndroid Build Coastguard Worker
716*2d543d20SAndroid Build Coastguard Worker return 0;
717*2d543d20SAndroid Build Coastguard Worker
718*2d543d20SAndroid Build Coastguard Worker bad:
719*2d543d20SAndroid Build Coastguard Worker return -1;
720*2d543d20SAndroid Build Coastguard Worker }
721*2d543d20SAndroid Build Coastguard Worker
validate_user_datum(sepol_handle_t * handle,const user_datum_t * user,validate_t flavors[],const policydb_t * p)722*2d543d20SAndroid Build Coastguard Worker static int validate_user_datum(sepol_handle_t *handle, const user_datum_t *user, validate_t flavors[], const policydb_t *p)
723*2d543d20SAndroid Build Coastguard Worker {
724*2d543d20SAndroid Build Coastguard Worker if (validate_value(user->s.value, &flavors[SYM_USERS]))
725*2d543d20SAndroid Build Coastguard Worker goto bad;
726*2d543d20SAndroid Build Coastguard Worker if (validate_role_set(&user->roles, &flavors[SYM_ROLES]))
727*2d543d20SAndroid Build Coastguard Worker goto bad;
728*2d543d20SAndroid Build Coastguard Worker if (validate_mls_semantic_range(&user->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
729*2d543d20SAndroid Build Coastguard Worker goto bad;
730*2d543d20SAndroid Build Coastguard Worker if (validate_mls_semantic_level(&user->dfltlevel, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
731*2d543d20SAndroid Build Coastguard Worker goto bad;
732*2d543d20SAndroid Build Coastguard Worker if (p->mls && p->policy_type != POLICY_MOD && validate_mls_range(&user->exp_range, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
733*2d543d20SAndroid Build Coastguard Worker goto bad;
734*2d543d20SAndroid Build Coastguard Worker if (p->mls && p->policy_type != POLICY_MOD && validate_mls_level(&user->exp_dfltlevel, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
735*2d543d20SAndroid Build Coastguard Worker goto bad;
736*2d543d20SAndroid Build Coastguard Worker if (user->bounds && validate_value(user->bounds, &flavors[SYM_USERS]))
737*2d543d20SAndroid Build Coastguard Worker goto bad;
738*2d543d20SAndroid Build Coastguard Worker
739*2d543d20SAndroid Build Coastguard Worker return 0;
740*2d543d20SAndroid Build Coastguard Worker
741*2d543d20SAndroid Build Coastguard Worker bad:
742*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid user datum");
743*2d543d20SAndroid Build Coastguard Worker return -1;
744*2d543d20SAndroid Build Coastguard Worker }
745*2d543d20SAndroid Build Coastguard Worker
validate_user_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)746*2d543d20SAndroid Build Coastguard Worker static int validate_user_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
747*2d543d20SAndroid Build Coastguard Worker {
748*2d543d20SAndroid Build Coastguard Worker map_arg_t *margs = args;
749*2d543d20SAndroid Build Coastguard Worker
750*2d543d20SAndroid Build Coastguard Worker return validate_user_datum(margs->handle, d, margs->flavors, margs->policy);
751*2d543d20SAndroid Build Coastguard Worker }
752*2d543d20SAndroid Build Coastguard Worker
validate_bool_datum(sepol_handle_t * handle,const cond_bool_datum_t * boolean,validate_t flavors[])753*2d543d20SAndroid Build Coastguard Worker static int validate_bool_datum(sepol_handle_t *handle, const cond_bool_datum_t *boolean, validate_t flavors[])
754*2d543d20SAndroid Build Coastguard Worker {
755*2d543d20SAndroid Build Coastguard Worker if (validate_value(boolean->s.value, &flavors[SYM_BOOLS]))
756*2d543d20SAndroid Build Coastguard Worker goto bad;
757*2d543d20SAndroid Build Coastguard Worker
758*2d543d20SAndroid Build Coastguard Worker switch (boolean->state) {
759*2d543d20SAndroid Build Coastguard Worker case 0:
760*2d543d20SAndroid Build Coastguard Worker case 1:
761*2d543d20SAndroid Build Coastguard Worker break;
762*2d543d20SAndroid Build Coastguard Worker default:
763*2d543d20SAndroid Build Coastguard Worker goto bad;
764*2d543d20SAndroid Build Coastguard Worker }
765*2d543d20SAndroid Build Coastguard Worker
766*2d543d20SAndroid Build Coastguard Worker switch (boolean->flags) {
767*2d543d20SAndroid Build Coastguard Worker case 0:
768*2d543d20SAndroid Build Coastguard Worker case COND_BOOL_FLAGS_TUNABLE:
769*2d543d20SAndroid Build Coastguard Worker break;
770*2d543d20SAndroid Build Coastguard Worker default:
771*2d543d20SAndroid Build Coastguard Worker goto bad;
772*2d543d20SAndroid Build Coastguard Worker }
773*2d543d20SAndroid Build Coastguard Worker
774*2d543d20SAndroid Build Coastguard Worker return 0;
775*2d543d20SAndroid Build Coastguard Worker
776*2d543d20SAndroid Build Coastguard Worker bad:
777*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid bool datum");
778*2d543d20SAndroid Build Coastguard Worker return -1;
779*2d543d20SAndroid Build Coastguard Worker }
780*2d543d20SAndroid Build Coastguard Worker
validate_bool_datum_wrapper(hashtab_key_t k,hashtab_datum_t d,void * args)781*2d543d20SAndroid Build Coastguard Worker static int validate_bool_datum_wrapper(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
782*2d543d20SAndroid Build Coastguard Worker {
783*2d543d20SAndroid Build Coastguard Worker map_arg_t *margs = args;
784*2d543d20SAndroid Build Coastguard Worker
785*2d543d20SAndroid Build Coastguard Worker return validate_bool_datum(margs->handle, d, margs->flavors);
786*2d543d20SAndroid Build Coastguard Worker }
787*2d543d20SAndroid Build Coastguard Worker
validate_datum_array_gaps(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])788*2d543d20SAndroid Build Coastguard Worker static int validate_datum_array_gaps(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
789*2d543d20SAndroid Build Coastguard Worker {
790*2d543d20SAndroid Build Coastguard Worker uint32_t i;
791*2d543d20SAndroid Build Coastguard Worker
792*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < p->p_classes.nprim; i++) {
793*2d543d20SAndroid Build Coastguard Worker if (bool_xnor(p->class_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_CLASSES].gaps, i)))
794*2d543d20SAndroid Build Coastguard Worker goto bad;
795*2d543d20SAndroid Build Coastguard Worker }
796*2d543d20SAndroid Build Coastguard Worker
797*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < p->p_roles.nprim; i++) {
798*2d543d20SAndroid Build Coastguard Worker if (bool_xnor(p->role_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_ROLES].gaps, i)))
799*2d543d20SAndroid Build Coastguard Worker goto bad;
800*2d543d20SAndroid Build Coastguard Worker }
801*2d543d20SAndroid Build Coastguard Worker
802*2d543d20SAndroid Build Coastguard Worker /*
803*2d543d20SAndroid Build Coastguard Worker * For policy versions between 20 and 23, attributes exist in the policy,
804*2d543d20SAndroid Build Coastguard Worker * but only in the type_attr_map, so all gaps must be assumed to be valid.
805*2d543d20SAndroid Build Coastguard Worker */
806*2d543d20SAndroid Build Coastguard Worker if (p->policy_type != POLICY_KERN || p->policyvers < POLICYDB_VERSION_AVTAB || p->policyvers > POLICYDB_VERSION_PERMISSIVE) {
807*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < p->p_types.nprim; i++) {
808*2d543d20SAndroid Build Coastguard Worker if (bool_xnor(p->type_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_TYPES].gaps, i)))
809*2d543d20SAndroid Build Coastguard Worker goto bad;
810*2d543d20SAndroid Build Coastguard Worker }
811*2d543d20SAndroid Build Coastguard Worker }
812*2d543d20SAndroid Build Coastguard Worker
813*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < p->p_users.nprim; i++) {
814*2d543d20SAndroid Build Coastguard Worker if (bool_xnor(p->user_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_USERS].gaps, i)))
815*2d543d20SAndroid Build Coastguard Worker goto bad;
816*2d543d20SAndroid Build Coastguard Worker }
817*2d543d20SAndroid Build Coastguard Worker
818*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < p->p_bools.nprim; i++) {
819*2d543d20SAndroid Build Coastguard Worker if (bool_xnor(p->bool_val_to_struct[i], ebitmap_get_bit(&flavors[SYM_BOOLS].gaps, i)))
820*2d543d20SAndroid Build Coastguard Worker goto bad;
821*2d543d20SAndroid Build Coastguard Worker }
822*2d543d20SAndroid Build Coastguard Worker
823*2d543d20SAndroid Build Coastguard Worker return 0;
824*2d543d20SAndroid Build Coastguard Worker
825*2d543d20SAndroid Build Coastguard Worker bad:
826*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid datum array gaps");
827*2d543d20SAndroid Build Coastguard Worker return -1;
828*2d543d20SAndroid Build Coastguard Worker }
829*2d543d20SAndroid Build Coastguard Worker
validate_datum(hashtab_key_t k,hashtab_datum_t d,void * args)830*2d543d20SAndroid Build Coastguard Worker static int validate_datum(__attribute__ ((unused))hashtab_key_t k, hashtab_datum_t d, void *args)
831*2d543d20SAndroid Build Coastguard Worker {
832*2d543d20SAndroid Build Coastguard Worker symtab_datum_t *s = d;
833*2d543d20SAndroid Build Coastguard Worker uint32_t *nprim = (uint32_t *)args;
834*2d543d20SAndroid Build Coastguard Worker
835*2d543d20SAndroid Build Coastguard Worker return !value_isvalid(s->value, *nprim);
836*2d543d20SAndroid Build Coastguard Worker }
837*2d543d20SAndroid Build Coastguard Worker
validate_datum_array_entries(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])838*2d543d20SAndroid Build Coastguard Worker static int validate_datum_array_entries(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
839*2d543d20SAndroid Build Coastguard Worker {
840*2d543d20SAndroid Build Coastguard Worker map_arg_t margs = { flavors, handle, p };
841*2d543d20SAndroid Build Coastguard Worker
842*2d543d20SAndroid Build Coastguard Worker if (hashtab_map(p->p_commons.table, validate_common_datum_wrapper, &margs))
843*2d543d20SAndroid Build Coastguard Worker goto bad;
844*2d543d20SAndroid Build Coastguard Worker
845*2d543d20SAndroid Build Coastguard Worker if (hashtab_map(p->p_classes.table, validate_class_datum_wrapper, &margs))
846*2d543d20SAndroid Build Coastguard Worker goto bad;
847*2d543d20SAndroid Build Coastguard Worker
848*2d543d20SAndroid Build Coastguard Worker if (hashtab_map(p->p_roles.table, validate_role_datum_wrapper, &margs))
849*2d543d20SAndroid Build Coastguard Worker goto bad;
850*2d543d20SAndroid Build Coastguard Worker
851*2d543d20SAndroid Build Coastguard Worker if (hashtab_map(p->p_types.table, validate_type_datum_wrapper, &margs))
852*2d543d20SAndroid Build Coastguard Worker goto bad;
853*2d543d20SAndroid Build Coastguard Worker
854*2d543d20SAndroid Build Coastguard Worker if (hashtab_map(p->p_users.table, validate_user_datum_wrapper, &margs))
855*2d543d20SAndroid Build Coastguard Worker goto bad;
856*2d543d20SAndroid Build Coastguard Worker
857*2d543d20SAndroid Build Coastguard Worker if (p->mls && hashtab_map(p->p_levels.table, validate_level_datum_wrapper, &margs))
858*2d543d20SAndroid Build Coastguard Worker goto bad;
859*2d543d20SAndroid Build Coastguard Worker
860*2d543d20SAndroid Build Coastguard Worker if (hashtab_map(p->p_cats.table, validate_datum, &flavors[SYM_CATS]))
861*2d543d20SAndroid Build Coastguard Worker goto bad;
862*2d543d20SAndroid Build Coastguard Worker
863*2d543d20SAndroid Build Coastguard Worker if (hashtab_map(p->p_bools.table, validate_bool_datum_wrapper, &margs))
864*2d543d20SAndroid Build Coastguard Worker goto bad;
865*2d543d20SAndroid Build Coastguard Worker
866*2d543d20SAndroid Build Coastguard Worker return 0;
867*2d543d20SAndroid Build Coastguard Worker
868*2d543d20SAndroid Build Coastguard Worker bad:
869*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid datum array entries");
870*2d543d20SAndroid Build Coastguard Worker return -1;
871*2d543d20SAndroid Build Coastguard Worker }
872*2d543d20SAndroid Build Coastguard Worker
873*2d543d20SAndroid Build Coastguard Worker /*
874*2d543d20SAndroid Build Coastguard Worker * Functions to validate a kernel policydb
875*2d543d20SAndroid Build Coastguard Worker */
876*2d543d20SAndroid Build Coastguard Worker
validate_avtab_key(const avtab_key_t * key,int conditional,const policydb_t * p,validate_t flavors[])877*2d543d20SAndroid Build Coastguard Worker static int validate_avtab_key(const avtab_key_t *key, int conditional, const policydb_t *p, validate_t flavors[])
878*2d543d20SAndroid Build Coastguard Worker {
879*2d543d20SAndroid Build Coastguard Worker if (p->policy_type == POLICY_KERN && key->specified & AVTAB_TYPE) {
880*2d543d20SAndroid Build Coastguard Worker if (validate_simpletype(key->source_type, p, flavors))
881*2d543d20SAndroid Build Coastguard Worker goto bad;
882*2d543d20SAndroid Build Coastguard Worker if (validate_simpletype(key->target_type, p, flavors))
883*2d543d20SAndroid Build Coastguard Worker goto bad;
884*2d543d20SAndroid Build Coastguard Worker } else {
885*2d543d20SAndroid Build Coastguard Worker if (validate_value(key->source_type, &flavors[SYM_TYPES]))
886*2d543d20SAndroid Build Coastguard Worker goto bad;
887*2d543d20SAndroid Build Coastguard Worker if (validate_value(key->target_type, &flavors[SYM_TYPES]))
888*2d543d20SAndroid Build Coastguard Worker goto bad;
889*2d543d20SAndroid Build Coastguard Worker }
890*2d543d20SAndroid Build Coastguard Worker
891*2d543d20SAndroid Build Coastguard Worker if (validate_value(key->target_class, &flavors[SYM_CLASSES]))
892*2d543d20SAndroid Build Coastguard Worker goto bad;
893*2d543d20SAndroid Build Coastguard Worker switch (0xFFF & key->specified) {
894*2d543d20SAndroid Build Coastguard Worker case AVTAB_ALLOWED:
895*2d543d20SAndroid Build Coastguard Worker case AVTAB_AUDITALLOW:
896*2d543d20SAndroid Build Coastguard Worker case AVTAB_AUDITDENY:
897*2d543d20SAndroid Build Coastguard Worker case AVTAB_TRANSITION:
898*2d543d20SAndroid Build Coastguard Worker case AVTAB_MEMBER:
899*2d543d20SAndroid Build Coastguard Worker case AVTAB_CHANGE:
900*2d543d20SAndroid Build Coastguard Worker break;
901*2d543d20SAndroid Build Coastguard Worker case AVTAB_XPERMS_ALLOWED:
902*2d543d20SAndroid Build Coastguard Worker case AVTAB_XPERMS_AUDITALLOW:
903*2d543d20SAndroid Build Coastguard Worker case AVTAB_XPERMS_DONTAUDIT:
904*2d543d20SAndroid Build Coastguard Worker if (p->target_platform != SEPOL_TARGET_SELINUX)
905*2d543d20SAndroid Build Coastguard Worker goto bad;
906*2d543d20SAndroid Build Coastguard Worker if (conditional)
907*2d543d20SAndroid Build Coastguard Worker goto bad;
908*2d543d20SAndroid Build Coastguard Worker break;
909*2d543d20SAndroid Build Coastguard Worker default:
910*2d543d20SAndroid Build Coastguard Worker goto bad;
911*2d543d20SAndroid Build Coastguard Worker }
912*2d543d20SAndroid Build Coastguard Worker
913*2d543d20SAndroid Build Coastguard Worker return 0;
914*2d543d20SAndroid Build Coastguard Worker
915*2d543d20SAndroid Build Coastguard Worker bad:
916*2d543d20SAndroid Build Coastguard Worker return -1;
917*2d543d20SAndroid Build Coastguard Worker }
918*2d543d20SAndroid Build Coastguard Worker
validate_xperms(const avtab_extended_perms_t * xperms)919*2d543d20SAndroid Build Coastguard Worker static int validate_xperms(const avtab_extended_perms_t *xperms)
920*2d543d20SAndroid Build Coastguard Worker {
921*2d543d20SAndroid Build Coastguard Worker switch (xperms->specified) {
922*2d543d20SAndroid Build Coastguard Worker case AVTAB_XPERMS_IOCTLDRIVER:
923*2d543d20SAndroid Build Coastguard Worker case AVTAB_XPERMS_IOCTLFUNCTION:
924*2d543d20SAndroid Build Coastguard Worker case AVTAB_XPERMS_NLMSG:
925*2d543d20SAndroid Build Coastguard Worker break;
926*2d543d20SAndroid Build Coastguard Worker default:
927*2d543d20SAndroid Build Coastguard Worker goto bad;
928*2d543d20SAndroid Build Coastguard Worker }
929*2d543d20SAndroid Build Coastguard Worker
930*2d543d20SAndroid Build Coastguard Worker return 0;
931*2d543d20SAndroid Build Coastguard Worker
932*2d543d20SAndroid Build Coastguard Worker bad:
933*2d543d20SAndroid Build Coastguard Worker return -1;
934*2d543d20SAndroid Build Coastguard Worker }
935*2d543d20SAndroid Build Coastguard Worker
validate_access_vector(sepol_handle_t * handle,const policydb_t * p,sepol_security_class_t tclass,sepol_access_vector_t av)936*2d543d20SAndroid Build Coastguard Worker static int validate_access_vector(sepol_handle_t *handle, const policydb_t *p, sepol_security_class_t tclass,
937*2d543d20SAndroid Build Coastguard Worker sepol_access_vector_t av)
938*2d543d20SAndroid Build Coastguard Worker {
939*2d543d20SAndroid Build Coastguard Worker const class_datum_t *cladatum = p->class_val_to_struct[tclass - 1];
940*2d543d20SAndroid Build Coastguard Worker
941*2d543d20SAndroid Build Coastguard Worker /*
942*2d543d20SAndroid Build Coastguard Worker * Check that at least one permission bit is valid.
943*2d543d20SAndroid Build Coastguard Worker * Older compilers might set invalid bits for the wildcard permission.
944*2d543d20SAndroid Build Coastguard Worker */
945*2d543d20SAndroid Build Coastguard Worker if (!(av & PERMISSION_MASK(cladatum->permissions.nprim)))
946*2d543d20SAndroid Build Coastguard Worker goto bad;
947*2d543d20SAndroid Build Coastguard Worker
948*2d543d20SAndroid Build Coastguard Worker return 0;
949*2d543d20SAndroid Build Coastguard Worker
950*2d543d20SAndroid Build Coastguard Worker bad:
951*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid access vector");
952*2d543d20SAndroid Build Coastguard Worker return -1;
953*2d543d20SAndroid Build Coastguard Worker }
954*2d543d20SAndroid Build Coastguard Worker
validate_avtab_key_and_datum(avtab_key_t * k,avtab_datum_t * d,void * args)955*2d543d20SAndroid Build Coastguard Worker static int validate_avtab_key_and_datum(avtab_key_t *k, avtab_datum_t *d, void *args)
956*2d543d20SAndroid Build Coastguard Worker {
957*2d543d20SAndroid Build Coastguard Worker map_arg_t *margs = args;
958*2d543d20SAndroid Build Coastguard Worker
959*2d543d20SAndroid Build Coastguard Worker if (validate_avtab_key(k, 0, margs->policy, margs->flavors))
960*2d543d20SAndroid Build Coastguard Worker return -1;
961*2d543d20SAndroid Build Coastguard Worker
962*2d543d20SAndroid Build Coastguard Worker if (k->specified & AVTAB_AV) {
963*2d543d20SAndroid Build Coastguard Worker uint32_t data = d->data;
964*2d543d20SAndroid Build Coastguard Worker
965*2d543d20SAndroid Build Coastguard Worker if ((0xFFF & k->specified) == AVTAB_AUDITDENY)
966*2d543d20SAndroid Build Coastguard Worker data = ~data;
967*2d543d20SAndroid Build Coastguard Worker
968*2d543d20SAndroid Build Coastguard Worker if (validate_access_vector(margs->handle, margs->policy, k->target_class, data))
969*2d543d20SAndroid Build Coastguard Worker return -1;
970*2d543d20SAndroid Build Coastguard Worker }
971*2d543d20SAndroid Build Coastguard Worker
972*2d543d20SAndroid Build Coastguard Worker if ((k->specified & AVTAB_TYPE) && validate_simpletype(d->data, margs->policy, margs->flavors))
973*2d543d20SAndroid Build Coastguard Worker return -1;
974*2d543d20SAndroid Build Coastguard Worker
975*2d543d20SAndroid Build Coastguard Worker if ((k->specified & AVTAB_XPERMS) && validate_xperms(d->xperms))
976*2d543d20SAndroid Build Coastguard Worker return -1;
977*2d543d20SAndroid Build Coastguard Worker
978*2d543d20SAndroid Build Coastguard Worker return 0;
979*2d543d20SAndroid Build Coastguard Worker }
980*2d543d20SAndroid Build Coastguard Worker
validate_avtab(sepol_handle_t * handle,const avtab_t * avtab,const policydb_t * p,validate_t flavors[])981*2d543d20SAndroid Build Coastguard Worker static int validate_avtab(sepol_handle_t *handle, const avtab_t *avtab, const policydb_t *p, validate_t flavors[])
982*2d543d20SAndroid Build Coastguard Worker {
983*2d543d20SAndroid Build Coastguard Worker map_arg_t margs = { flavors, handle, p };
984*2d543d20SAndroid Build Coastguard Worker
985*2d543d20SAndroid Build Coastguard Worker if (avtab_map(avtab, validate_avtab_key_and_datum, &margs)) {
986*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid avtab");
987*2d543d20SAndroid Build Coastguard Worker return -1;
988*2d543d20SAndroid Build Coastguard Worker }
989*2d543d20SAndroid Build Coastguard Worker
990*2d543d20SAndroid Build Coastguard Worker return 0;
991*2d543d20SAndroid Build Coastguard Worker }
992*2d543d20SAndroid Build Coastguard Worker
validate_cond_av_list(sepol_handle_t * handle,const cond_av_list_t * cond_av,const policydb_t * p,validate_t flavors[])993*2d543d20SAndroid Build Coastguard Worker static int validate_cond_av_list(sepol_handle_t *handle, const cond_av_list_t *cond_av, const policydb_t *p, validate_t flavors[])
994*2d543d20SAndroid Build Coastguard Worker {
995*2d543d20SAndroid Build Coastguard Worker const struct avtab_node *avtab_ptr;
996*2d543d20SAndroid Build Coastguard Worker
997*2d543d20SAndroid Build Coastguard Worker for (; cond_av; cond_av = cond_av->next) {
998*2d543d20SAndroid Build Coastguard Worker for (avtab_ptr = cond_av->node; avtab_ptr; avtab_ptr = avtab_ptr->next) {
999*2d543d20SAndroid Build Coastguard Worker const avtab_key_t *key = &avtab_ptr->key;
1000*2d543d20SAndroid Build Coastguard Worker const avtab_datum_t *datum = &avtab_ptr->datum;
1001*2d543d20SAndroid Build Coastguard Worker
1002*2d543d20SAndroid Build Coastguard Worker if (validate_avtab_key(key, 1, p, flavors))
1003*2d543d20SAndroid Build Coastguard Worker goto bad;
1004*2d543d20SAndroid Build Coastguard Worker if (key->specified & AVTAB_AV) {
1005*2d543d20SAndroid Build Coastguard Worker uint32_t data = datum->data;
1006*2d543d20SAndroid Build Coastguard Worker
1007*2d543d20SAndroid Build Coastguard Worker if ((0xFFF & key->specified) == AVTAB_AUDITDENY)
1008*2d543d20SAndroid Build Coastguard Worker data = ~data;
1009*2d543d20SAndroid Build Coastguard Worker
1010*2d543d20SAndroid Build Coastguard Worker if (validate_access_vector(handle, p, key->target_class, data))
1011*2d543d20SAndroid Build Coastguard Worker goto bad;
1012*2d543d20SAndroid Build Coastguard Worker }
1013*2d543d20SAndroid Build Coastguard Worker if ((key->specified & AVTAB_TYPE) && validate_simpletype(datum->data, p, flavors))
1014*2d543d20SAndroid Build Coastguard Worker goto bad;
1015*2d543d20SAndroid Build Coastguard Worker }
1016*2d543d20SAndroid Build Coastguard Worker }
1017*2d543d20SAndroid Build Coastguard Worker
1018*2d543d20SAndroid Build Coastguard Worker return 0;
1019*2d543d20SAndroid Build Coastguard Worker
1020*2d543d20SAndroid Build Coastguard Worker bad:
1021*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid cond av list");
1022*2d543d20SAndroid Build Coastguard Worker return -1;
1023*2d543d20SAndroid Build Coastguard Worker }
1024*2d543d20SAndroid Build Coastguard Worker
validate_avrules(sepol_handle_t * handle,const avrule_t * avrule,int conditional,const policydb_t * p,validate_t flavors[])1025*2d543d20SAndroid Build Coastguard Worker static int validate_avrules(sepol_handle_t *handle, const avrule_t *avrule, int conditional, const policydb_t *p, validate_t flavors[])
1026*2d543d20SAndroid Build Coastguard Worker {
1027*2d543d20SAndroid Build Coastguard Worker const class_perm_node_t *classperm;
1028*2d543d20SAndroid Build Coastguard Worker
1029*2d543d20SAndroid Build Coastguard Worker for (; avrule; avrule = avrule->next) {
1030*2d543d20SAndroid Build Coastguard Worker if (validate_type_set(&avrule->stypes, &flavors[SYM_TYPES]))
1031*2d543d20SAndroid Build Coastguard Worker goto bad;
1032*2d543d20SAndroid Build Coastguard Worker if (validate_type_set(&avrule->ttypes, &flavors[SYM_TYPES]))
1033*2d543d20SAndroid Build Coastguard Worker goto bad;
1034*2d543d20SAndroid Build Coastguard Worker
1035*2d543d20SAndroid Build Coastguard Worker switch(avrule->specified) {
1036*2d543d20SAndroid Build Coastguard Worker case AVRULE_ALLOWED:
1037*2d543d20SAndroid Build Coastguard Worker case AVRULE_AUDITALLOW:
1038*2d543d20SAndroid Build Coastguard Worker case AVRULE_AUDITDENY:
1039*2d543d20SAndroid Build Coastguard Worker case AVRULE_DONTAUDIT:
1040*2d543d20SAndroid Build Coastguard Worker case AVRULE_TRANSITION:
1041*2d543d20SAndroid Build Coastguard Worker case AVRULE_MEMBER:
1042*2d543d20SAndroid Build Coastguard Worker case AVRULE_CHANGE:
1043*2d543d20SAndroid Build Coastguard Worker break;
1044*2d543d20SAndroid Build Coastguard Worker case AVRULE_NEVERALLOW:
1045*2d543d20SAndroid Build Coastguard Worker case AVRULE_XPERMS_ALLOWED:
1046*2d543d20SAndroid Build Coastguard Worker case AVRULE_XPERMS_AUDITALLOW:
1047*2d543d20SAndroid Build Coastguard Worker case AVRULE_XPERMS_DONTAUDIT:
1048*2d543d20SAndroid Build Coastguard Worker case AVRULE_XPERMS_NEVERALLOW:
1049*2d543d20SAndroid Build Coastguard Worker if (conditional)
1050*2d543d20SAndroid Build Coastguard Worker goto bad;
1051*2d543d20SAndroid Build Coastguard Worker break;
1052*2d543d20SAndroid Build Coastguard Worker default:
1053*2d543d20SAndroid Build Coastguard Worker goto bad;
1054*2d543d20SAndroid Build Coastguard Worker }
1055*2d543d20SAndroid Build Coastguard Worker
1056*2d543d20SAndroid Build Coastguard Worker for (classperm = avrule->perms; classperm; classperm = classperm->next) {
1057*2d543d20SAndroid Build Coastguard Worker if (validate_value(classperm->tclass, &flavors[SYM_CLASSES]))
1058*2d543d20SAndroid Build Coastguard Worker goto bad;
1059*2d543d20SAndroid Build Coastguard Worker if ((avrule->specified & AVRULE_TYPE) && validate_simpletype(classperm->data, p, flavors))
1060*2d543d20SAndroid Build Coastguard Worker goto bad;
1061*2d543d20SAndroid Build Coastguard Worker }
1062*2d543d20SAndroid Build Coastguard Worker
1063*2d543d20SAndroid Build Coastguard Worker if (avrule->specified & AVRULE_XPERMS) {
1064*2d543d20SAndroid Build Coastguard Worker if (p->target_platform != SEPOL_TARGET_SELINUX)
1065*2d543d20SAndroid Build Coastguard Worker goto bad;
1066*2d543d20SAndroid Build Coastguard Worker if (!avrule->xperms)
1067*2d543d20SAndroid Build Coastguard Worker goto bad;
1068*2d543d20SAndroid Build Coastguard Worker switch (avrule->xperms->specified) {
1069*2d543d20SAndroid Build Coastguard Worker case AVRULE_XPERMS_IOCTLFUNCTION:
1070*2d543d20SAndroid Build Coastguard Worker case AVRULE_XPERMS_IOCTLDRIVER:
1071*2d543d20SAndroid Build Coastguard Worker case AVRULE_XPERMS_NLMSG:
1072*2d543d20SAndroid Build Coastguard Worker break;
1073*2d543d20SAndroid Build Coastguard Worker default:
1074*2d543d20SAndroid Build Coastguard Worker goto bad;
1075*2d543d20SAndroid Build Coastguard Worker }
1076*2d543d20SAndroid Build Coastguard Worker } else if (avrule->xperms)
1077*2d543d20SAndroid Build Coastguard Worker goto bad;
1078*2d543d20SAndroid Build Coastguard Worker
1079*2d543d20SAndroid Build Coastguard Worker switch(avrule->flags) {
1080*2d543d20SAndroid Build Coastguard Worker case 0:
1081*2d543d20SAndroid Build Coastguard Worker break;
1082*2d543d20SAndroid Build Coastguard Worker case RULE_SELF:
1083*2d543d20SAndroid Build Coastguard Worker if (p->policyvers != POLICY_KERN &&
1084*2d543d20SAndroid Build Coastguard Worker p->policyvers < MOD_POLICYDB_VERSION_SELF_TYPETRANS &&
1085*2d543d20SAndroid Build Coastguard Worker (avrule->specified & AVRULE_TYPE))
1086*2d543d20SAndroid Build Coastguard Worker goto bad;
1087*2d543d20SAndroid Build Coastguard Worker break;
1088*2d543d20SAndroid Build Coastguard Worker case RULE_NOTSELF:
1089*2d543d20SAndroid Build Coastguard Worker switch(avrule->specified) {
1090*2d543d20SAndroid Build Coastguard Worker case AVRULE_NEVERALLOW:
1091*2d543d20SAndroid Build Coastguard Worker case AVRULE_XPERMS_NEVERALLOW:
1092*2d543d20SAndroid Build Coastguard Worker break;
1093*2d543d20SAndroid Build Coastguard Worker default:
1094*2d543d20SAndroid Build Coastguard Worker goto bad;
1095*2d543d20SAndroid Build Coastguard Worker }
1096*2d543d20SAndroid Build Coastguard Worker break;
1097*2d543d20SAndroid Build Coastguard Worker default:
1098*2d543d20SAndroid Build Coastguard Worker goto bad;
1099*2d543d20SAndroid Build Coastguard Worker }
1100*2d543d20SAndroid Build Coastguard Worker }
1101*2d543d20SAndroid Build Coastguard Worker
1102*2d543d20SAndroid Build Coastguard Worker return 0;
1103*2d543d20SAndroid Build Coastguard Worker
1104*2d543d20SAndroid Build Coastguard Worker bad:
1105*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid avrule");
1106*2d543d20SAndroid Build Coastguard Worker return -1;
1107*2d543d20SAndroid Build Coastguard Worker }
1108*2d543d20SAndroid Build Coastguard Worker
validate_bool_id_array(sepol_handle_t * handle,const uint32_t bool_ids[],unsigned int nbools,const validate_t * boolean)1109*2d543d20SAndroid Build Coastguard Worker static int validate_bool_id_array(sepol_handle_t *handle, const uint32_t bool_ids[], unsigned int nbools, const validate_t *boolean)
1110*2d543d20SAndroid Build Coastguard Worker {
1111*2d543d20SAndroid Build Coastguard Worker unsigned int i;
1112*2d543d20SAndroid Build Coastguard Worker
1113*2d543d20SAndroid Build Coastguard Worker if (nbools >= COND_MAX_BOOLS)
1114*2d543d20SAndroid Build Coastguard Worker goto bad;
1115*2d543d20SAndroid Build Coastguard Worker
1116*2d543d20SAndroid Build Coastguard Worker for (i=0; i < nbools; i++) {
1117*2d543d20SAndroid Build Coastguard Worker if (validate_value(bool_ids[i], boolean))
1118*2d543d20SAndroid Build Coastguard Worker goto bad;
1119*2d543d20SAndroid Build Coastguard Worker }
1120*2d543d20SAndroid Build Coastguard Worker
1121*2d543d20SAndroid Build Coastguard Worker return 0;
1122*2d543d20SAndroid Build Coastguard Worker
1123*2d543d20SAndroid Build Coastguard Worker bad:
1124*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid bool id array");
1125*2d543d20SAndroid Build Coastguard Worker return -1;
1126*2d543d20SAndroid Build Coastguard Worker }
1127*2d543d20SAndroid Build Coastguard Worker
validate_cond_expr(sepol_handle_t * handle,const struct cond_expr * expr,const validate_t * boolean)1128*2d543d20SAndroid Build Coastguard Worker static int validate_cond_expr(sepol_handle_t *handle, const struct cond_expr *expr, const validate_t *boolean)
1129*2d543d20SAndroid Build Coastguard Worker {
1130*2d543d20SAndroid Build Coastguard Worker int depth = -1;
1131*2d543d20SAndroid Build Coastguard Worker
1132*2d543d20SAndroid Build Coastguard Worker if (!expr)
1133*2d543d20SAndroid Build Coastguard Worker goto bad;
1134*2d543d20SAndroid Build Coastguard Worker
1135*2d543d20SAndroid Build Coastguard Worker for (; expr; expr = expr->next) {
1136*2d543d20SAndroid Build Coastguard Worker switch(expr->expr_type) {
1137*2d543d20SAndroid Build Coastguard Worker case COND_BOOL:
1138*2d543d20SAndroid Build Coastguard Worker if (validate_value(expr->boolean, boolean))
1139*2d543d20SAndroid Build Coastguard Worker goto bad;
1140*2d543d20SAndroid Build Coastguard Worker if (depth >= (COND_EXPR_MAXDEPTH - 1))
1141*2d543d20SAndroid Build Coastguard Worker goto bad;
1142*2d543d20SAndroid Build Coastguard Worker depth++;
1143*2d543d20SAndroid Build Coastguard Worker break;
1144*2d543d20SAndroid Build Coastguard Worker case COND_NOT:
1145*2d543d20SAndroid Build Coastguard Worker if (depth < 0)
1146*2d543d20SAndroid Build Coastguard Worker goto bad;
1147*2d543d20SAndroid Build Coastguard Worker if (expr->boolean != 0)
1148*2d543d20SAndroid Build Coastguard Worker goto bad;
1149*2d543d20SAndroid Build Coastguard Worker break;
1150*2d543d20SAndroid Build Coastguard Worker case COND_OR:
1151*2d543d20SAndroid Build Coastguard Worker case COND_AND:
1152*2d543d20SAndroid Build Coastguard Worker case COND_XOR:
1153*2d543d20SAndroid Build Coastguard Worker case COND_EQ:
1154*2d543d20SAndroid Build Coastguard Worker case COND_NEQ:
1155*2d543d20SAndroid Build Coastguard Worker if (depth < 1)
1156*2d543d20SAndroid Build Coastguard Worker goto bad;
1157*2d543d20SAndroid Build Coastguard Worker if (expr->boolean != 0)
1158*2d543d20SAndroid Build Coastguard Worker goto bad;
1159*2d543d20SAndroid Build Coastguard Worker depth--;
1160*2d543d20SAndroid Build Coastguard Worker break;
1161*2d543d20SAndroid Build Coastguard Worker default:
1162*2d543d20SAndroid Build Coastguard Worker goto bad;
1163*2d543d20SAndroid Build Coastguard Worker }
1164*2d543d20SAndroid Build Coastguard Worker }
1165*2d543d20SAndroid Build Coastguard Worker
1166*2d543d20SAndroid Build Coastguard Worker if (depth != 0)
1167*2d543d20SAndroid Build Coastguard Worker goto bad;
1168*2d543d20SAndroid Build Coastguard Worker
1169*2d543d20SAndroid Build Coastguard Worker return 0;
1170*2d543d20SAndroid Build Coastguard Worker
1171*2d543d20SAndroid Build Coastguard Worker bad:
1172*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid cond expression");
1173*2d543d20SAndroid Build Coastguard Worker return -1;
1174*2d543d20SAndroid Build Coastguard Worker }
1175*2d543d20SAndroid Build Coastguard Worker
validate_cond_list(sepol_handle_t * handle,const cond_list_t * cond,const policydb_t * p,validate_t flavors[])1176*2d543d20SAndroid Build Coastguard Worker static int validate_cond_list(sepol_handle_t *handle, const cond_list_t *cond, const policydb_t *p, validate_t flavors[])
1177*2d543d20SAndroid Build Coastguard Worker {
1178*2d543d20SAndroid Build Coastguard Worker for (; cond; cond = cond->next) {
1179*2d543d20SAndroid Build Coastguard Worker if (validate_cond_expr(handle, cond->expr, &flavors[SYM_BOOLS]))
1180*2d543d20SAndroid Build Coastguard Worker goto bad;
1181*2d543d20SAndroid Build Coastguard Worker if (validate_cond_av_list(handle, cond->true_list, p, flavors))
1182*2d543d20SAndroid Build Coastguard Worker goto bad;
1183*2d543d20SAndroid Build Coastguard Worker if (validate_cond_av_list(handle, cond->false_list, p, flavors))
1184*2d543d20SAndroid Build Coastguard Worker goto bad;
1185*2d543d20SAndroid Build Coastguard Worker if (validate_avrules(handle, cond->avtrue_list, 1, p, flavors))
1186*2d543d20SAndroid Build Coastguard Worker goto bad;
1187*2d543d20SAndroid Build Coastguard Worker if (validate_avrules(handle, cond->avfalse_list, 1, p, flavors))
1188*2d543d20SAndroid Build Coastguard Worker goto bad;
1189*2d543d20SAndroid Build Coastguard Worker if (validate_bool_id_array(handle, cond->bool_ids, cond->nbools, &flavors[SYM_BOOLS]))
1190*2d543d20SAndroid Build Coastguard Worker goto bad;
1191*2d543d20SAndroid Build Coastguard Worker
1192*2d543d20SAndroid Build Coastguard Worker switch (cond->cur_state) {
1193*2d543d20SAndroid Build Coastguard Worker case 0:
1194*2d543d20SAndroid Build Coastguard Worker case 1:
1195*2d543d20SAndroid Build Coastguard Worker break;
1196*2d543d20SAndroid Build Coastguard Worker default:
1197*2d543d20SAndroid Build Coastguard Worker goto bad;
1198*2d543d20SAndroid Build Coastguard Worker }
1199*2d543d20SAndroid Build Coastguard Worker
1200*2d543d20SAndroid Build Coastguard Worker switch (cond->flags) {
1201*2d543d20SAndroid Build Coastguard Worker case 0:
1202*2d543d20SAndroid Build Coastguard Worker case COND_NODE_FLAGS_TUNABLE:
1203*2d543d20SAndroid Build Coastguard Worker break;
1204*2d543d20SAndroid Build Coastguard Worker default:
1205*2d543d20SAndroid Build Coastguard Worker goto bad;
1206*2d543d20SAndroid Build Coastguard Worker }
1207*2d543d20SAndroid Build Coastguard Worker }
1208*2d543d20SAndroid Build Coastguard Worker
1209*2d543d20SAndroid Build Coastguard Worker return 0;
1210*2d543d20SAndroid Build Coastguard Worker
1211*2d543d20SAndroid Build Coastguard Worker bad:
1212*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid cond list");
1213*2d543d20SAndroid Build Coastguard Worker return -1;
1214*2d543d20SAndroid Build Coastguard Worker }
1215*2d543d20SAndroid Build Coastguard Worker
validate_role_transes(sepol_handle_t * handle,const role_trans_t * role_trans,validate_t flavors[])1216*2d543d20SAndroid Build Coastguard Worker static int validate_role_transes(sepol_handle_t *handle, const role_trans_t *role_trans, validate_t flavors[])
1217*2d543d20SAndroid Build Coastguard Worker {
1218*2d543d20SAndroid Build Coastguard Worker for (; role_trans; role_trans = role_trans->next) {
1219*2d543d20SAndroid Build Coastguard Worker if (validate_value(role_trans->role, &flavors[SYM_ROLES]))
1220*2d543d20SAndroid Build Coastguard Worker goto bad;
1221*2d543d20SAndroid Build Coastguard Worker if (validate_value(role_trans->type, &flavors[SYM_TYPES]))
1222*2d543d20SAndroid Build Coastguard Worker goto bad;
1223*2d543d20SAndroid Build Coastguard Worker if (validate_value(role_trans->tclass, &flavors[SYM_CLASSES]))
1224*2d543d20SAndroid Build Coastguard Worker goto bad;
1225*2d543d20SAndroid Build Coastguard Worker if (validate_value(role_trans->new_role, &flavors[SYM_ROLES]))
1226*2d543d20SAndroid Build Coastguard Worker goto bad;
1227*2d543d20SAndroid Build Coastguard Worker }
1228*2d543d20SAndroid Build Coastguard Worker
1229*2d543d20SAndroid Build Coastguard Worker return 0;
1230*2d543d20SAndroid Build Coastguard Worker
1231*2d543d20SAndroid Build Coastguard Worker bad:
1232*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid role trans");
1233*2d543d20SAndroid Build Coastguard Worker return -1;
1234*2d543d20SAndroid Build Coastguard Worker }
1235*2d543d20SAndroid Build Coastguard Worker
validate_role_allows(sepol_handle_t * handle,const role_allow_t * role_allow,validate_t flavors[])1236*2d543d20SAndroid Build Coastguard Worker static int validate_role_allows(sepol_handle_t *handle, const role_allow_t *role_allow, validate_t flavors[])
1237*2d543d20SAndroid Build Coastguard Worker {
1238*2d543d20SAndroid Build Coastguard Worker for (; role_allow; role_allow = role_allow->next) {
1239*2d543d20SAndroid Build Coastguard Worker if (validate_value(role_allow->role, &flavors[SYM_ROLES]))
1240*2d543d20SAndroid Build Coastguard Worker goto bad;
1241*2d543d20SAndroid Build Coastguard Worker if (validate_value(role_allow->new_role, &flavors[SYM_ROLES]))
1242*2d543d20SAndroid Build Coastguard Worker goto bad;
1243*2d543d20SAndroid Build Coastguard Worker }
1244*2d543d20SAndroid Build Coastguard Worker
1245*2d543d20SAndroid Build Coastguard Worker return 0;
1246*2d543d20SAndroid Build Coastguard Worker
1247*2d543d20SAndroid Build Coastguard Worker bad:
1248*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid role allow");
1249*2d543d20SAndroid Build Coastguard Worker return -1;
1250*2d543d20SAndroid Build Coastguard Worker }
1251*2d543d20SAndroid Build Coastguard Worker
validate_filename_trans(hashtab_key_t k,hashtab_datum_t d,void * args)1252*2d543d20SAndroid Build Coastguard Worker static int validate_filename_trans(hashtab_key_t k, hashtab_datum_t d, void *args)
1253*2d543d20SAndroid Build Coastguard Worker {
1254*2d543d20SAndroid Build Coastguard Worker const filename_trans_key_t *ftk = (filename_trans_key_t *)k;
1255*2d543d20SAndroid Build Coastguard Worker const filename_trans_datum_t *ftd = d;
1256*2d543d20SAndroid Build Coastguard Worker const map_arg_t *margs = args;
1257*2d543d20SAndroid Build Coastguard Worker const validate_t *flavors = margs->flavors;
1258*2d543d20SAndroid Build Coastguard Worker const policydb_t *p = margs->policy;
1259*2d543d20SAndroid Build Coastguard Worker
1260*2d543d20SAndroid Build Coastguard Worker if (validate_value(ftk->ttype, &flavors[SYM_TYPES]))
1261*2d543d20SAndroid Build Coastguard Worker goto bad;
1262*2d543d20SAndroid Build Coastguard Worker if (validate_value(ftk->tclass, &flavors[SYM_CLASSES]))
1263*2d543d20SAndroid Build Coastguard Worker goto bad;
1264*2d543d20SAndroid Build Coastguard Worker if (!ftd)
1265*2d543d20SAndroid Build Coastguard Worker goto bad;
1266*2d543d20SAndroid Build Coastguard Worker for (; ftd; ftd = ftd->next) {
1267*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&ftd->stypes, &flavors[SYM_TYPES]))
1268*2d543d20SAndroid Build Coastguard Worker goto bad;
1269*2d543d20SAndroid Build Coastguard Worker if (validate_simpletype(ftd->otype, p, flavors))
1270*2d543d20SAndroid Build Coastguard Worker goto bad;
1271*2d543d20SAndroid Build Coastguard Worker }
1272*2d543d20SAndroid Build Coastguard Worker
1273*2d543d20SAndroid Build Coastguard Worker return 0;
1274*2d543d20SAndroid Build Coastguard Worker
1275*2d543d20SAndroid Build Coastguard Worker bad:
1276*2d543d20SAndroid Build Coastguard Worker return -1;
1277*2d543d20SAndroid Build Coastguard Worker }
1278*2d543d20SAndroid Build Coastguard Worker
validate_filename_trans_hashtab(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1279*2d543d20SAndroid Build Coastguard Worker static int validate_filename_trans_hashtab(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1280*2d543d20SAndroid Build Coastguard Worker {
1281*2d543d20SAndroid Build Coastguard Worker map_arg_t margs = { flavors, handle, p };
1282*2d543d20SAndroid Build Coastguard Worker
1283*2d543d20SAndroid Build Coastguard Worker if (hashtab_map(p->filename_trans, validate_filename_trans, &margs)) {
1284*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid filename trans");
1285*2d543d20SAndroid Build Coastguard Worker return -1;
1286*2d543d20SAndroid Build Coastguard Worker }
1287*2d543d20SAndroid Build Coastguard Worker
1288*2d543d20SAndroid Build Coastguard Worker return 0;
1289*2d543d20SAndroid Build Coastguard Worker }
1290*2d543d20SAndroid Build Coastguard Worker
validate_context(const context_struct_t * con,validate_t flavors[],int mls)1291*2d543d20SAndroid Build Coastguard Worker static int validate_context(const context_struct_t *con, validate_t flavors[], int mls)
1292*2d543d20SAndroid Build Coastguard Worker {
1293*2d543d20SAndroid Build Coastguard Worker if (validate_value(con->user, &flavors[SYM_USERS]))
1294*2d543d20SAndroid Build Coastguard Worker return -1;
1295*2d543d20SAndroid Build Coastguard Worker if (validate_value(con->role, &flavors[SYM_ROLES]))
1296*2d543d20SAndroid Build Coastguard Worker return -1;
1297*2d543d20SAndroid Build Coastguard Worker if (validate_value(con->type, &flavors[SYM_TYPES]))
1298*2d543d20SAndroid Build Coastguard Worker return -1;
1299*2d543d20SAndroid Build Coastguard Worker if (mls && validate_mls_range(&con->range, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
1300*2d543d20SAndroid Build Coastguard Worker return -1;
1301*2d543d20SAndroid Build Coastguard Worker
1302*2d543d20SAndroid Build Coastguard Worker return 0;
1303*2d543d20SAndroid Build Coastguard Worker }
1304*2d543d20SAndroid Build Coastguard Worker
validate_ocontexts(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1305*2d543d20SAndroid Build Coastguard Worker static int validate_ocontexts(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1306*2d543d20SAndroid Build Coastguard Worker {
1307*2d543d20SAndroid Build Coastguard Worker const ocontext_t *octx;
1308*2d543d20SAndroid Build Coastguard Worker unsigned int i;
1309*2d543d20SAndroid Build Coastguard Worker
1310*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < OCON_NUM; i++) {
1311*2d543d20SAndroid Build Coastguard Worker for (octx = p->ocontexts[i]; octx; octx = octx->next) {
1312*2d543d20SAndroid Build Coastguard Worker if (validate_context(&octx->context[0], flavors, p->mls))
1313*2d543d20SAndroid Build Coastguard Worker goto bad;
1314*2d543d20SAndroid Build Coastguard Worker
1315*2d543d20SAndroid Build Coastguard Worker if (p->target_platform == SEPOL_TARGET_SELINUX) {
1316*2d543d20SAndroid Build Coastguard Worker switch (i) {
1317*2d543d20SAndroid Build Coastguard Worker case OCON_ISID:
1318*2d543d20SAndroid Build Coastguard Worker if (octx->sid[0] == SEPOL_SECSID_NULL || octx->sid[0] >= SELINUX_SID_SZ)
1319*2d543d20SAndroid Build Coastguard Worker goto bad;
1320*2d543d20SAndroid Build Coastguard Worker break;
1321*2d543d20SAndroid Build Coastguard Worker case OCON_FS:
1322*2d543d20SAndroid Build Coastguard Worker case OCON_NETIF:
1323*2d543d20SAndroid Build Coastguard Worker if (validate_context(&octx->context[1], flavors, p->mls))
1324*2d543d20SAndroid Build Coastguard Worker goto bad;
1325*2d543d20SAndroid Build Coastguard Worker if (!octx->u.name)
1326*2d543d20SAndroid Build Coastguard Worker goto bad;
1327*2d543d20SAndroid Build Coastguard Worker break;
1328*2d543d20SAndroid Build Coastguard Worker case OCON_PORT:
1329*2d543d20SAndroid Build Coastguard Worker if (octx->u.port.low_port > octx->u.port.high_port)
1330*2d543d20SAndroid Build Coastguard Worker goto bad;
1331*2d543d20SAndroid Build Coastguard Worker break;
1332*2d543d20SAndroid Build Coastguard Worker case OCON_FSUSE:
1333*2d543d20SAndroid Build Coastguard Worker switch (octx->v.behavior) {
1334*2d543d20SAndroid Build Coastguard Worker case SECURITY_FS_USE_XATTR:
1335*2d543d20SAndroid Build Coastguard Worker case SECURITY_FS_USE_TRANS:
1336*2d543d20SAndroid Build Coastguard Worker case SECURITY_FS_USE_TASK:
1337*2d543d20SAndroid Build Coastguard Worker break;
1338*2d543d20SAndroid Build Coastguard Worker default:
1339*2d543d20SAndroid Build Coastguard Worker goto bad;
1340*2d543d20SAndroid Build Coastguard Worker }
1341*2d543d20SAndroid Build Coastguard Worker if (!octx->u.name)
1342*2d543d20SAndroid Build Coastguard Worker goto bad;
1343*2d543d20SAndroid Build Coastguard Worker break;
1344*2d543d20SAndroid Build Coastguard Worker case OCON_IBPKEY:
1345*2d543d20SAndroid Build Coastguard Worker if (octx->u.ibpkey.low_pkey > octx->u.ibpkey.high_pkey)
1346*2d543d20SAndroid Build Coastguard Worker goto bad;
1347*2d543d20SAndroid Build Coastguard Worker break;
1348*2d543d20SAndroid Build Coastguard Worker case OCON_IBENDPORT:
1349*2d543d20SAndroid Build Coastguard Worker if (octx->u.ibendport.port == 0)
1350*2d543d20SAndroid Build Coastguard Worker goto bad;
1351*2d543d20SAndroid Build Coastguard Worker if (!octx->u.ibendport.dev_name)
1352*2d543d20SAndroid Build Coastguard Worker goto bad;
1353*2d543d20SAndroid Build Coastguard Worker break;
1354*2d543d20SAndroid Build Coastguard Worker }
1355*2d543d20SAndroid Build Coastguard Worker } else if (p->target_platform == SEPOL_TARGET_XEN) {
1356*2d543d20SAndroid Build Coastguard Worker switch(i) {
1357*2d543d20SAndroid Build Coastguard Worker case OCON_XEN_ISID:
1358*2d543d20SAndroid Build Coastguard Worker if (octx->sid[0] == SEPOL_SECSID_NULL || octx->sid[0] >= XEN_SID_SZ)
1359*2d543d20SAndroid Build Coastguard Worker goto bad;
1360*2d543d20SAndroid Build Coastguard Worker break;
1361*2d543d20SAndroid Build Coastguard Worker case OCON_XEN_IOPORT:
1362*2d543d20SAndroid Build Coastguard Worker if (octx->u.ioport.low_ioport > octx->u.ioport.high_ioport)
1363*2d543d20SAndroid Build Coastguard Worker goto bad;
1364*2d543d20SAndroid Build Coastguard Worker break;
1365*2d543d20SAndroid Build Coastguard Worker case OCON_XEN_IOMEM:
1366*2d543d20SAndroid Build Coastguard Worker if (octx->u.iomem.low_iomem > octx->u.iomem.high_iomem)
1367*2d543d20SAndroid Build Coastguard Worker goto bad;
1368*2d543d20SAndroid Build Coastguard Worker if (p->policyvers < POLICYDB_VERSION_XEN_DEVICETREE && octx->u.iomem.high_iomem > 0xFFFFFFFFULL)
1369*2d543d20SAndroid Build Coastguard Worker goto bad;
1370*2d543d20SAndroid Build Coastguard Worker break;
1371*2d543d20SAndroid Build Coastguard Worker case OCON_XEN_DEVICETREE:
1372*2d543d20SAndroid Build Coastguard Worker if (!octx->u.name)
1373*2d543d20SAndroid Build Coastguard Worker goto bad;
1374*2d543d20SAndroid Build Coastguard Worker break;
1375*2d543d20SAndroid Build Coastguard Worker }
1376*2d543d20SAndroid Build Coastguard Worker }
1377*2d543d20SAndroid Build Coastguard Worker }
1378*2d543d20SAndroid Build Coastguard Worker }
1379*2d543d20SAndroid Build Coastguard Worker
1380*2d543d20SAndroid Build Coastguard Worker return 0;
1381*2d543d20SAndroid Build Coastguard Worker
1382*2d543d20SAndroid Build Coastguard Worker bad:
1383*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid ocontext");
1384*2d543d20SAndroid Build Coastguard Worker return -1;
1385*2d543d20SAndroid Build Coastguard Worker }
1386*2d543d20SAndroid Build Coastguard Worker
validate_genfs(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1387*2d543d20SAndroid Build Coastguard Worker static int validate_genfs(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1388*2d543d20SAndroid Build Coastguard Worker {
1389*2d543d20SAndroid Build Coastguard Worker const genfs_t *genfs;
1390*2d543d20SAndroid Build Coastguard Worker const ocontext_t *octx;
1391*2d543d20SAndroid Build Coastguard Worker
1392*2d543d20SAndroid Build Coastguard Worker for (genfs = p->genfs; genfs; genfs = genfs->next) {
1393*2d543d20SAndroid Build Coastguard Worker for (octx = genfs->head; octx; octx = octx->next) {
1394*2d543d20SAndroid Build Coastguard Worker if (validate_context(&octx->context[0], flavors, p->mls))
1395*2d543d20SAndroid Build Coastguard Worker goto bad;
1396*2d543d20SAndroid Build Coastguard Worker if (octx->v.sclass && validate_value(octx->v.sclass, &flavors[SYM_CLASSES]))
1397*2d543d20SAndroid Build Coastguard Worker goto bad;
1398*2d543d20SAndroid Build Coastguard Worker }
1399*2d543d20SAndroid Build Coastguard Worker
1400*2d543d20SAndroid Build Coastguard Worker if (!genfs->fstype)
1401*2d543d20SAndroid Build Coastguard Worker goto bad;
1402*2d543d20SAndroid Build Coastguard Worker }
1403*2d543d20SAndroid Build Coastguard Worker
1404*2d543d20SAndroid Build Coastguard Worker return 0;
1405*2d543d20SAndroid Build Coastguard Worker
1406*2d543d20SAndroid Build Coastguard Worker bad:
1407*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid genfs");
1408*2d543d20SAndroid Build Coastguard Worker return -1;
1409*2d543d20SAndroid Build Coastguard Worker }
1410*2d543d20SAndroid Build Coastguard Worker
1411*2d543d20SAndroid Build Coastguard Worker /*
1412*2d543d20SAndroid Build Coastguard Worker * Functions to validate a module policydb
1413*2d543d20SAndroid Build Coastguard Worker */
1414*2d543d20SAndroid Build Coastguard Worker
validate_role_trans_rules(sepol_handle_t * handle,const role_trans_rule_t * role_trans,validate_t flavors[])1415*2d543d20SAndroid Build Coastguard Worker static int validate_role_trans_rules(sepol_handle_t *handle, const role_trans_rule_t *role_trans, validate_t flavors[])
1416*2d543d20SAndroid Build Coastguard Worker {
1417*2d543d20SAndroid Build Coastguard Worker for (; role_trans; role_trans = role_trans->next) {
1418*2d543d20SAndroid Build Coastguard Worker if (validate_role_set(&role_trans->roles, &flavors[SYM_ROLES]))
1419*2d543d20SAndroid Build Coastguard Worker goto bad;
1420*2d543d20SAndroid Build Coastguard Worker if (validate_type_set(&role_trans->types, &flavors[SYM_TYPES]))
1421*2d543d20SAndroid Build Coastguard Worker goto bad;
1422*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&role_trans->classes, &flavors[SYM_CLASSES]))
1423*2d543d20SAndroid Build Coastguard Worker goto bad;
1424*2d543d20SAndroid Build Coastguard Worker if (validate_value(role_trans->new_role, &flavors[SYM_ROLES]))
1425*2d543d20SAndroid Build Coastguard Worker goto bad;
1426*2d543d20SAndroid Build Coastguard Worker }
1427*2d543d20SAndroid Build Coastguard Worker
1428*2d543d20SAndroid Build Coastguard Worker return 0;
1429*2d543d20SAndroid Build Coastguard Worker
1430*2d543d20SAndroid Build Coastguard Worker bad:
1431*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid role trans rule");
1432*2d543d20SAndroid Build Coastguard Worker return -1;
1433*2d543d20SAndroid Build Coastguard Worker }
1434*2d543d20SAndroid Build Coastguard Worker
validate_role_allow_rules(sepol_handle_t * handle,const role_allow_rule_t * role_allow,validate_t flavors[])1435*2d543d20SAndroid Build Coastguard Worker static int validate_role_allow_rules(sepol_handle_t *handle, const role_allow_rule_t *role_allow, validate_t flavors[])
1436*2d543d20SAndroid Build Coastguard Worker {
1437*2d543d20SAndroid Build Coastguard Worker for (; role_allow; role_allow = role_allow->next) {
1438*2d543d20SAndroid Build Coastguard Worker if (validate_role_set(&role_allow->roles, &flavors[SYM_ROLES]))
1439*2d543d20SAndroid Build Coastguard Worker goto bad;
1440*2d543d20SAndroid Build Coastguard Worker if (validate_role_set(&role_allow->new_roles, &flavors[SYM_ROLES]))
1441*2d543d20SAndroid Build Coastguard Worker goto bad;
1442*2d543d20SAndroid Build Coastguard Worker }
1443*2d543d20SAndroid Build Coastguard Worker
1444*2d543d20SAndroid Build Coastguard Worker return 0;
1445*2d543d20SAndroid Build Coastguard Worker
1446*2d543d20SAndroid Build Coastguard Worker bad:
1447*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid role allow rule");
1448*2d543d20SAndroid Build Coastguard Worker return -1;
1449*2d543d20SAndroid Build Coastguard Worker }
1450*2d543d20SAndroid Build Coastguard Worker
validate_range_trans_rules(sepol_handle_t * handle,const range_trans_rule_t * range_trans,validate_t flavors[])1451*2d543d20SAndroid Build Coastguard Worker static int validate_range_trans_rules(sepol_handle_t *handle, const range_trans_rule_t *range_trans, validate_t flavors[])
1452*2d543d20SAndroid Build Coastguard Worker {
1453*2d543d20SAndroid Build Coastguard Worker for (; range_trans; range_trans = range_trans->next) {
1454*2d543d20SAndroid Build Coastguard Worker if (validate_type_set(&range_trans->stypes, &flavors[SYM_TYPES]))
1455*2d543d20SAndroid Build Coastguard Worker goto bad;
1456*2d543d20SAndroid Build Coastguard Worker if (validate_type_set(&range_trans->ttypes, &flavors[SYM_TYPES]))
1457*2d543d20SAndroid Build Coastguard Worker goto bad;
1458*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&range_trans->tclasses, &flavors[SYM_CLASSES]))
1459*2d543d20SAndroid Build Coastguard Worker goto bad;
1460*2d543d20SAndroid Build Coastguard Worker if (validate_mls_semantic_range(&range_trans->trange, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
1461*2d543d20SAndroid Build Coastguard Worker goto bad;
1462*2d543d20SAndroid Build Coastguard Worker }
1463*2d543d20SAndroid Build Coastguard Worker
1464*2d543d20SAndroid Build Coastguard Worker return 0;
1465*2d543d20SAndroid Build Coastguard Worker
1466*2d543d20SAndroid Build Coastguard Worker bad:
1467*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid range trans rule");
1468*2d543d20SAndroid Build Coastguard Worker return -1;
1469*2d543d20SAndroid Build Coastguard Worker }
1470*2d543d20SAndroid Build Coastguard Worker
validate_scope_index(sepol_handle_t * handle,const scope_index_t * scope_index,validate_t flavors[])1471*2d543d20SAndroid Build Coastguard Worker static int validate_scope_index(sepol_handle_t *handle, const scope_index_t *scope_index, validate_t flavors[])
1472*2d543d20SAndroid Build Coastguard Worker {
1473*2d543d20SAndroid Build Coastguard Worker uint32_t i;
1474*2d543d20SAndroid Build Coastguard Worker
1475*2d543d20SAndroid Build Coastguard Worker if (!ebitmap_is_empty(&scope_index->scope[SYM_COMMONS]))
1476*2d543d20SAndroid Build Coastguard Worker goto bad;
1477*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&scope_index->p_classes_scope, &flavors[SYM_CLASSES]))
1478*2d543d20SAndroid Build Coastguard Worker goto bad;
1479*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&scope_index->p_roles_scope, &flavors[SYM_ROLES]))
1480*2d543d20SAndroid Build Coastguard Worker goto bad;
1481*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&scope_index->p_types_scope, &flavors[SYM_TYPES]))
1482*2d543d20SAndroid Build Coastguard Worker goto bad;
1483*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&scope_index->p_users_scope, &flavors[SYM_USERS]))
1484*2d543d20SAndroid Build Coastguard Worker goto bad;
1485*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&scope_index->p_bools_scope, &flavors[SYM_BOOLS]))
1486*2d543d20SAndroid Build Coastguard Worker goto bad;
1487*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&scope_index->p_sens_scope, &flavors[SYM_LEVELS]))
1488*2d543d20SAndroid Build Coastguard Worker goto bad;
1489*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&scope_index->p_cat_scope, &flavors[SYM_CATS]))
1490*2d543d20SAndroid Build Coastguard Worker goto bad;
1491*2d543d20SAndroid Build Coastguard Worker
1492*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < scope_index->class_perms_len; i++)
1493*2d543d20SAndroid Build Coastguard Worker if (validate_value(i + 1, &flavors[SYM_CLASSES]))
1494*2d543d20SAndroid Build Coastguard Worker goto bad;
1495*2d543d20SAndroid Build Coastguard Worker
1496*2d543d20SAndroid Build Coastguard Worker return 0;
1497*2d543d20SAndroid Build Coastguard Worker
1498*2d543d20SAndroid Build Coastguard Worker bad:
1499*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid scope");
1500*2d543d20SAndroid Build Coastguard Worker return -1;
1501*2d543d20SAndroid Build Coastguard Worker }
1502*2d543d20SAndroid Build Coastguard Worker
1503*2d543d20SAndroid Build Coastguard Worker
validate_filename_trans_rules(sepol_handle_t * handle,const filename_trans_rule_t * filename_trans,const policydb_t * p,validate_t flavors[])1504*2d543d20SAndroid Build Coastguard Worker static int validate_filename_trans_rules(sepol_handle_t *handle, const filename_trans_rule_t *filename_trans, const policydb_t *p, validate_t flavors[])
1505*2d543d20SAndroid Build Coastguard Worker {
1506*2d543d20SAndroid Build Coastguard Worker for (; filename_trans; filename_trans = filename_trans->next) {
1507*2d543d20SAndroid Build Coastguard Worker if (validate_type_set(&filename_trans->stypes, &flavors[SYM_TYPES]))
1508*2d543d20SAndroid Build Coastguard Worker goto bad;
1509*2d543d20SAndroid Build Coastguard Worker if (validate_type_set(&filename_trans->ttypes, &flavors[SYM_TYPES]))
1510*2d543d20SAndroid Build Coastguard Worker goto bad;
1511*2d543d20SAndroid Build Coastguard Worker if (validate_value(filename_trans->tclass,&flavors[SYM_CLASSES] ))
1512*2d543d20SAndroid Build Coastguard Worker goto bad;
1513*2d543d20SAndroid Build Coastguard Worker if (validate_simpletype(filename_trans->otype, p, flavors))
1514*2d543d20SAndroid Build Coastguard Worker goto bad;
1515*2d543d20SAndroid Build Coastguard Worker
1516*2d543d20SAndroid Build Coastguard Worker /* currently only the RULE_SELF flag can be set */
1517*2d543d20SAndroid Build Coastguard Worker switch (filename_trans->flags) {
1518*2d543d20SAndroid Build Coastguard Worker case 0:
1519*2d543d20SAndroid Build Coastguard Worker break;
1520*2d543d20SAndroid Build Coastguard Worker case RULE_SELF:
1521*2d543d20SAndroid Build Coastguard Worker if (p->policyvers != POLICY_KERN && p->policyvers < MOD_POLICYDB_VERSION_SELF_TYPETRANS)
1522*2d543d20SAndroid Build Coastguard Worker goto bad;
1523*2d543d20SAndroid Build Coastguard Worker break;
1524*2d543d20SAndroid Build Coastguard Worker default:
1525*2d543d20SAndroid Build Coastguard Worker goto bad;
1526*2d543d20SAndroid Build Coastguard Worker }
1527*2d543d20SAndroid Build Coastguard Worker }
1528*2d543d20SAndroid Build Coastguard Worker
1529*2d543d20SAndroid Build Coastguard Worker return 0;
1530*2d543d20SAndroid Build Coastguard Worker
1531*2d543d20SAndroid Build Coastguard Worker bad:
1532*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid filename trans rule list");
1533*2d543d20SAndroid Build Coastguard Worker return -1;
1534*2d543d20SAndroid Build Coastguard Worker }
1535*2d543d20SAndroid Build Coastguard Worker
validate_symtabs(sepol_handle_t * handle,const symtab_t symtabs[],validate_t flavors[])1536*2d543d20SAndroid Build Coastguard Worker static int validate_symtabs(sepol_handle_t *handle, const symtab_t symtabs[], validate_t flavors[])
1537*2d543d20SAndroid Build Coastguard Worker {
1538*2d543d20SAndroid Build Coastguard Worker unsigned int i;
1539*2d543d20SAndroid Build Coastguard Worker
1540*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < SYM_NUM; i++) {
1541*2d543d20SAndroid Build Coastguard Worker if (hashtab_map(symtabs[i].table, validate_datum, &flavors[i].nprim)) {
1542*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid symtab");
1543*2d543d20SAndroid Build Coastguard Worker return -1;
1544*2d543d20SAndroid Build Coastguard Worker }
1545*2d543d20SAndroid Build Coastguard Worker }
1546*2d543d20SAndroid Build Coastguard Worker
1547*2d543d20SAndroid Build Coastguard Worker return 0;
1548*2d543d20SAndroid Build Coastguard Worker }
1549*2d543d20SAndroid Build Coastguard Worker
validate_avrule_blocks(sepol_handle_t * handle,const avrule_block_t * avrule_block,const policydb_t * p,validate_t flavors[])1550*2d543d20SAndroid Build Coastguard Worker static int validate_avrule_blocks(sepol_handle_t *handle, const avrule_block_t *avrule_block, const policydb_t *p, validate_t flavors[])
1551*2d543d20SAndroid Build Coastguard Worker {
1552*2d543d20SAndroid Build Coastguard Worker const avrule_decl_t *decl;
1553*2d543d20SAndroid Build Coastguard Worker
1554*2d543d20SAndroid Build Coastguard Worker for (; avrule_block; avrule_block = avrule_block->next) {
1555*2d543d20SAndroid Build Coastguard Worker for (decl = avrule_block->branch_list; decl != NULL; decl = decl->next) {
1556*2d543d20SAndroid Build Coastguard Worker if (validate_cond_list(handle, decl->cond_list, p, flavors))
1557*2d543d20SAndroid Build Coastguard Worker goto bad;
1558*2d543d20SAndroid Build Coastguard Worker if (validate_avrules(handle, decl->avrules, 0, p, flavors))
1559*2d543d20SAndroid Build Coastguard Worker goto bad;
1560*2d543d20SAndroid Build Coastguard Worker if (validate_role_trans_rules(handle, decl->role_tr_rules, flavors))
1561*2d543d20SAndroid Build Coastguard Worker goto bad;
1562*2d543d20SAndroid Build Coastguard Worker if (validate_role_allow_rules(handle, decl->role_allow_rules, flavors))
1563*2d543d20SAndroid Build Coastguard Worker goto bad;
1564*2d543d20SAndroid Build Coastguard Worker if (validate_range_trans_rules(handle, decl->range_tr_rules, flavors))
1565*2d543d20SAndroid Build Coastguard Worker goto bad;
1566*2d543d20SAndroid Build Coastguard Worker if (validate_scope_index(handle, &decl->required, flavors))
1567*2d543d20SAndroid Build Coastguard Worker goto bad;
1568*2d543d20SAndroid Build Coastguard Worker if (validate_scope_index(handle, &decl->declared, flavors))
1569*2d543d20SAndroid Build Coastguard Worker goto bad;
1570*2d543d20SAndroid Build Coastguard Worker if (validate_filename_trans_rules(handle, decl->filename_trans_rules, p, flavors))
1571*2d543d20SAndroid Build Coastguard Worker goto bad;
1572*2d543d20SAndroid Build Coastguard Worker if (validate_symtabs(handle, decl->symtab, flavors))
1573*2d543d20SAndroid Build Coastguard Worker goto bad;
1574*2d543d20SAndroid Build Coastguard Worker }
1575*2d543d20SAndroid Build Coastguard Worker
1576*2d543d20SAndroid Build Coastguard Worker switch (avrule_block->flags) {
1577*2d543d20SAndroid Build Coastguard Worker case 0:
1578*2d543d20SAndroid Build Coastguard Worker case AVRULE_OPTIONAL:
1579*2d543d20SAndroid Build Coastguard Worker break;
1580*2d543d20SAndroid Build Coastguard Worker default:
1581*2d543d20SAndroid Build Coastguard Worker goto bad;
1582*2d543d20SAndroid Build Coastguard Worker }
1583*2d543d20SAndroid Build Coastguard Worker }
1584*2d543d20SAndroid Build Coastguard Worker
1585*2d543d20SAndroid Build Coastguard Worker return 0;
1586*2d543d20SAndroid Build Coastguard Worker
1587*2d543d20SAndroid Build Coastguard Worker bad:
1588*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid avrule block");
1589*2d543d20SAndroid Build Coastguard Worker return -1;
1590*2d543d20SAndroid Build Coastguard Worker }
1591*2d543d20SAndroid Build Coastguard Worker
validate_permissives(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1592*2d543d20SAndroid Build Coastguard Worker static int validate_permissives(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1593*2d543d20SAndroid Build Coastguard Worker {
1594*2d543d20SAndroid Build Coastguard Worker ebitmap_node_t *node;
1595*2d543d20SAndroid Build Coastguard Worker uint32_t i;
1596*2d543d20SAndroid Build Coastguard Worker
1597*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&p->permissive_map, node, i) {
1598*2d543d20SAndroid Build Coastguard Worker if (validate_simpletype(i, p, flavors))
1599*2d543d20SAndroid Build Coastguard Worker goto bad;
1600*2d543d20SAndroid Build Coastguard Worker }
1601*2d543d20SAndroid Build Coastguard Worker
1602*2d543d20SAndroid Build Coastguard Worker return 0;
1603*2d543d20SAndroid Build Coastguard Worker
1604*2d543d20SAndroid Build Coastguard Worker bad:
1605*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid permissive type");
1606*2d543d20SAndroid Build Coastguard Worker return -1;
1607*2d543d20SAndroid Build Coastguard Worker }
1608*2d543d20SAndroid Build Coastguard Worker
validate_range_transition(hashtab_key_t key,hashtab_datum_t data,void * args)1609*2d543d20SAndroid Build Coastguard Worker static int validate_range_transition(hashtab_key_t key, hashtab_datum_t data, void *args)
1610*2d543d20SAndroid Build Coastguard Worker {
1611*2d543d20SAndroid Build Coastguard Worker const range_trans_t *rt = (const range_trans_t *)key;
1612*2d543d20SAndroid Build Coastguard Worker const mls_range_t *r = data;
1613*2d543d20SAndroid Build Coastguard Worker const map_arg_t *margs = args;
1614*2d543d20SAndroid Build Coastguard Worker const validate_t *flavors = margs->flavors;
1615*2d543d20SAndroid Build Coastguard Worker
1616*2d543d20SAndroid Build Coastguard Worker if (validate_value(rt->source_type, &flavors[SYM_TYPES]))
1617*2d543d20SAndroid Build Coastguard Worker goto bad;
1618*2d543d20SAndroid Build Coastguard Worker if (validate_value(rt->target_type, &flavors[SYM_TYPES]))
1619*2d543d20SAndroid Build Coastguard Worker goto bad;
1620*2d543d20SAndroid Build Coastguard Worker if (validate_value(rt->target_class, &flavors[SYM_CLASSES]))
1621*2d543d20SAndroid Build Coastguard Worker goto bad;
1622*2d543d20SAndroid Build Coastguard Worker
1623*2d543d20SAndroid Build Coastguard Worker if (validate_mls_range(r, &flavors[SYM_LEVELS], &flavors[SYM_CATS]))
1624*2d543d20SAndroid Build Coastguard Worker goto bad;
1625*2d543d20SAndroid Build Coastguard Worker
1626*2d543d20SAndroid Build Coastguard Worker return 0;
1627*2d543d20SAndroid Build Coastguard Worker
1628*2d543d20SAndroid Build Coastguard Worker bad:
1629*2d543d20SAndroid Build Coastguard Worker return -1;
1630*2d543d20SAndroid Build Coastguard Worker }
1631*2d543d20SAndroid Build Coastguard Worker
validate_range_transitions(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1632*2d543d20SAndroid Build Coastguard Worker static int validate_range_transitions(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1633*2d543d20SAndroid Build Coastguard Worker {
1634*2d543d20SAndroid Build Coastguard Worker map_arg_t margs = { flavors, handle, p };
1635*2d543d20SAndroid Build Coastguard Worker
1636*2d543d20SAndroid Build Coastguard Worker if (hashtab_map(p->range_tr, validate_range_transition, &margs)) {
1637*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid range transition");
1638*2d543d20SAndroid Build Coastguard Worker return -1;
1639*2d543d20SAndroid Build Coastguard Worker }
1640*2d543d20SAndroid Build Coastguard Worker
1641*2d543d20SAndroid Build Coastguard Worker return 0;
1642*2d543d20SAndroid Build Coastguard Worker }
1643*2d543d20SAndroid Build Coastguard Worker
validate_typeattr_map(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1644*2d543d20SAndroid Build Coastguard Worker static int validate_typeattr_map(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1645*2d543d20SAndroid Build Coastguard Worker {
1646*2d543d20SAndroid Build Coastguard Worker const ebitmap_t *maps = p->type_attr_map;
1647*2d543d20SAndroid Build Coastguard Worker uint32_t i;
1648*2d543d20SAndroid Build Coastguard Worker
1649*2d543d20SAndroid Build Coastguard Worker if (p->policy_type == POLICY_KERN) {
1650*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < p->p_types.nprim; i++) {
1651*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&maps[i], &flavors[SYM_TYPES]))
1652*2d543d20SAndroid Build Coastguard Worker goto bad;
1653*2d543d20SAndroid Build Coastguard Worker }
1654*2d543d20SAndroid Build Coastguard Worker } else if (maps)
1655*2d543d20SAndroid Build Coastguard Worker goto bad;
1656*2d543d20SAndroid Build Coastguard Worker
1657*2d543d20SAndroid Build Coastguard Worker return 0;
1658*2d543d20SAndroid Build Coastguard Worker
1659*2d543d20SAndroid Build Coastguard Worker bad:
1660*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid type attr map");
1661*2d543d20SAndroid Build Coastguard Worker return -1;
1662*2d543d20SAndroid Build Coastguard Worker }
1663*2d543d20SAndroid Build Coastguard Worker
validate_attrtype_map(sepol_handle_t * handle,const policydb_t * p,validate_t flavors[])1664*2d543d20SAndroid Build Coastguard Worker static int validate_attrtype_map(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[])
1665*2d543d20SAndroid Build Coastguard Worker {
1666*2d543d20SAndroid Build Coastguard Worker const ebitmap_t *maps = p->attr_type_map;
1667*2d543d20SAndroid Build Coastguard Worker uint32_t i;
1668*2d543d20SAndroid Build Coastguard Worker
1669*2d543d20SAndroid Build Coastguard Worker if (p->policy_type == POLICY_KERN) {
1670*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < p->p_types.nprim; i++) {
1671*2d543d20SAndroid Build Coastguard Worker if (validate_ebitmap(&maps[i], &flavors[SYM_TYPES]))
1672*2d543d20SAndroid Build Coastguard Worker goto bad;
1673*2d543d20SAndroid Build Coastguard Worker }
1674*2d543d20SAndroid Build Coastguard Worker } else if (maps)
1675*2d543d20SAndroid Build Coastguard Worker goto bad;
1676*2d543d20SAndroid Build Coastguard Worker
1677*2d543d20SAndroid Build Coastguard Worker return 0;
1678*2d543d20SAndroid Build Coastguard Worker
1679*2d543d20SAndroid Build Coastguard Worker bad:
1680*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid attr type map");
1681*2d543d20SAndroid Build Coastguard Worker return -1;
1682*2d543d20SAndroid Build Coastguard Worker }
1683*2d543d20SAndroid Build Coastguard Worker
validate_properties(sepol_handle_t * handle,const policydb_t * p)1684*2d543d20SAndroid Build Coastguard Worker static int validate_properties(sepol_handle_t *handle, const policydb_t *p)
1685*2d543d20SAndroid Build Coastguard Worker {
1686*2d543d20SAndroid Build Coastguard Worker switch (p->policy_type) {
1687*2d543d20SAndroid Build Coastguard Worker case POLICY_KERN:
1688*2d543d20SAndroid Build Coastguard Worker if (p->policyvers < POLICYDB_VERSION_MIN || p->policyvers > POLICYDB_VERSION_MAX)
1689*2d543d20SAndroid Build Coastguard Worker goto bad;
1690*2d543d20SAndroid Build Coastguard Worker if (p->mls && p->policyvers < POLICYDB_VERSION_MLS)
1691*2d543d20SAndroid Build Coastguard Worker goto bad;
1692*2d543d20SAndroid Build Coastguard Worker break;
1693*2d543d20SAndroid Build Coastguard Worker case POLICY_BASE:
1694*2d543d20SAndroid Build Coastguard Worker case POLICY_MOD:
1695*2d543d20SAndroid Build Coastguard Worker if (p->policyvers < MOD_POLICYDB_VERSION_MIN || p->policyvers > MOD_POLICYDB_VERSION_MAX)
1696*2d543d20SAndroid Build Coastguard Worker goto bad;
1697*2d543d20SAndroid Build Coastguard Worker if (p->mls && p->policyvers < MOD_POLICYDB_VERSION_MLS)
1698*2d543d20SAndroid Build Coastguard Worker goto bad;
1699*2d543d20SAndroid Build Coastguard Worker break;
1700*2d543d20SAndroid Build Coastguard Worker default:
1701*2d543d20SAndroid Build Coastguard Worker goto bad;
1702*2d543d20SAndroid Build Coastguard Worker }
1703*2d543d20SAndroid Build Coastguard Worker
1704*2d543d20SAndroid Build Coastguard Worker switch (p->target_platform) {
1705*2d543d20SAndroid Build Coastguard Worker case SEPOL_TARGET_SELINUX:
1706*2d543d20SAndroid Build Coastguard Worker case SEPOL_TARGET_XEN:
1707*2d543d20SAndroid Build Coastguard Worker break;
1708*2d543d20SAndroid Build Coastguard Worker default:
1709*2d543d20SAndroid Build Coastguard Worker goto bad;
1710*2d543d20SAndroid Build Coastguard Worker }
1711*2d543d20SAndroid Build Coastguard Worker
1712*2d543d20SAndroid Build Coastguard Worker switch (p->mls) {
1713*2d543d20SAndroid Build Coastguard Worker case 0:
1714*2d543d20SAndroid Build Coastguard Worker case 1:
1715*2d543d20SAndroid Build Coastguard Worker break;
1716*2d543d20SAndroid Build Coastguard Worker default:
1717*2d543d20SAndroid Build Coastguard Worker goto bad;
1718*2d543d20SAndroid Build Coastguard Worker }
1719*2d543d20SAndroid Build Coastguard Worker
1720*2d543d20SAndroid Build Coastguard Worker switch (p->handle_unknown) {
1721*2d543d20SAndroid Build Coastguard Worker case SEPOL_DENY_UNKNOWN:
1722*2d543d20SAndroid Build Coastguard Worker case SEPOL_REJECT_UNKNOWN:
1723*2d543d20SAndroid Build Coastguard Worker case SEPOL_ALLOW_UNKNOWN:
1724*2d543d20SAndroid Build Coastguard Worker break;
1725*2d543d20SAndroid Build Coastguard Worker default:
1726*2d543d20SAndroid Build Coastguard Worker goto bad;
1727*2d543d20SAndroid Build Coastguard Worker }
1728*2d543d20SAndroid Build Coastguard Worker
1729*2d543d20SAndroid Build Coastguard Worker return 0;
1730*2d543d20SAndroid Build Coastguard Worker
1731*2d543d20SAndroid Build Coastguard Worker bad:
1732*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid policy property");
1733*2d543d20SAndroid Build Coastguard Worker return -1;
1734*2d543d20SAndroid Build Coastguard Worker }
1735*2d543d20SAndroid Build Coastguard Worker
validate_policycaps(sepol_handle_t * handle,const policydb_t * p)1736*2d543d20SAndroid Build Coastguard Worker static int validate_policycaps(sepol_handle_t *handle, const policydb_t *p)
1737*2d543d20SAndroid Build Coastguard Worker {
1738*2d543d20SAndroid Build Coastguard Worker ebitmap_node_t *node;
1739*2d543d20SAndroid Build Coastguard Worker uint32_t i;
1740*2d543d20SAndroid Build Coastguard Worker
1741*2d543d20SAndroid Build Coastguard Worker ebitmap_for_each_positive_bit(&p->policycaps, node, i) {
1742*2d543d20SAndroid Build Coastguard Worker if (!sepol_polcap_getname(i))
1743*2d543d20SAndroid Build Coastguard Worker goto bad;
1744*2d543d20SAndroid Build Coastguard Worker }
1745*2d543d20SAndroid Build Coastguard Worker
1746*2d543d20SAndroid Build Coastguard Worker return 0;
1747*2d543d20SAndroid Build Coastguard Worker
1748*2d543d20SAndroid Build Coastguard Worker bad:
1749*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid policy capability");
1750*2d543d20SAndroid Build Coastguard Worker return -1;
1751*2d543d20SAndroid Build Coastguard Worker }
1752*2d543d20SAndroid Build Coastguard Worker
validate_array_destroy(validate_t flavors[])1753*2d543d20SAndroid Build Coastguard Worker static void validate_array_destroy(validate_t flavors[])
1754*2d543d20SAndroid Build Coastguard Worker {
1755*2d543d20SAndroid Build Coastguard Worker unsigned int i;
1756*2d543d20SAndroid Build Coastguard Worker
1757*2d543d20SAndroid Build Coastguard Worker for (i = 0; i < SYM_NUM; i++) {
1758*2d543d20SAndroid Build Coastguard Worker ebitmap_destroy(&flavors[i].gaps);
1759*2d543d20SAndroid Build Coastguard Worker }
1760*2d543d20SAndroid Build Coastguard Worker }
1761*2d543d20SAndroid Build Coastguard Worker
1762*2d543d20SAndroid Build Coastguard Worker /*
1763*2d543d20SAndroid Build Coastguard Worker * Validate policydb
1764*2d543d20SAndroid Build Coastguard Worker */
policydb_validate(sepol_handle_t * handle,const policydb_t * p)1765*2d543d20SAndroid Build Coastguard Worker int policydb_validate(sepol_handle_t *handle, const policydb_t *p)
1766*2d543d20SAndroid Build Coastguard Worker {
1767*2d543d20SAndroid Build Coastguard Worker validate_t flavors[SYM_NUM] = {};
1768*2d543d20SAndroid Build Coastguard Worker
1769*2d543d20SAndroid Build Coastguard Worker if (validate_array_init(p, flavors))
1770*2d543d20SAndroid Build Coastguard Worker goto bad;
1771*2d543d20SAndroid Build Coastguard Worker
1772*2d543d20SAndroid Build Coastguard Worker if (validate_properties(handle, p))
1773*2d543d20SAndroid Build Coastguard Worker goto bad;
1774*2d543d20SAndroid Build Coastguard Worker
1775*2d543d20SAndroid Build Coastguard Worker if (validate_policycaps(handle, p))
1776*2d543d20SAndroid Build Coastguard Worker goto bad;
1777*2d543d20SAndroid Build Coastguard Worker
1778*2d543d20SAndroid Build Coastguard Worker if (p->policy_type == POLICY_KERN) {
1779*2d543d20SAndroid Build Coastguard Worker if (validate_avtab(handle, &p->te_avtab, p, flavors))
1780*2d543d20SAndroid Build Coastguard Worker goto bad;
1781*2d543d20SAndroid Build Coastguard Worker if (p->policyvers >= POLICYDB_VERSION_BOOL)
1782*2d543d20SAndroid Build Coastguard Worker if (validate_cond_list(handle, p->cond_list, p, flavors))
1783*2d543d20SAndroid Build Coastguard Worker goto bad;
1784*2d543d20SAndroid Build Coastguard Worker if (validate_role_transes(handle, p->role_tr, flavors))
1785*2d543d20SAndroid Build Coastguard Worker goto bad;
1786*2d543d20SAndroid Build Coastguard Worker if (validate_role_allows(handle, p->role_allow, flavors))
1787*2d543d20SAndroid Build Coastguard Worker goto bad;
1788*2d543d20SAndroid Build Coastguard Worker if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS)
1789*2d543d20SAndroid Build Coastguard Worker if (validate_filename_trans_hashtab(handle, p, flavors))
1790*2d543d20SAndroid Build Coastguard Worker goto bad;
1791*2d543d20SAndroid Build Coastguard Worker } else {
1792*2d543d20SAndroid Build Coastguard Worker if (validate_avrule_blocks(handle, p->global, p, flavors))
1793*2d543d20SAndroid Build Coastguard Worker goto bad;
1794*2d543d20SAndroid Build Coastguard Worker }
1795*2d543d20SAndroid Build Coastguard Worker
1796*2d543d20SAndroid Build Coastguard Worker if (validate_ocontexts(handle, p, flavors))
1797*2d543d20SAndroid Build Coastguard Worker goto bad;
1798*2d543d20SAndroid Build Coastguard Worker
1799*2d543d20SAndroid Build Coastguard Worker if (validate_genfs(handle, p, flavors))
1800*2d543d20SAndroid Build Coastguard Worker goto bad;
1801*2d543d20SAndroid Build Coastguard Worker
1802*2d543d20SAndroid Build Coastguard Worker if (validate_scopes(handle, p->scope, p->global))
1803*2d543d20SAndroid Build Coastguard Worker goto bad;
1804*2d543d20SAndroid Build Coastguard Worker
1805*2d543d20SAndroid Build Coastguard Worker if (validate_datum_array_gaps(handle, p, flavors))
1806*2d543d20SAndroid Build Coastguard Worker goto bad;
1807*2d543d20SAndroid Build Coastguard Worker
1808*2d543d20SAndroid Build Coastguard Worker if (validate_datum_array_entries(handle, p, flavors))
1809*2d543d20SAndroid Build Coastguard Worker goto bad;
1810*2d543d20SAndroid Build Coastguard Worker
1811*2d543d20SAndroid Build Coastguard Worker if (validate_permissives(handle, p, flavors))
1812*2d543d20SAndroid Build Coastguard Worker goto bad;
1813*2d543d20SAndroid Build Coastguard Worker
1814*2d543d20SAndroid Build Coastguard Worker if (validate_range_transitions(handle, p, flavors))
1815*2d543d20SAndroid Build Coastguard Worker goto bad;
1816*2d543d20SAndroid Build Coastguard Worker
1817*2d543d20SAndroid Build Coastguard Worker if (validate_typeattr_map(handle, p, flavors))
1818*2d543d20SAndroid Build Coastguard Worker goto bad;
1819*2d543d20SAndroid Build Coastguard Worker
1820*2d543d20SAndroid Build Coastguard Worker if (validate_attrtype_map(handle, p, flavors))
1821*2d543d20SAndroid Build Coastguard Worker goto bad;
1822*2d543d20SAndroid Build Coastguard Worker
1823*2d543d20SAndroid Build Coastguard Worker validate_array_destroy(flavors);
1824*2d543d20SAndroid Build Coastguard Worker
1825*2d543d20SAndroid Build Coastguard Worker return 0;
1826*2d543d20SAndroid Build Coastguard Worker
1827*2d543d20SAndroid Build Coastguard Worker bad:
1828*2d543d20SAndroid Build Coastguard Worker ERR(handle, "Invalid policydb");
1829*2d543d20SAndroid Build Coastguard Worker validate_array_destroy(flavors);
1830*2d543d20SAndroid Build Coastguard Worker return -1;
1831*2d543d20SAndroid Build Coastguard Worker }
1832