diff options
Diffstat (limited to 'security/selinux/ss/policydb.c')
-rw-r--r-- | security/selinux/ss/policydb.c | 701 |
1 files changed, 351 insertions, 350 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 94f630d93a5c..be9de3872837 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -148,32 +148,30 @@ static int roles_init(struct policydb *p) | |||
148 | int rc; | 148 | int rc; |
149 | struct role_datum *role; | 149 | struct role_datum *role; |
150 | 150 | ||
151 | rc = -ENOMEM; | ||
151 | role = kzalloc(sizeof(*role), GFP_KERNEL); | 152 | role = kzalloc(sizeof(*role), GFP_KERNEL); |
152 | if (!role) { | 153 | if (!role) |
153 | rc = -ENOMEM; | ||
154 | goto out; | 154 | goto out; |
155 | } | 155 | |
156 | rc = -EINVAL; | ||
156 | role->value = ++p->p_roles.nprim; | 157 | role->value = ++p->p_roles.nprim; |
157 | if (role->value != OBJECT_R_VAL) { | 158 | if (role->value != OBJECT_R_VAL) |
158 | rc = -EINVAL; | 159 | goto out; |
159 | goto out_free_role; | 160 | |
160 | } | 161 | rc = -ENOMEM; |
161 | key = kstrdup(OBJECT_R, GFP_KERNEL); | 162 | key = kstrdup(OBJECT_R, GFP_KERNEL); |
162 | if (!key) { | 163 | if (!key) |
163 | rc = -ENOMEM; | 164 | goto out; |
164 | goto out_free_role; | 165 | |
165 | } | ||
166 | rc = hashtab_insert(p->p_roles.table, key, role); | 166 | rc = hashtab_insert(p->p_roles.table, key, role); |
167 | if (rc) | 167 | if (rc) |
168 | goto out_free_key; | 168 | goto out; |
169 | out: | ||
170 | return rc; | ||
171 | 169 | ||
172 | out_free_key: | 170 | return 0; |
171 | out: | ||
173 | kfree(key); | 172 | kfree(key); |
174 | out_free_role: | ||
175 | kfree(role); | 173 | kfree(role); |
176 | goto out; | 174 | return rc; |
177 | } | 175 | } |
178 | 176 | ||
179 | static u32 rangetr_hash(struct hashtab *h, const void *k) | 177 | static u32 rangetr_hash(struct hashtab *h, const void *k) |
@@ -213,35 +211,33 @@ static int policydb_init(struct policydb *p) | |||
213 | for (i = 0; i < SYM_NUM; i++) { | 211 | for (i = 0; i < SYM_NUM; i++) { |
214 | rc = symtab_init(&p->symtab[i], symtab_sizes[i]); | 212 | rc = symtab_init(&p->symtab[i], symtab_sizes[i]); |
215 | if (rc) | 213 | if (rc) |
216 | goto out_free_symtab; | 214 | goto out; |
217 | } | 215 | } |
218 | 216 | ||
219 | rc = avtab_init(&p->te_avtab); | 217 | rc = avtab_init(&p->te_avtab); |
220 | if (rc) | 218 | if (rc) |
221 | goto out_free_symtab; | 219 | goto out; |
222 | 220 | ||
223 | rc = roles_init(p); | 221 | rc = roles_init(p); |
224 | if (rc) | 222 | if (rc) |
225 | goto out_free_symtab; | 223 | goto out; |
226 | 224 | ||
227 | rc = cond_policydb_init(p); | 225 | rc = cond_policydb_init(p); |
228 | if (rc) | 226 | if (rc) |
229 | goto out_free_symtab; | 227 | goto out; |
230 | 228 | ||
231 | p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); | 229 | p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); |
232 | if (!p->range_tr) | 230 | if (!p->range_tr) |
233 | goto out_free_symtab; | 231 | goto out; |
234 | 232 | ||
235 | ebitmap_init(&p->policycaps); | 233 | ebitmap_init(&p->policycaps); |
236 | ebitmap_init(&p->permissive_map); | 234 | ebitmap_init(&p->permissive_map); |
237 | 235 | ||
236 | return 0; | ||
238 | out: | 237 | out: |
239 | return rc; | ||
240 | |||
241 | out_free_symtab: | ||
242 | for (i = 0; i < SYM_NUM; i++) | 238 | for (i = 0; i < SYM_NUM; i++) |
243 | hashtab_destroy(p->symtab[i].table); | 239 | hashtab_destroy(p->symtab[i].table); |
244 | goto out; | 240 | return rc; |
245 | } | 241 | } |
246 | 242 | ||
247 | /* | 243 | /* |
@@ -258,12 +254,17 @@ static int common_index(void *key, void *datum, void *datap) | |||
258 | { | 254 | { |
259 | struct policydb *p; | 255 | struct policydb *p; |
260 | struct common_datum *comdatum; | 256 | struct common_datum *comdatum; |
257 | struct flex_array *fa; | ||
261 | 258 | ||
262 | comdatum = datum; | 259 | comdatum = datum; |
263 | p = datap; | 260 | p = datap; |
264 | if (!comdatum->value || comdatum->value > p->p_commons.nprim) | 261 | if (!comdatum->value || comdatum->value > p->p_commons.nprim) |
265 | return -EINVAL; | 262 | return -EINVAL; |
266 | p->p_common_val_to_name[comdatum->value - 1] = key; | 263 | |
264 | fa = p->sym_val_to_name[SYM_COMMONS]; | ||
265 | if (flex_array_put_ptr(fa, comdatum->value - 1, key, | ||
266 | GFP_KERNEL | __GFP_ZERO)) | ||
267 | BUG(); | ||
267 | return 0; | 268 | return 0; |
268 | } | 269 | } |
269 | 270 | ||
@@ -271,12 +272,16 @@ static int class_index(void *key, void *datum, void *datap) | |||
271 | { | 272 | { |
272 | struct policydb *p; | 273 | struct policydb *p; |
273 | struct class_datum *cladatum; | 274 | struct class_datum *cladatum; |
275 | struct flex_array *fa; | ||
274 | 276 | ||
275 | cladatum = datum; | 277 | cladatum = datum; |
276 | p = datap; | 278 | p = datap; |
277 | if (!cladatum->value || cladatum->value > p->p_classes.nprim) | 279 | if (!cladatum->value || cladatum->value > p->p_classes.nprim) |
278 | return -EINVAL; | 280 | return -EINVAL; |
279 | p->p_class_val_to_name[cladatum->value - 1] = key; | 281 | fa = p->sym_val_to_name[SYM_CLASSES]; |
282 | if (flex_array_put_ptr(fa, cladatum->value - 1, key, | ||
283 | GFP_KERNEL | __GFP_ZERO)) | ||
284 | BUG(); | ||
280 | p->class_val_to_struct[cladatum->value - 1] = cladatum; | 285 | p->class_val_to_struct[cladatum->value - 1] = cladatum; |
281 | return 0; | 286 | return 0; |
282 | } | 287 | } |
@@ -285,6 +290,7 @@ static int role_index(void *key, void *datum, void *datap) | |||
285 | { | 290 | { |
286 | struct policydb *p; | 291 | struct policydb *p; |
287 | struct role_datum *role; | 292 | struct role_datum *role; |
293 | struct flex_array *fa; | ||
288 | 294 | ||
289 | role = datum; | 295 | role = datum; |
290 | p = datap; | 296 | p = datap; |
@@ -292,7 +298,11 @@ static int role_index(void *key, void *datum, void *datap) | |||
292 | || role->value > p->p_roles.nprim | 298 | || role->value > p->p_roles.nprim |
293 | || role->bounds > p->p_roles.nprim) | 299 | || role->bounds > p->p_roles.nprim) |
294 | return -EINVAL; | 300 | return -EINVAL; |
295 | p->p_role_val_to_name[role->value - 1] = key; | 301 | |
302 | fa = p->sym_val_to_name[SYM_ROLES]; | ||
303 | if (flex_array_put_ptr(fa, role->value - 1, key, | ||
304 | GFP_KERNEL | __GFP_ZERO)) | ||
305 | BUG(); | ||
296 | p->role_val_to_struct[role->value - 1] = role; | 306 | p->role_val_to_struct[role->value - 1] = role; |
297 | return 0; | 307 | return 0; |
298 | } | 308 | } |
@@ -301,6 +311,7 @@ static int type_index(void *key, void *datum, void *datap) | |||
301 | { | 311 | { |
302 | struct policydb *p; | 312 | struct policydb *p; |
303 | struct type_datum *typdatum; | 313 | struct type_datum *typdatum; |
314 | struct flex_array *fa; | ||
304 | 315 | ||
305 | typdatum = datum; | 316 | typdatum = datum; |
306 | p = datap; | 317 | p = datap; |
@@ -310,8 +321,15 @@ static int type_index(void *key, void *datum, void *datap) | |||
310 | || typdatum->value > p->p_types.nprim | 321 | || typdatum->value > p->p_types.nprim |
311 | || typdatum->bounds > p->p_types.nprim) | 322 | || typdatum->bounds > p->p_types.nprim) |
312 | return -EINVAL; | 323 | return -EINVAL; |
313 | p->p_type_val_to_name[typdatum->value - 1] = key; | 324 | fa = p->sym_val_to_name[SYM_TYPES]; |
314 | p->type_val_to_struct[typdatum->value - 1] = typdatum; | 325 | if (flex_array_put_ptr(fa, typdatum->value - 1, key, |
326 | GFP_KERNEL | __GFP_ZERO)) | ||
327 | BUG(); | ||
328 | |||
329 | fa = p->type_val_to_struct_array; | ||
330 | if (flex_array_put_ptr(fa, typdatum->value - 1, typdatum, | ||
331 | GFP_KERNEL | __GFP_ZERO)) | ||
332 | BUG(); | ||
315 | } | 333 | } |
316 | 334 | ||
317 | return 0; | 335 | return 0; |
@@ -321,6 +339,7 @@ static int user_index(void *key, void *datum, void *datap) | |||
321 | { | 339 | { |
322 | struct policydb *p; | 340 | struct policydb *p; |
323 | struct user_datum *usrdatum; | 341 | struct user_datum *usrdatum; |
342 | struct flex_array *fa; | ||
324 | 343 | ||
325 | usrdatum = datum; | 344 | usrdatum = datum; |
326 | p = datap; | 345 | p = datap; |
@@ -328,7 +347,11 @@ static int user_index(void *key, void *datum, void *datap) | |||
328 | || usrdatum->value > p->p_users.nprim | 347 | || usrdatum->value > p->p_users.nprim |
329 | || usrdatum->bounds > p->p_users.nprim) | 348 | || usrdatum->bounds > p->p_users.nprim) |
330 | return -EINVAL; | 349 | return -EINVAL; |
331 | p->p_user_val_to_name[usrdatum->value - 1] = key; | 350 | |
351 | fa = p->sym_val_to_name[SYM_USERS]; | ||
352 | if (flex_array_put_ptr(fa, usrdatum->value - 1, key, | ||
353 | GFP_KERNEL | __GFP_ZERO)) | ||
354 | BUG(); | ||
332 | p->user_val_to_struct[usrdatum->value - 1] = usrdatum; | 355 | p->user_val_to_struct[usrdatum->value - 1] = usrdatum; |
333 | return 0; | 356 | return 0; |
334 | } | 357 | } |
@@ -337,6 +360,7 @@ static int sens_index(void *key, void *datum, void *datap) | |||
337 | { | 360 | { |
338 | struct policydb *p; | 361 | struct policydb *p; |
339 | struct level_datum *levdatum; | 362 | struct level_datum *levdatum; |
363 | struct flex_array *fa; | ||
340 | 364 | ||
341 | levdatum = datum; | 365 | levdatum = datum; |
342 | p = datap; | 366 | p = datap; |
@@ -345,7 +369,10 @@ static int sens_index(void *key, void *datum, void *datap) | |||
345 | if (!levdatum->level->sens || | 369 | if (!levdatum->level->sens || |
346 | levdatum->level->sens > p->p_levels.nprim) | 370 | levdatum->level->sens > p->p_levels.nprim) |
347 | return -EINVAL; | 371 | return -EINVAL; |
348 | p->p_sens_val_to_name[levdatum->level->sens - 1] = key; | 372 | fa = p->sym_val_to_name[SYM_LEVELS]; |
373 | if (flex_array_put_ptr(fa, levdatum->level->sens - 1, key, | ||
374 | GFP_KERNEL | __GFP_ZERO)) | ||
375 | BUG(); | ||
349 | } | 376 | } |
350 | 377 | ||
351 | return 0; | 378 | return 0; |
@@ -355,6 +382,7 @@ static int cat_index(void *key, void *datum, void *datap) | |||
355 | { | 382 | { |
356 | struct policydb *p; | 383 | struct policydb *p; |
357 | struct cat_datum *catdatum; | 384 | struct cat_datum *catdatum; |
385 | struct flex_array *fa; | ||
358 | 386 | ||
359 | catdatum = datum; | 387 | catdatum = datum; |
360 | p = datap; | 388 | p = datap; |
@@ -362,7 +390,10 @@ static int cat_index(void *key, void *datum, void *datap) | |||
362 | if (!catdatum->isalias) { | 390 | if (!catdatum->isalias) { |
363 | if (!catdatum->value || catdatum->value > p->p_cats.nprim) | 391 | if (!catdatum->value || catdatum->value > p->p_cats.nprim) |
364 | return -EINVAL; | 392 | return -EINVAL; |
365 | p->p_cat_val_to_name[catdatum->value - 1] = key; | 393 | fa = p->sym_val_to_name[SYM_CATS]; |
394 | if (flex_array_put_ptr(fa, catdatum->value - 1, key, | ||
395 | GFP_KERNEL | __GFP_ZERO)) | ||
396 | BUG(); | ||
366 | } | 397 | } |
367 | 398 | ||
368 | return 0; | 399 | return 0; |
@@ -380,47 +411,6 @@ static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) = | |||
380 | cat_index, | 411 | cat_index, |
381 | }; | 412 | }; |
382 | 413 | ||
383 | /* | ||
384 | * Define the common val_to_name array and the class | ||
385 | * val_to_name and val_to_struct arrays in a policy | ||
386 | * database structure. | ||
387 | * | ||
388 | * Caller must clean up upon failure. | ||
389 | */ | ||
390 | static int policydb_index_classes(struct policydb *p) | ||
391 | { | ||
392 | int rc; | ||
393 | |||
394 | p->p_common_val_to_name = | ||
395 | kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL); | ||
396 | if (!p->p_common_val_to_name) { | ||
397 | rc = -ENOMEM; | ||
398 | goto out; | ||
399 | } | ||
400 | |||
401 | rc = hashtab_map(p->p_commons.table, common_index, p); | ||
402 | if (rc) | ||
403 | goto out; | ||
404 | |||
405 | p->class_val_to_struct = | ||
406 | kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), GFP_KERNEL); | ||
407 | if (!p->class_val_to_struct) { | ||
408 | rc = -ENOMEM; | ||
409 | goto out; | ||
410 | } | ||
411 | |||
412 | p->p_class_val_to_name = | ||
413 | kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL); | ||
414 | if (!p->p_class_val_to_name) { | ||
415 | rc = -ENOMEM; | ||
416 | goto out; | ||
417 | } | ||
418 | |||
419 | rc = hashtab_map(p->p_classes.table, class_index, p); | ||
420 | out: | ||
421 | return rc; | ||
422 | } | ||
423 | |||
424 | #ifdef DEBUG_HASHES | 414 | #ifdef DEBUG_HASHES |
425 | static void symtab_hash_eval(struct symtab *s) | 415 | static void symtab_hash_eval(struct symtab *s) |
426 | { | 416 | { |
@@ -458,9 +448,9 @@ static inline void rangetr_hash_eval(struct hashtab *h) | |||
458 | * | 448 | * |
459 | * Caller must clean up on failure. | 449 | * Caller must clean up on failure. |
460 | */ | 450 | */ |
461 | static int policydb_index_others(struct policydb *p) | 451 | static int policydb_index(struct policydb *p) |
462 | { | 452 | { |
463 | int i, rc = 0; | 453 | int i, rc; |
464 | 454 | ||
465 | printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", | 455 | printk(KERN_DEBUG "SELinux: %d users, %d roles, %d types, %d bools", |
466 | p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); | 456 | p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim); |
@@ -477,47 +467,63 @@ static int policydb_index_others(struct policydb *p) | |||
477 | symtab_hash_eval(p->symtab); | 467 | symtab_hash_eval(p->symtab); |
478 | #endif | 468 | #endif |
479 | 469 | ||
470 | rc = -ENOMEM; | ||
471 | p->class_val_to_struct = | ||
472 | kmalloc(p->p_classes.nprim * sizeof(*(p->class_val_to_struct)), | ||
473 | GFP_KERNEL); | ||
474 | if (!p->class_val_to_struct) | ||
475 | goto out; | ||
476 | |||
477 | rc = -ENOMEM; | ||
480 | p->role_val_to_struct = | 478 | p->role_val_to_struct = |
481 | kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)), | 479 | kmalloc(p->p_roles.nprim * sizeof(*(p->role_val_to_struct)), |
482 | GFP_KERNEL); | 480 | GFP_KERNEL); |
483 | if (!p->role_val_to_struct) { | 481 | if (!p->role_val_to_struct) |
484 | rc = -ENOMEM; | ||
485 | goto out; | 482 | goto out; |
486 | } | ||
487 | 483 | ||
484 | rc = -ENOMEM; | ||
488 | p->user_val_to_struct = | 485 | p->user_val_to_struct = |
489 | kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)), | 486 | kmalloc(p->p_users.nprim * sizeof(*(p->user_val_to_struct)), |
490 | GFP_KERNEL); | 487 | GFP_KERNEL); |
491 | if (!p->user_val_to_struct) { | 488 | if (!p->user_val_to_struct) |
492 | rc = -ENOMEM; | ||
493 | goto out; | 489 | goto out; |
494 | } | ||
495 | 490 | ||
496 | p->type_val_to_struct = | 491 | /* Yes, I want the sizeof the pointer, not the structure */ |
497 | kmalloc(p->p_types.nprim * sizeof(*(p->type_val_to_struct)), | 492 | rc = -ENOMEM; |
498 | GFP_KERNEL); | 493 | p->type_val_to_struct_array = flex_array_alloc(sizeof(struct type_datum *), |
499 | if (!p->type_val_to_struct) { | 494 | p->p_types.nprim, |
500 | rc = -ENOMEM; | 495 | GFP_KERNEL | __GFP_ZERO); |
496 | if (!p->type_val_to_struct_array) | ||
501 | goto out; | 497 | goto out; |
502 | } | ||
503 | 498 | ||
504 | if (cond_init_bool_indexes(p)) { | 499 | rc = flex_array_prealloc(p->type_val_to_struct_array, 0, |
505 | rc = -ENOMEM; | 500 | p->p_types.nprim - 1, GFP_KERNEL | __GFP_ZERO); |
501 | if (rc) | ||
506 | goto out; | 502 | goto out; |
507 | } | ||
508 | 503 | ||
509 | for (i = SYM_ROLES; i < SYM_NUM; i++) { | 504 | rc = -ENOMEM; |
510 | p->sym_val_to_name[i] = | 505 | if (cond_init_bool_indexes(p)) |
511 | kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL); | 506 | goto out; |
512 | if (!p->sym_val_to_name[i]) { | 507 | |
513 | rc = -ENOMEM; | 508 | for (i = 0; i < SYM_NUM; i++) { |
509 | rc = -ENOMEM; | ||
510 | p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *), | ||
511 | p->symtab[i].nprim, | ||
512 | GFP_KERNEL | __GFP_ZERO); | ||
513 | if (!p->sym_val_to_name[i]) | ||
514 | goto out; | 514 | goto out; |
515 | } | 515 | |
516 | rc = flex_array_prealloc(p->sym_val_to_name[i], | ||
517 | 0, p->symtab[i].nprim - 1, | ||
518 | GFP_KERNEL | __GFP_ZERO); | ||
519 | if (rc) | ||
520 | goto out; | ||
521 | |||
516 | rc = hashtab_map(p->symtab[i].table, index_f[i], p); | 522 | rc = hashtab_map(p->symtab[i].table, index_f[i], p); |
517 | if (rc) | 523 | if (rc) |
518 | goto out; | 524 | goto out; |
519 | } | 525 | } |
520 | 526 | rc = 0; | |
521 | out: | 527 | out: |
522 | return rc; | 528 | return rc; |
523 | } | 529 | } |
@@ -540,9 +546,11 @@ static int common_destroy(void *key, void *datum, void *p) | |||
540 | struct common_datum *comdatum; | 546 | struct common_datum *comdatum; |
541 | 547 | ||
542 | kfree(key); | 548 | kfree(key); |
543 | comdatum = datum; | 549 | if (datum) { |
544 | hashtab_map(comdatum->permissions.table, perm_destroy, NULL); | 550 | comdatum = datum; |
545 | hashtab_destroy(comdatum->permissions.table); | 551 | hashtab_map(comdatum->permissions.table, perm_destroy, NULL); |
552 | hashtab_destroy(comdatum->permissions.table); | ||
553 | } | ||
546 | kfree(datum); | 554 | kfree(datum); |
547 | return 0; | 555 | return 0; |
548 | } | 556 | } |
@@ -554,38 +562,40 @@ static int cls_destroy(void *key, void *datum, void *p) | |||
554 | struct constraint_expr *e, *etmp; | 562 | struct constraint_expr *e, *etmp; |
555 | 563 | ||
556 | kfree(key); | 564 | kfree(key); |
557 | cladatum = datum; | 565 | if (datum) { |
558 | hashtab_map(cladatum->permissions.table, perm_destroy, NULL); | 566 | cladatum = datum; |
559 | hashtab_destroy(cladatum->permissions.table); | 567 | hashtab_map(cladatum->permissions.table, perm_destroy, NULL); |
560 | constraint = cladatum->constraints; | 568 | hashtab_destroy(cladatum->permissions.table); |
561 | while (constraint) { | 569 | constraint = cladatum->constraints; |
562 | e = constraint->expr; | 570 | while (constraint) { |
563 | while (e) { | 571 | e = constraint->expr; |
564 | ebitmap_destroy(&e->names); | 572 | while (e) { |
565 | etmp = e; | 573 | ebitmap_destroy(&e->names); |
566 | e = e->next; | 574 | etmp = e; |
567 | kfree(etmp); | 575 | e = e->next; |
576 | kfree(etmp); | ||
577 | } | ||
578 | ctemp = constraint; | ||
579 | constraint = constraint->next; | ||
580 | kfree(ctemp); | ||
568 | } | 581 | } |
569 | ctemp = constraint; | 582 | |
570 | constraint = constraint->next; | 583 | constraint = cladatum->validatetrans; |
571 | kfree(ctemp); | 584 | while (constraint) { |
572 | } | 585 | e = constraint->expr; |
573 | 586 | while (e) { | |
574 | constraint = cladatum->validatetrans; | 587 | ebitmap_destroy(&e->names); |
575 | while (constraint) { | 588 | etmp = e; |
576 | e = constraint->expr; | 589 | e = e->next; |
577 | while (e) { | 590 | kfree(etmp); |
578 | ebitmap_destroy(&e->names); | 591 | } |
579 | etmp = e; | 592 | ctemp = constraint; |
580 | e = e->next; | 593 | constraint = constraint->next; |
581 | kfree(etmp); | 594 | kfree(ctemp); |
582 | } | 595 | } |
583 | ctemp = constraint; | ||
584 | constraint = constraint->next; | ||
585 | kfree(ctemp); | ||
586 | } | ||
587 | 596 | ||
588 | kfree(cladatum->comkey); | 597 | kfree(cladatum->comkey); |
598 | } | ||
589 | kfree(datum); | 599 | kfree(datum); |
590 | return 0; | 600 | return 0; |
591 | } | 601 | } |
@@ -595,9 +605,11 @@ static int role_destroy(void *key, void *datum, void *p) | |||
595 | struct role_datum *role; | 605 | struct role_datum *role; |
596 | 606 | ||
597 | kfree(key); | 607 | kfree(key); |
598 | role = datum; | 608 | if (datum) { |
599 | ebitmap_destroy(&role->dominates); | 609 | role = datum; |
600 | ebitmap_destroy(&role->types); | 610 | ebitmap_destroy(&role->dominates); |
611 | ebitmap_destroy(&role->types); | ||
612 | } | ||
601 | kfree(datum); | 613 | kfree(datum); |
602 | return 0; | 614 | return 0; |
603 | } | 615 | } |
@@ -614,11 +626,13 @@ static int user_destroy(void *key, void *datum, void *p) | |||
614 | struct user_datum *usrdatum; | 626 | struct user_datum *usrdatum; |
615 | 627 | ||
616 | kfree(key); | 628 | kfree(key); |
617 | usrdatum = datum; | 629 | if (datum) { |
618 | ebitmap_destroy(&usrdatum->roles); | 630 | usrdatum = datum; |
619 | ebitmap_destroy(&usrdatum->range.level[0].cat); | 631 | ebitmap_destroy(&usrdatum->roles); |
620 | ebitmap_destroy(&usrdatum->range.level[1].cat); | 632 | ebitmap_destroy(&usrdatum->range.level[0].cat); |
621 | ebitmap_destroy(&usrdatum->dfltlevel.cat); | 633 | ebitmap_destroy(&usrdatum->range.level[1].cat); |
634 | ebitmap_destroy(&usrdatum->dfltlevel.cat); | ||
635 | } | ||
622 | kfree(datum); | 636 | kfree(datum); |
623 | return 0; | 637 | return 0; |
624 | } | 638 | } |
@@ -628,9 +642,11 @@ static int sens_destroy(void *key, void *datum, void *p) | |||
628 | struct level_datum *levdatum; | 642 | struct level_datum *levdatum; |
629 | 643 | ||
630 | kfree(key); | 644 | kfree(key); |
631 | levdatum = datum; | 645 | if (datum) { |
632 | ebitmap_destroy(&levdatum->level->cat); | 646 | levdatum = datum; |
633 | kfree(levdatum->level); | 647 | ebitmap_destroy(&levdatum->level->cat); |
648 | kfree(levdatum->level); | ||
649 | } | ||
634 | kfree(datum); | 650 | kfree(datum); |
635 | return 0; | 651 | return 0; |
636 | } | 652 | } |
@@ -695,13 +711,16 @@ void policydb_destroy(struct policydb *p) | |||
695 | hashtab_destroy(p->symtab[i].table); | 711 | hashtab_destroy(p->symtab[i].table); |
696 | } | 712 | } |
697 | 713 | ||
698 | for (i = 0; i < SYM_NUM; i++) | 714 | for (i = 0; i < SYM_NUM; i++) { |
699 | kfree(p->sym_val_to_name[i]); | 715 | if (p->sym_val_to_name[i]) |
716 | flex_array_free(p->sym_val_to_name[i]); | ||
717 | } | ||
700 | 718 | ||
701 | kfree(p->class_val_to_struct); | 719 | kfree(p->class_val_to_struct); |
702 | kfree(p->role_val_to_struct); | 720 | kfree(p->role_val_to_struct); |
703 | kfree(p->user_val_to_struct); | 721 | kfree(p->user_val_to_struct); |
704 | kfree(p->type_val_to_struct); | 722 | if (p->type_val_to_struct_array) |
723 | flex_array_free(p->type_val_to_struct_array); | ||
705 | 724 | ||
706 | avtab_destroy(&p->te_avtab); | 725 | avtab_destroy(&p->te_avtab); |
707 | 726 | ||
@@ -785,19 +804,21 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s) | |||
785 | 804 | ||
786 | head = p->ocontexts[OCON_ISID]; | 805 | head = p->ocontexts[OCON_ISID]; |
787 | for (c = head; c; c = c->next) { | 806 | for (c = head; c; c = c->next) { |
807 | rc = -EINVAL; | ||
788 | if (!c->context[0].user) { | 808 | if (!c->context[0].user) { |
789 | printk(KERN_ERR "SELinux: SID %s was never " | 809 | printk(KERN_ERR "SELinux: SID %s was never defined.\n", |
790 | "defined.\n", c->u.name); | 810 | c->u.name); |
791 | rc = -EINVAL; | ||
792 | goto out; | 811 | goto out; |
793 | } | 812 | } |
794 | if (sidtab_insert(s, c->sid[0], &c->context[0])) { | 813 | |
795 | printk(KERN_ERR "SELinux: unable to load initial " | 814 | rc = sidtab_insert(s, c->sid[0], &c->context[0]); |
796 | "SID %s.\n", c->u.name); | 815 | if (rc) { |
797 | rc = -EINVAL; | 816 | printk(KERN_ERR "SELinux: unable to load initial SID %s.\n", |
817 | c->u.name); | ||
798 | goto out; | 818 | goto out; |
799 | } | 819 | } |
800 | } | 820 | } |
821 | rc = 0; | ||
801 | out: | 822 | out: |
802 | return rc; | 823 | return rc; |
803 | } | 824 | } |
@@ -846,8 +867,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c) | |||
846 | * Role must be authorized for the type. | 867 | * Role must be authorized for the type. |
847 | */ | 868 | */ |
848 | role = p->role_val_to_struct[c->role - 1]; | 869 | role = p->role_val_to_struct[c->role - 1]; |
849 | if (!ebitmap_get_bit(&role->types, | 870 | if (!ebitmap_get_bit(&role->types, c->type - 1)) |
850 | c->type - 1)) | ||
851 | /* role may not be associated with type */ | 871 | /* role may not be associated with type */ |
852 | return 0; | 872 | return 0; |
853 | 873 | ||
@@ -858,8 +878,7 @@ int policydb_context_isvalid(struct policydb *p, struct context *c) | |||
858 | if (!usrdatum) | 878 | if (!usrdatum) |
859 | return 0; | 879 | return 0; |
860 | 880 | ||
861 | if (!ebitmap_get_bit(&usrdatum->roles, | 881 | if (!ebitmap_get_bit(&usrdatum->roles, c->role - 1)) |
862 | c->role - 1)) | ||
863 | /* user may not be associated with role */ | 882 | /* user may not be associated with role */ |
864 | return 0; | 883 | return 0; |
865 | } | 884 | } |
@@ -881,20 +900,22 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) | |||
881 | int rc; | 900 | int rc; |
882 | 901 | ||
883 | rc = next_entry(buf, fp, sizeof(u32)); | 902 | rc = next_entry(buf, fp, sizeof(u32)); |
884 | if (rc < 0) | 903 | if (rc) |
885 | goto out; | 904 | goto out; |
886 | 905 | ||
906 | rc = -EINVAL; | ||
887 | items = le32_to_cpu(buf[0]); | 907 | items = le32_to_cpu(buf[0]); |
888 | if (items > ARRAY_SIZE(buf)) { | 908 | if (items > ARRAY_SIZE(buf)) { |
889 | printk(KERN_ERR "SELinux: mls: range overflow\n"); | 909 | printk(KERN_ERR "SELinux: mls: range overflow\n"); |
890 | rc = -EINVAL; | ||
891 | goto out; | 910 | goto out; |
892 | } | 911 | } |
912 | |||
893 | rc = next_entry(buf, fp, sizeof(u32) * items); | 913 | rc = next_entry(buf, fp, sizeof(u32) * items); |
894 | if (rc < 0) { | 914 | if (rc) { |
895 | printk(KERN_ERR "SELinux: mls: truncated range\n"); | 915 | printk(KERN_ERR "SELinux: mls: truncated range\n"); |
896 | goto out; | 916 | goto out; |
897 | } | 917 | } |
918 | |||
898 | r->level[0].sens = le32_to_cpu(buf[0]); | 919 | r->level[0].sens = le32_to_cpu(buf[0]); |
899 | if (items > 1) | 920 | if (items > 1) |
900 | r->level[1].sens = le32_to_cpu(buf[1]); | 921 | r->level[1].sens = le32_to_cpu(buf[1]); |
@@ -903,15 +924,13 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) | |||
903 | 924 | ||
904 | rc = ebitmap_read(&r->level[0].cat, fp); | 925 | rc = ebitmap_read(&r->level[0].cat, fp); |
905 | if (rc) { | 926 | if (rc) { |
906 | printk(KERN_ERR "SELinux: mls: error reading low " | 927 | printk(KERN_ERR "SELinux: mls: error reading low categories\n"); |
907 | "categories\n"); | ||
908 | goto out; | 928 | goto out; |
909 | } | 929 | } |
910 | if (items > 1) { | 930 | if (items > 1) { |
911 | rc = ebitmap_read(&r->level[1].cat, fp); | 931 | rc = ebitmap_read(&r->level[1].cat, fp); |
912 | if (rc) { | 932 | if (rc) { |
913 | printk(KERN_ERR "SELinux: mls: error reading high " | 933 | printk(KERN_ERR "SELinux: mls: error reading high categories\n"); |
914 | "categories\n"); | ||
915 | goto bad_high; | 934 | goto bad_high; |
916 | } | 935 | } |
917 | } else { | 936 | } else { |
@@ -922,12 +941,11 @@ static int mls_read_range_helper(struct mls_range *r, void *fp) | |||
922 | } | 941 | } |
923 | } | 942 | } |
924 | 943 | ||
925 | rc = 0; | 944 | return 0; |
926 | out: | ||
927 | return rc; | ||
928 | bad_high: | 945 | bad_high: |
929 | ebitmap_destroy(&r->level[0].cat); | 946 | ebitmap_destroy(&r->level[0].cat); |
930 | goto out; | 947 | out: |
948 | return rc; | ||
931 | } | 949 | } |
932 | 950 | ||
933 | /* | 951 | /* |
@@ -942,7 +960,7 @@ static int context_read_and_validate(struct context *c, | |||
942 | int rc; | 960 | int rc; |
943 | 961 | ||
944 | rc = next_entry(buf, fp, sizeof buf); | 962 | rc = next_entry(buf, fp, sizeof buf); |
945 | if (rc < 0) { | 963 | if (rc) { |
946 | printk(KERN_ERR "SELinux: context truncated\n"); | 964 | printk(KERN_ERR "SELinux: context truncated\n"); |
947 | goto out; | 965 | goto out; |
948 | } | 966 | } |
@@ -950,19 +968,20 @@ static int context_read_and_validate(struct context *c, | |||
950 | c->role = le32_to_cpu(buf[1]); | 968 | c->role = le32_to_cpu(buf[1]); |
951 | c->type = le32_to_cpu(buf[2]); | 969 | c->type = le32_to_cpu(buf[2]); |
952 | if (p->policyvers >= POLICYDB_VERSION_MLS) { | 970 | if (p->policyvers >= POLICYDB_VERSION_MLS) { |
953 | if (mls_read_range_helper(&c->range, fp)) { | 971 | rc = mls_read_range_helper(&c->range, fp); |
954 | printk(KERN_ERR "SELinux: error reading MLS range of " | 972 | if (rc) { |
955 | "context\n"); | 973 | printk(KERN_ERR "SELinux: error reading MLS range of context\n"); |
956 | rc = -EINVAL; | ||
957 | goto out; | 974 | goto out; |
958 | } | 975 | } |
959 | } | 976 | } |
960 | 977 | ||
978 | rc = -EINVAL; | ||
961 | if (!policydb_context_isvalid(p, c)) { | 979 | if (!policydb_context_isvalid(p, c)) { |
962 | printk(KERN_ERR "SELinux: invalid security context\n"); | 980 | printk(KERN_ERR "SELinux: invalid security context\n"); |
963 | context_destroy(c); | 981 | context_destroy(c); |
964 | rc = -EINVAL; | 982 | goto out; |
965 | } | 983 | } |
984 | rc = 0; | ||
966 | out: | 985 | out: |
967 | return rc; | 986 | return rc; |
968 | } | 987 | } |
@@ -981,37 +1000,36 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp) | |||
981 | __le32 buf[2]; | 1000 | __le32 buf[2]; |
982 | u32 len; | 1001 | u32 len; |
983 | 1002 | ||
1003 | rc = -ENOMEM; | ||
984 | perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL); | 1004 | perdatum = kzalloc(sizeof(*perdatum), GFP_KERNEL); |
985 | if (!perdatum) { | 1005 | if (!perdatum) |
986 | rc = -ENOMEM; | 1006 | goto bad; |
987 | goto out; | ||
988 | } | ||
989 | 1007 | ||
990 | rc = next_entry(buf, fp, sizeof buf); | 1008 | rc = next_entry(buf, fp, sizeof buf); |
991 | if (rc < 0) | 1009 | if (rc) |
992 | goto bad; | 1010 | goto bad; |
993 | 1011 | ||
994 | len = le32_to_cpu(buf[0]); | 1012 | len = le32_to_cpu(buf[0]); |
995 | perdatum->value = le32_to_cpu(buf[1]); | 1013 | perdatum->value = le32_to_cpu(buf[1]); |
996 | 1014 | ||
1015 | rc = -ENOMEM; | ||
997 | key = kmalloc(len + 1, GFP_KERNEL); | 1016 | key = kmalloc(len + 1, GFP_KERNEL); |
998 | if (!key) { | 1017 | if (!key) |
999 | rc = -ENOMEM; | ||
1000 | goto bad; | 1018 | goto bad; |
1001 | } | 1019 | |
1002 | rc = next_entry(key, fp, len); | 1020 | rc = next_entry(key, fp, len); |
1003 | if (rc < 0) | 1021 | if (rc) |
1004 | goto bad; | 1022 | goto bad; |
1005 | key[len] = '\0'; | 1023 | key[len] = '\0'; |
1006 | 1024 | ||
1007 | rc = hashtab_insert(h, key, perdatum); | 1025 | rc = hashtab_insert(h, key, perdatum); |
1008 | if (rc) | 1026 | if (rc) |
1009 | goto bad; | 1027 | goto bad; |
1010 | out: | 1028 | |
1011 | return rc; | 1029 | return 0; |
1012 | bad: | 1030 | bad: |
1013 | perm_destroy(key, perdatum, NULL); | 1031 | perm_destroy(key, perdatum, NULL); |
1014 | goto out; | 1032 | return rc; |
1015 | } | 1033 | } |
1016 | 1034 | ||
1017 | static int common_read(struct policydb *p, struct hashtab *h, void *fp) | 1035 | static int common_read(struct policydb *p, struct hashtab *h, void *fp) |
@@ -1022,14 +1040,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1022 | u32 len, nel; | 1040 | u32 len, nel; |
1023 | int i, rc; | 1041 | int i, rc; |
1024 | 1042 | ||
1043 | rc = -ENOMEM; | ||
1025 | comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL); | 1044 | comdatum = kzalloc(sizeof(*comdatum), GFP_KERNEL); |
1026 | if (!comdatum) { | 1045 | if (!comdatum) |
1027 | rc = -ENOMEM; | 1046 | goto bad; |
1028 | goto out; | ||
1029 | } | ||
1030 | 1047 | ||
1031 | rc = next_entry(buf, fp, sizeof buf); | 1048 | rc = next_entry(buf, fp, sizeof buf); |
1032 | if (rc < 0) | 1049 | if (rc) |
1033 | goto bad; | 1050 | goto bad; |
1034 | 1051 | ||
1035 | len = le32_to_cpu(buf[0]); | 1052 | len = le32_to_cpu(buf[0]); |
@@ -1041,13 +1058,13 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1041 | comdatum->permissions.nprim = le32_to_cpu(buf[2]); | 1058 | comdatum->permissions.nprim = le32_to_cpu(buf[2]); |
1042 | nel = le32_to_cpu(buf[3]); | 1059 | nel = le32_to_cpu(buf[3]); |
1043 | 1060 | ||
1061 | rc = -ENOMEM; | ||
1044 | key = kmalloc(len + 1, GFP_KERNEL); | 1062 | key = kmalloc(len + 1, GFP_KERNEL); |
1045 | if (!key) { | 1063 | if (!key) |
1046 | rc = -ENOMEM; | ||
1047 | goto bad; | 1064 | goto bad; |
1048 | } | 1065 | |
1049 | rc = next_entry(key, fp, len); | 1066 | rc = next_entry(key, fp, len); |
1050 | if (rc < 0) | 1067 | if (rc) |
1051 | goto bad; | 1068 | goto bad; |
1052 | key[len] = '\0'; | 1069 | key[len] = '\0'; |
1053 | 1070 | ||
@@ -1060,11 +1077,10 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1060 | rc = hashtab_insert(h, key, comdatum); | 1077 | rc = hashtab_insert(h, key, comdatum); |
1061 | if (rc) | 1078 | if (rc) |
1062 | goto bad; | 1079 | goto bad; |
1063 | out: | 1080 | return 0; |
1064 | return rc; | ||
1065 | bad: | 1081 | bad: |
1066 | common_destroy(key, comdatum, NULL); | 1082 | common_destroy(key, comdatum, NULL); |
1067 | goto out; | 1083 | return rc; |
1068 | } | 1084 | } |
1069 | 1085 | ||
1070 | static int read_cons_helper(struct constraint_node **nodep, int ncons, | 1086 | static int read_cons_helper(struct constraint_node **nodep, int ncons, |
@@ -1088,7 +1104,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, | |||
1088 | *nodep = c; | 1104 | *nodep = c; |
1089 | 1105 | ||
1090 | rc = next_entry(buf, fp, (sizeof(u32) * 2)); | 1106 | rc = next_entry(buf, fp, (sizeof(u32) * 2)); |
1091 | if (rc < 0) | 1107 | if (rc) |
1092 | return rc; | 1108 | return rc; |
1093 | c->permissions = le32_to_cpu(buf[0]); | 1109 | c->permissions = le32_to_cpu(buf[0]); |
1094 | nexpr = le32_to_cpu(buf[1]); | 1110 | nexpr = le32_to_cpu(buf[1]); |
@@ -1105,7 +1121,7 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, | |||
1105 | c->expr = e; | 1121 | c->expr = e; |
1106 | 1122 | ||
1107 | rc = next_entry(buf, fp, (sizeof(u32) * 3)); | 1123 | rc = next_entry(buf, fp, (sizeof(u32) * 3)); |
1108 | if (rc < 0) | 1124 | if (rc) |
1109 | return rc; | 1125 | return rc; |
1110 | e->expr_type = le32_to_cpu(buf[0]); | 1126 | e->expr_type = le32_to_cpu(buf[0]); |
1111 | e->attr = le32_to_cpu(buf[1]); | 1127 | e->attr = le32_to_cpu(buf[1]); |
@@ -1133,8 +1149,9 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons, | |||
1133 | if (depth == (CEXPR_MAXDEPTH - 1)) | 1149 | if (depth == (CEXPR_MAXDEPTH - 1)) |
1134 | return -EINVAL; | 1150 | return -EINVAL; |
1135 | depth++; | 1151 | depth++; |
1136 | if (ebitmap_read(&e->names, fp)) | 1152 | rc = ebitmap_read(&e->names, fp); |
1137 | return -EINVAL; | 1153 | if (rc) |
1154 | return rc; | ||
1138 | break; | 1155 | break; |
1139 | default: | 1156 | default: |
1140 | return -EINVAL; | 1157 | return -EINVAL; |
@@ -1157,14 +1174,13 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1157 | u32 len, len2, ncons, nel; | 1174 | u32 len, len2, ncons, nel; |
1158 | int i, rc; | 1175 | int i, rc; |
1159 | 1176 | ||
1177 | rc = -ENOMEM; | ||
1160 | cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL); | 1178 | cladatum = kzalloc(sizeof(*cladatum), GFP_KERNEL); |
1161 | if (!cladatum) { | 1179 | if (!cladatum) |
1162 | rc = -ENOMEM; | 1180 | goto bad; |
1163 | goto out; | ||
1164 | } | ||
1165 | 1181 | ||
1166 | rc = next_entry(buf, fp, sizeof(u32)*6); | 1182 | rc = next_entry(buf, fp, sizeof(u32)*6); |
1167 | if (rc < 0) | 1183 | if (rc) |
1168 | goto bad; | 1184 | goto bad; |
1169 | 1185 | ||
1170 | len = le32_to_cpu(buf[0]); | 1186 | len = le32_to_cpu(buf[0]); |
@@ -1179,33 +1195,30 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1179 | 1195 | ||
1180 | ncons = le32_to_cpu(buf[5]); | 1196 | ncons = le32_to_cpu(buf[5]); |
1181 | 1197 | ||
1198 | rc = -ENOMEM; | ||
1182 | key = kmalloc(len + 1, GFP_KERNEL); | 1199 | key = kmalloc(len + 1, GFP_KERNEL); |
1183 | if (!key) { | 1200 | if (!key) |
1184 | rc = -ENOMEM; | ||
1185 | goto bad; | 1201 | goto bad; |
1186 | } | 1202 | |
1187 | rc = next_entry(key, fp, len); | 1203 | rc = next_entry(key, fp, len); |
1188 | if (rc < 0) | 1204 | if (rc) |
1189 | goto bad; | 1205 | goto bad; |
1190 | key[len] = '\0'; | 1206 | key[len] = '\0'; |
1191 | 1207 | ||
1192 | if (len2) { | 1208 | if (len2) { |
1209 | rc = -ENOMEM; | ||
1193 | cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL); | 1210 | cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL); |
1194 | if (!cladatum->comkey) { | 1211 | if (!cladatum->comkey) |
1195 | rc = -ENOMEM; | ||
1196 | goto bad; | 1212 | goto bad; |
1197 | } | ||
1198 | rc = next_entry(cladatum->comkey, fp, len2); | 1213 | rc = next_entry(cladatum->comkey, fp, len2); |
1199 | if (rc < 0) | 1214 | if (rc) |
1200 | goto bad; | 1215 | goto bad; |
1201 | cladatum->comkey[len2] = '\0'; | 1216 | cladatum->comkey[len2] = '\0'; |
1202 | 1217 | ||
1203 | cladatum->comdatum = hashtab_search(p->p_commons.table, | 1218 | rc = -EINVAL; |
1204 | cladatum->comkey); | 1219 | cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey); |
1205 | if (!cladatum->comdatum) { | 1220 | if (!cladatum->comdatum) { |
1206 | printk(KERN_ERR "SELinux: unknown common %s\n", | 1221 | printk(KERN_ERR "SELinux: unknown common %s\n", cladatum->comkey); |
1207 | cladatum->comkey); | ||
1208 | rc = -EINVAL; | ||
1209 | goto bad; | 1222 | goto bad; |
1210 | } | 1223 | } |
1211 | } | 1224 | } |
@@ -1222,7 +1235,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1222 | if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) { | 1235 | if (p->policyvers >= POLICYDB_VERSION_VALIDATETRANS) { |
1223 | /* grab the validatetrans rules */ | 1236 | /* grab the validatetrans rules */ |
1224 | rc = next_entry(buf, fp, sizeof(u32)); | 1237 | rc = next_entry(buf, fp, sizeof(u32)); |
1225 | if (rc < 0) | 1238 | if (rc) |
1226 | goto bad; | 1239 | goto bad; |
1227 | ncons = le32_to_cpu(buf[0]); | 1240 | ncons = le32_to_cpu(buf[0]); |
1228 | rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); | 1241 | rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp); |
@@ -1234,12 +1247,10 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1234 | if (rc) | 1247 | if (rc) |
1235 | goto bad; | 1248 | goto bad; |
1236 | 1249 | ||
1237 | rc = 0; | 1250 | return 0; |
1238 | out: | ||
1239 | return rc; | ||
1240 | bad: | 1251 | bad: |
1241 | cls_destroy(key, cladatum, NULL); | 1252 | cls_destroy(key, cladatum, NULL); |
1242 | goto out; | 1253 | return rc; |
1243 | } | 1254 | } |
1244 | 1255 | ||
1245 | static int role_read(struct policydb *p, struct hashtab *h, void *fp) | 1256 | static int role_read(struct policydb *p, struct hashtab *h, void *fp) |
@@ -1250,17 +1261,16 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1250 | __le32 buf[3]; | 1261 | __le32 buf[3]; |
1251 | u32 len; | 1262 | u32 len; |
1252 | 1263 | ||
1264 | rc = -ENOMEM; | ||
1253 | role = kzalloc(sizeof(*role), GFP_KERNEL); | 1265 | role = kzalloc(sizeof(*role), GFP_KERNEL); |
1254 | if (!role) { | 1266 | if (!role) |
1255 | rc = -ENOMEM; | 1267 | goto bad; |
1256 | goto out; | ||
1257 | } | ||
1258 | 1268 | ||
1259 | if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) | 1269 | if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) |
1260 | to_read = 3; | 1270 | to_read = 3; |
1261 | 1271 | ||
1262 | rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); | 1272 | rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); |
1263 | if (rc < 0) | 1273 | if (rc) |
1264 | goto bad; | 1274 | goto bad; |
1265 | 1275 | ||
1266 | len = le32_to_cpu(buf[0]); | 1276 | len = le32_to_cpu(buf[0]); |
@@ -1268,13 +1278,13 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1268 | if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) | 1278 | if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) |
1269 | role->bounds = le32_to_cpu(buf[2]); | 1279 | role->bounds = le32_to_cpu(buf[2]); |
1270 | 1280 | ||
1281 | rc = -ENOMEM; | ||
1271 | key = kmalloc(len + 1, GFP_KERNEL); | 1282 | key = kmalloc(len + 1, GFP_KERNEL); |
1272 | if (!key) { | 1283 | if (!key) |
1273 | rc = -ENOMEM; | ||
1274 | goto bad; | 1284 | goto bad; |
1275 | } | 1285 | |
1276 | rc = next_entry(key, fp, len); | 1286 | rc = next_entry(key, fp, len); |
1277 | if (rc < 0) | 1287 | if (rc) |
1278 | goto bad; | 1288 | goto bad; |
1279 | key[len] = '\0'; | 1289 | key[len] = '\0'; |
1280 | 1290 | ||
@@ -1287,10 +1297,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1287 | goto bad; | 1297 | goto bad; |
1288 | 1298 | ||
1289 | if (strcmp(key, OBJECT_R) == 0) { | 1299 | if (strcmp(key, OBJECT_R) == 0) { |
1300 | rc = -EINVAL; | ||
1290 | if (role->value != OBJECT_R_VAL) { | 1301 | if (role->value != OBJECT_R_VAL) { |
1291 | printk(KERN_ERR "SELinux: Role %s has wrong value %d\n", | 1302 | printk(KERN_ERR "SELinux: Role %s has wrong value %d\n", |
1292 | OBJECT_R, role->value); | 1303 | OBJECT_R, role->value); |
1293 | rc = -EINVAL; | ||
1294 | goto bad; | 1304 | goto bad; |
1295 | } | 1305 | } |
1296 | rc = 0; | 1306 | rc = 0; |
@@ -1300,11 +1310,10 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1300 | rc = hashtab_insert(h, key, role); | 1310 | rc = hashtab_insert(h, key, role); |
1301 | if (rc) | 1311 | if (rc) |
1302 | goto bad; | 1312 | goto bad; |
1303 | out: | 1313 | return 0; |
1304 | return rc; | ||
1305 | bad: | 1314 | bad: |
1306 | role_destroy(key, role, NULL); | 1315 | role_destroy(key, role, NULL); |
1307 | goto out; | 1316 | return rc; |
1308 | } | 1317 | } |
1309 | 1318 | ||
1310 | static int type_read(struct policydb *p, struct hashtab *h, void *fp) | 1319 | static int type_read(struct policydb *p, struct hashtab *h, void *fp) |
@@ -1315,17 +1324,16 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1315 | __le32 buf[4]; | 1324 | __le32 buf[4]; |
1316 | u32 len; | 1325 | u32 len; |
1317 | 1326 | ||
1327 | rc = -ENOMEM; | ||
1318 | typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL); | 1328 | typdatum = kzalloc(sizeof(*typdatum), GFP_KERNEL); |
1319 | if (!typdatum) { | 1329 | if (!typdatum) |
1320 | rc = -ENOMEM; | 1330 | goto bad; |
1321 | return rc; | ||
1322 | } | ||
1323 | 1331 | ||
1324 | if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) | 1332 | if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) |
1325 | to_read = 4; | 1333 | to_read = 4; |
1326 | 1334 | ||
1327 | rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); | 1335 | rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); |
1328 | if (rc < 0) | 1336 | if (rc) |
1329 | goto bad; | 1337 | goto bad; |
1330 | 1338 | ||
1331 | len = le32_to_cpu(buf[0]); | 1339 | len = le32_to_cpu(buf[0]); |
@@ -1343,24 +1351,22 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1343 | typdatum->primary = le32_to_cpu(buf[2]); | 1351 | typdatum->primary = le32_to_cpu(buf[2]); |
1344 | } | 1352 | } |
1345 | 1353 | ||
1354 | rc = -ENOMEM; | ||
1346 | key = kmalloc(len + 1, GFP_KERNEL); | 1355 | key = kmalloc(len + 1, GFP_KERNEL); |
1347 | if (!key) { | 1356 | if (!key) |
1348 | rc = -ENOMEM; | ||
1349 | goto bad; | 1357 | goto bad; |
1350 | } | ||
1351 | rc = next_entry(key, fp, len); | 1358 | rc = next_entry(key, fp, len); |
1352 | if (rc < 0) | 1359 | if (rc) |
1353 | goto bad; | 1360 | goto bad; |
1354 | key[len] = '\0'; | 1361 | key[len] = '\0'; |
1355 | 1362 | ||
1356 | rc = hashtab_insert(h, key, typdatum); | 1363 | rc = hashtab_insert(h, key, typdatum); |
1357 | if (rc) | 1364 | if (rc) |
1358 | goto bad; | 1365 | goto bad; |
1359 | out: | 1366 | return 0; |
1360 | return rc; | ||
1361 | bad: | 1367 | bad: |
1362 | type_destroy(key, typdatum, NULL); | 1368 | type_destroy(key, typdatum, NULL); |
1363 | goto out; | 1369 | return rc; |
1364 | } | 1370 | } |
1365 | 1371 | ||
1366 | 1372 | ||
@@ -1376,22 +1382,18 @@ static int mls_read_level(struct mls_level *lp, void *fp) | |||
1376 | memset(lp, 0, sizeof(*lp)); | 1382 | memset(lp, 0, sizeof(*lp)); |
1377 | 1383 | ||
1378 | rc = next_entry(buf, fp, sizeof buf); | 1384 | rc = next_entry(buf, fp, sizeof buf); |
1379 | if (rc < 0) { | 1385 | if (rc) { |
1380 | printk(KERN_ERR "SELinux: mls: truncated level\n"); | 1386 | printk(KERN_ERR "SELinux: mls: truncated level\n"); |
1381 | goto bad; | 1387 | return rc; |
1382 | } | 1388 | } |
1383 | lp->sens = le32_to_cpu(buf[0]); | 1389 | lp->sens = le32_to_cpu(buf[0]); |
1384 | 1390 | ||
1385 | if (ebitmap_read(&lp->cat, fp)) { | 1391 | rc = ebitmap_read(&lp->cat, fp); |
1386 | printk(KERN_ERR "SELinux: mls: error reading level " | 1392 | if (rc) { |
1387 | "categories\n"); | 1393 | printk(KERN_ERR "SELinux: mls: error reading level categories\n"); |
1388 | goto bad; | 1394 | return rc; |
1389 | } | 1395 | } |
1390 | |||
1391 | return 0; | 1396 | return 0; |
1392 | |||
1393 | bad: | ||
1394 | return -EINVAL; | ||
1395 | } | 1397 | } |
1396 | 1398 | ||
1397 | static int user_read(struct policydb *p, struct hashtab *h, void *fp) | 1399 | static int user_read(struct policydb *p, struct hashtab *h, void *fp) |
@@ -1402,17 +1404,16 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1402 | __le32 buf[3]; | 1404 | __le32 buf[3]; |
1403 | u32 len; | 1405 | u32 len; |
1404 | 1406 | ||
1407 | rc = -ENOMEM; | ||
1405 | usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL); | 1408 | usrdatum = kzalloc(sizeof(*usrdatum), GFP_KERNEL); |
1406 | if (!usrdatum) { | 1409 | if (!usrdatum) |
1407 | rc = -ENOMEM; | 1410 | goto bad; |
1408 | goto out; | ||
1409 | } | ||
1410 | 1411 | ||
1411 | if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) | 1412 | if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) |
1412 | to_read = 3; | 1413 | to_read = 3; |
1413 | 1414 | ||
1414 | rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); | 1415 | rc = next_entry(buf, fp, sizeof(buf[0]) * to_read); |
1415 | if (rc < 0) | 1416 | if (rc) |
1416 | goto bad; | 1417 | goto bad; |
1417 | 1418 | ||
1418 | len = le32_to_cpu(buf[0]); | 1419 | len = le32_to_cpu(buf[0]); |
@@ -1420,13 +1421,12 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1420 | if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) | 1421 | if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) |
1421 | usrdatum->bounds = le32_to_cpu(buf[2]); | 1422 | usrdatum->bounds = le32_to_cpu(buf[2]); |
1422 | 1423 | ||
1424 | rc = -ENOMEM; | ||
1423 | key = kmalloc(len + 1, GFP_KERNEL); | 1425 | key = kmalloc(len + 1, GFP_KERNEL); |
1424 | if (!key) { | 1426 | if (!key) |
1425 | rc = -ENOMEM; | ||
1426 | goto bad; | 1427 | goto bad; |
1427 | } | ||
1428 | rc = next_entry(key, fp, len); | 1428 | rc = next_entry(key, fp, len); |
1429 | if (rc < 0) | 1429 | if (rc) |
1430 | goto bad; | 1430 | goto bad; |
1431 | key[len] = '\0'; | 1431 | key[len] = '\0'; |
1432 | 1432 | ||
@@ -1446,11 +1446,10 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1446 | rc = hashtab_insert(h, key, usrdatum); | 1446 | rc = hashtab_insert(h, key, usrdatum); |
1447 | if (rc) | 1447 | if (rc) |
1448 | goto bad; | 1448 | goto bad; |
1449 | out: | 1449 | return 0; |
1450 | return rc; | ||
1451 | bad: | 1450 | bad: |
1452 | user_destroy(key, usrdatum, NULL); | 1451 | user_destroy(key, usrdatum, NULL); |
1453 | goto out; | 1452 | return rc; |
1454 | } | 1453 | } |
1455 | 1454 | ||
1456 | static int sens_read(struct policydb *p, struct hashtab *h, void *fp) | 1455 | static int sens_read(struct policydb *p, struct hashtab *h, void *fp) |
@@ -1461,47 +1460,43 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1461 | __le32 buf[2]; | 1460 | __le32 buf[2]; |
1462 | u32 len; | 1461 | u32 len; |
1463 | 1462 | ||
1463 | rc = -ENOMEM; | ||
1464 | levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC); | 1464 | levdatum = kzalloc(sizeof(*levdatum), GFP_ATOMIC); |
1465 | if (!levdatum) { | 1465 | if (!levdatum) |
1466 | rc = -ENOMEM; | 1466 | goto bad; |
1467 | goto out; | ||
1468 | } | ||
1469 | 1467 | ||
1470 | rc = next_entry(buf, fp, sizeof buf); | 1468 | rc = next_entry(buf, fp, sizeof buf); |
1471 | if (rc < 0) | 1469 | if (rc) |
1472 | goto bad; | 1470 | goto bad; |
1473 | 1471 | ||
1474 | len = le32_to_cpu(buf[0]); | 1472 | len = le32_to_cpu(buf[0]); |
1475 | levdatum->isalias = le32_to_cpu(buf[1]); | 1473 | levdatum->isalias = le32_to_cpu(buf[1]); |
1476 | 1474 | ||
1475 | rc = -ENOMEM; | ||
1477 | key = kmalloc(len + 1, GFP_ATOMIC); | 1476 | key = kmalloc(len + 1, GFP_ATOMIC); |
1478 | if (!key) { | 1477 | if (!key) |
1479 | rc = -ENOMEM; | ||
1480 | goto bad; | 1478 | goto bad; |
1481 | } | ||
1482 | rc = next_entry(key, fp, len); | 1479 | rc = next_entry(key, fp, len); |
1483 | if (rc < 0) | 1480 | if (rc) |
1484 | goto bad; | 1481 | goto bad; |
1485 | key[len] = '\0'; | 1482 | key[len] = '\0'; |
1486 | 1483 | ||
1484 | rc = -ENOMEM; | ||
1487 | levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); | 1485 | levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); |
1488 | if (!levdatum->level) { | 1486 | if (!levdatum->level) |
1489 | rc = -ENOMEM; | ||
1490 | goto bad; | 1487 | goto bad; |
1491 | } | 1488 | |
1492 | if (mls_read_level(levdatum->level, fp)) { | 1489 | rc = mls_read_level(levdatum->level, fp); |
1493 | rc = -EINVAL; | 1490 | if (rc) |
1494 | goto bad; | 1491 | goto bad; |
1495 | } | ||
1496 | 1492 | ||
1497 | rc = hashtab_insert(h, key, levdatum); | 1493 | rc = hashtab_insert(h, key, levdatum); |
1498 | if (rc) | 1494 | if (rc) |
1499 | goto bad; | 1495 | goto bad; |
1500 | out: | 1496 | return 0; |
1501 | return rc; | ||
1502 | bad: | 1497 | bad: |
1503 | sens_destroy(key, levdatum, NULL); | 1498 | sens_destroy(key, levdatum, NULL); |
1504 | goto out; | 1499 | return rc; |
1505 | } | 1500 | } |
1506 | 1501 | ||
1507 | static int cat_read(struct policydb *p, struct hashtab *h, void *fp) | 1502 | static int cat_read(struct policydb *p, struct hashtab *h, void *fp) |
@@ -1512,39 +1507,35 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp) | |||
1512 | __le32 buf[3]; | 1507 | __le32 buf[3]; |
1513 | u32 len; | 1508 | u32 len; |
1514 | 1509 | ||
1510 | rc = -ENOMEM; | ||
1515 | catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC); | 1511 | catdatum = kzalloc(sizeof(*catdatum), GFP_ATOMIC); |
1516 | if (!catdatum) { | 1512 | if (!catdatum) |
1517 | rc = -ENOMEM; | 1513 | goto bad; |
1518 | goto out; | ||
1519 | } | ||
1520 | 1514 | ||
1521 | rc = next_entry(buf, fp, sizeof buf); | 1515 | rc = next_entry(buf, fp, sizeof buf); |
1522 | if (rc < 0) | 1516 | if (rc) |
1523 | goto bad; | 1517 | goto bad; |
1524 | 1518 | ||
1525 | len = le32_to_cpu(buf[0]); | 1519 | len = le32_to_cpu(buf[0]); |
1526 | catdatum->value = le32_to_cpu(buf[1]); | 1520 | catdatum->value = le32_to_cpu(buf[1]); |
1527 | catdatum->isalias = le32_to_cpu(buf[2]); | 1521 | catdatum->isalias = le32_to_cpu(buf[2]); |
1528 | 1522 | ||
1523 | rc = -ENOMEM; | ||
1529 | key = kmalloc(len + 1, GFP_ATOMIC); | 1524 | key = kmalloc(len + 1, GFP_ATOMIC); |
1530 | if (!key) { | 1525 | if (!key) |
1531 | rc = -ENOMEM; | ||
1532 | goto bad; | 1526 | goto bad; |
1533 | } | ||
1534 | rc = next_entry(key, fp, len); | 1527 | rc = next_entry(key, fp, len); |
1535 | if (rc < 0) | 1528 | if (rc) |
1536 | goto bad; | 1529 | goto bad; |
1537 | key[len] = '\0'; | 1530 | key[len] = '\0'; |
1538 | 1531 | ||
1539 | rc = hashtab_insert(h, key, catdatum); | 1532 | rc = hashtab_insert(h, key, catdatum); |
1540 | if (rc) | 1533 | if (rc) |
1541 | goto bad; | 1534 | goto bad; |
1542 | out: | 1535 | return 0; |
1543 | return rc; | ||
1544 | |||
1545 | bad: | 1536 | bad: |
1546 | cat_destroy(key, catdatum, NULL); | 1537 | cat_destroy(key, catdatum, NULL); |
1547 | goto out; | 1538 | return rc; |
1548 | } | 1539 | } |
1549 | 1540 | ||
1550 | static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) = | 1541 | static int (*read_f[SYM_NUM]) (struct policydb *p, struct hashtab *h, void *fp) = |
@@ -1585,9 +1576,9 @@ static int user_bounds_sanity_check(void *key, void *datum, void *datap) | |||
1585 | printk(KERN_ERR | 1576 | printk(KERN_ERR |
1586 | "SELinux: boundary violated policy: " | 1577 | "SELinux: boundary violated policy: " |
1587 | "user=%s role=%s bounds=%s\n", | 1578 | "user=%s role=%s bounds=%s\n", |
1588 | p->p_user_val_to_name[user->value - 1], | 1579 | sym_name(p, SYM_USERS, user->value - 1), |
1589 | p->p_role_val_to_name[bit], | 1580 | sym_name(p, SYM_ROLES, bit), |
1590 | p->p_user_val_to_name[upper->value - 1]); | 1581 | sym_name(p, SYM_USERS, upper->value - 1)); |
1591 | 1582 | ||
1592 | return -EINVAL; | 1583 | return -EINVAL; |
1593 | } | 1584 | } |
@@ -1622,9 +1613,9 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap) | |||
1622 | printk(KERN_ERR | 1613 | printk(KERN_ERR |
1623 | "SELinux: boundary violated policy: " | 1614 | "SELinux: boundary violated policy: " |
1624 | "role=%s type=%s bounds=%s\n", | 1615 | "role=%s type=%s bounds=%s\n", |
1625 | p->p_role_val_to_name[role->value - 1], | 1616 | sym_name(p, SYM_ROLES, role->value - 1), |
1626 | p->p_type_val_to_name[bit], | 1617 | sym_name(p, SYM_TYPES, bit), |
1627 | p->p_role_val_to_name[upper->value - 1]); | 1618 | sym_name(p, SYM_ROLES, upper->value - 1)); |
1628 | 1619 | ||
1629 | return -EINVAL; | 1620 | return -EINVAL; |
1630 | } | 1621 | } |
@@ -1648,12 +1639,15 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap) | |||
1648 | return -EINVAL; | 1639 | return -EINVAL; |
1649 | } | 1640 | } |
1650 | 1641 | ||
1651 | upper = p->type_val_to_struct[upper->bounds - 1]; | 1642 | upper = flex_array_get_ptr(p->type_val_to_struct_array, |
1643 | upper->bounds - 1); | ||
1644 | BUG_ON(!upper); | ||
1645 | |||
1652 | if (upper->attribute) { | 1646 | if (upper->attribute) { |
1653 | printk(KERN_ERR "SELinux: type %s: " | 1647 | printk(KERN_ERR "SELinux: type %s: " |
1654 | "bounded by attribute %s", | 1648 | "bounded by attribute %s", |
1655 | (char *) key, | 1649 | (char *) key, |
1656 | p->p_type_val_to_name[upper->value - 1]); | 1650 | sym_name(p, SYM_TYPES, upper->value - 1)); |
1657 | return -EINVAL; | 1651 | return -EINVAL; |
1658 | } | 1652 | } |
1659 | } | 1653 | } |
@@ -2066,13 +2060,14 @@ int policydb_read(struct policydb *p, void *fp) | |||
2066 | 2060 | ||
2067 | rc = policydb_init(p); | 2061 | rc = policydb_init(p); |
2068 | if (rc) | 2062 | if (rc) |
2069 | goto out; | 2063 | return rc; |
2070 | 2064 | ||
2071 | /* Read the magic number and string length. */ | 2065 | /* Read the magic number and string length. */ |
2072 | rc = next_entry(buf, fp, sizeof(u32) * 2); | 2066 | rc = next_entry(buf, fp, sizeof(u32) * 2); |
2073 | if (rc < 0) | 2067 | if (rc) |
2074 | goto bad; | 2068 | goto bad; |
2075 | 2069 | ||
2070 | rc = -EINVAL; | ||
2076 | if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { | 2071 | if (le32_to_cpu(buf[0]) != POLICYDB_MAGIC) { |
2077 | printk(KERN_ERR "SELinux: policydb magic number 0x%x does " | 2072 | printk(KERN_ERR "SELinux: policydb magic number 0x%x does " |
2078 | "not match expected magic number 0x%x\n", | 2073 | "not match expected magic number 0x%x\n", |
@@ -2080,6 +2075,7 @@ int policydb_read(struct policydb *p, void *fp) | |||
2080 | goto bad; | 2075 | goto bad; |
2081 | } | 2076 | } |
2082 | 2077 | ||
2078 | rc = -EINVAL; | ||
2083 | len = le32_to_cpu(buf[1]); | 2079 | len = le32_to_cpu(buf[1]); |
2084 | if (len != strlen(POLICYDB_STRING)) { | 2080 | if (len != strlen(POLICYDB_STRING)) { |
2085 | printk(KERN_ERR "SELinux: policydb string length %d does not " | 2081 | printk(KERN_ERR "SELinux: policydb string length %d does not " |
@@ -2087,19 +2083,23 @@ int policydb_read(struct policydb *p, void *fp) | |||
2087 | len, strlen(POLICYDB_STRING)); | 2083 | len, strlen(POLICYDB_STRING)); |
2088 | goto bad; | 2084 | goto bad; |
2089 | } | 2085 | } |
2086 | |||
2087 | rc = -ENOMEM; | ||
2090 | policydb_str = kmalloc(len + 1, GFP_KERNEL); | 2088 | policydb_str = kmalloc(len + 1, GFP_KERNEL); |
2091 | if (!policydb_str) { | 2089 | if (!policydb_str) { |
2092 | printk(KERN_ERR "SELinux: unable to allocate memory for policydb " | 2090 | printk(KERN_ERR "SELinux: unable to allocate memory for policydb " |
2093 | "string of length %d\n", len); | 2091 | "string of length %d\n", len); |
2094 | rc = -ENOMEM; | ||
2095 | goto bad; | 2092 | goto bad; |
2096 | } | 2093 | } |
2094 | |||
2097 | rc = next_entry(policydb_str, fp, len); | 2095 | rc = next_entry(policydb_str, fp, len); |
2098 | if (rc < 0) { | 2096 | if (rc) { |
2099 | printk(KERN_ERR "SELinux: truncated policydb string identifier\n"); | 2097 | printk(KERN_ERR "SELinux: truncated policydb string identifier\n"); |
2100 | kfree(policydb_str); | 2098 | kfree(policydb_str); |
2101 | goto bad; | 2099 | goto bad; |
2102 | } | 2100 | } |
2101 | |||
2102 | rc = -EINVAL; | ||
2103 | policydb_str[len] = '\0'; | 2103 | policydb_str[len] = '\0'; |
2104 | if (strcmp(policydb_str, POLICYDB_STRING)) { | 2104 | if (strcmp(policydb_str, POLICYDB_STRING)) { |
2105 | printk(KERN_ERR "SELinux: policydb string %s does not match " | 2105 | printk(KERN_ERR "SELinux: policydb string %s does not match " |
@@ -2113,9 +2113,10 @@ int policydb_read(struct policydb *p, void *fp) | |||
2113 | 2113 | ||
2114 | /* Read the version and table sizes. */ | 2114 | /* Read the version and table sizes. */ |
2115 | rc = next_entry(buf, fp, sizeof(u32)*4); | 2115 | rc = next_entry(buf, fp, sizeof(u32)*4); |
2116 | if (rc < 0) | 2116 | if (rc) |
2117 | goto bad; | 2117 | goto bad; |
2118 | 2118 | ||
2119 | rc = -EINVAL; | ||
2119 | p->policyvers = le32_to_cpu(buf[0]); | 2120 | p->policyvers = le32_to_cpu(buf[0]); |
2120 | if (p->policyvers < POLICYDB_VERSION_MIN || | 2121 | if (p->policyvers < POLICYDB_VERSION_MIN || |
2121 | p->policyvers > POLICYDB_VERSION_MAX) { | 2122 | p->policyvers > POLICYDB_VERSION_MAX) { |
@@ -2128,6 +2129,7 @@ int policydb_read(struct policydb *p, void *fp) | |||
2128 | if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { | 2129 | if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) { |
2129 | p->mls_enabled = 1; | 2130 | p->mls_enabled = 1; |
2130 | 2131 | ||
2132 | rc = -EINVAL; | ||
2131 | if (p->policyvers < POLICYDB_VERSION_MLS) { | 2133 | if (p->policyvers < POLICYDB_VERSION_MLS) { |
2132 | printk(KERN_ERR "SELinux: security policydb version %d " | 2134 | printk(KERN_ERR "SELinux: security policydb version %d " |
2133 | "(MLS) not backwards compatible\n", | 2135 | "(MLS) not backwards compatible\n", |
@@ -2138,14 +2140,19 @@ int policydb_read(struct policydb *p, void *fp) | |||
2138 | p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); | 2140 | p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); |
2139 | p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); | 2141 | p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); |
2140 | 2142 | ||
2141 | if (p->policyvers >= POLICYDB_VERSION_POLCAP && | 2143 | if (p->policyvers >= POLICYDB_VERSION_POLCAP) { |
2142 | ebitmap_read(&p->policycaps, fp) != 0) | 2144 | rc = ebitmap_read(&p->policycaps, fp); |
2143 | goto bad; | 2145 | if (rc) |
2146 | goto bad; | ||
2147 | } | ||
2144 | 2148 | ||
2145 | if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE && | 2149 | if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE) { |
2146 | ebitmap_read(&p->permissive_map, fp) != 0) | 2150 | rc = ebitmap_read(&p->permissive_map, fp); |
2147 | goto bad; | 2151 | if (rc) |
2152 | goto bad; | ||
2153 | } | ||
2148 | 2154 | ||
2155 | rc = -EINVAL; | ||
2149 | info = policydb_lookup_compat(p->policyvers); | 2156 | info = policydb_lookup_compat(p->policyvers); |
2150 | if (!info) { | 2157 | if (!info) { |
2151 | printk(KERN_ERR "SELinux: unable to find policy compat info " | 2158 | printk(KERN_ERR "SELinux: unable to find policy compat info " |
@@ -2153,6 +2160,7 @@ int policydb_read(struct policydb *p, void *fp) | |||
2153 | goto bad; | 2160 | goto bad; |
2154 | } | 2161 | } |
2155 | 2162 | ||
2163 | rc = -EINVAL; | ||
2156 | if (le32_to_cpu(buf[2]) != info->sym_num || | 2164 | if (le32_to_cpu(buf[2]) != info->sym_num || |
2157 | le32_to_cpu(buf[3]) != info->ocon_num) { | 2165 | le32_to_cpu(buf[3]) != info->ocon_num) { |
2158 | printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do " | 2166 | printk(KERN_ERR "SELinux: policydb table sizes (%d,%d) do " |
@@ -2164,7 +2172,7 @@ int policydb_read(struct policydb *p, void *fp) | |||
2164 | 2172 | ||
2165 | for (i = 0; i < info->sym_num; i++) { | 2173 | for (i = 0; i < info->sym_num; i++) { |
2166 | rc = next_entry(buf, fp, sizeof(u32)*2); | 2174 | rc = next_entry(buf, fp, sizeof(u32)*2); |
2167 | if (rc < 0) | 2175 | if (rc) |
2168 | goto bad; | 2176 | goto bad; |
2169 | nprim = le32_to_cpu(buf[0]); | 2177 | nprim = le32_to_cpu(buf[0]); |
2170 | nel = le32_to_cpu(buf[1]); | 2178 | nel = le32_to_cpu(buf[1]); |
@@ -2188,78 +2196,73 @@ int policydb_read(struct policydb *p, void *fp) | |||
2188 | } | 2196 | } |
2189 | 2197 | ||
2190 | rc = next_entry(buf, fp, sizeof(u32)); | 2198 | rc = next_entry(buf, fp, sizeof(u32)); |
2191 | if (rc < 0) | 2199 | if (rc) |
2192 | goto bad; | 2200 | goto bad; |
2193 | nel = le32_to_cpu(buf[0]); | 2201 | nel = le32_to_cpu(buf[0]); |
2194 | ltr = NULL; | 2202 | ltr = NULL; |
2195 | for (i = 0; i < nel; i++) { | 2203 | for (i = 0; i < nel; i++) { |
2204 | rc = -ENOMEM; | ||
2196 | tr = kzalloc(sizeof(*tr), GFP_KERNEL); | 2205 | tr = kzalloc(sizeof(*tr), GFP_KERNEL); |
2197 | if (!tr) { | 2206 | if (!tr) |
2198 | rc = -ENOMEM; | ||
2199 | goto bad; | 2207 | goto bad; |
2200 | } | ||
2201 | if (ltr) | 2208 | if (ltr) |
2202 | ltr->next = tr; | 2209 | ltr->next = tr; |
2203 | else | 2210 | else |
2204 | p->role_tr = tr; | 2211 | p->role_tr = tr; |
2205 | rc = next_entry(buf, fp, sizeof(u32)*3); | 2212 | rc = next_entry(buf, fp, sizeof(u32)*3); |
2206 | if (rc < 0) | 2213 | if (rc) |
2207 | goto bad; | 2214 | goto bad; |
2215 | |||
2216 | rc = -EINVAL; | ||
2208 | tr->role = le32_to_cpu(buf[0]); | 2217 | tr->role = le32_to_cpu(buf[0]); |
2209 | tr->type = le32_to_cpu(buf[1]); | 2218 | tr->type = le32_to_cpu(buf[1]); |
2210 | tr->new_role = le32_to_cpu(buf[2]); | 2219 | tr->new_role = le32_to_cpu(buf[2]); |
2211 | if (!policydb_role_isvalid(p, tr->role) || | 2220 | if (!policydb_role_isvalid(p, tr->role) || |
2212 | !policydb_type_isvalid(p, tr->type) || | 2221 | !policydb_type_isvalid(p, tr->type) || |
2213 | !policydb_role_isvalid(p, tr->new_role)) { | 2222 | !policydb_role_isvalid(p, tr->new_role)) |
2214 | rc = -EINVAL; | ||
2215 | goto bad; | 2223 | goto bad; |
2216 | } | ||
2217 | ltr = tr; | 2224 | ltr = tr; |
2218 | } | 2225 | } |
2219 | 2226 | ||
2220 | rc = next_entry(buf, fp, sizeof(u32)); | 2227 | rc = next_entry(buf, fp, sizeof(u32)); |
2221 | if (rc < 0) | 2228 | if (rc) |
2222 | goto bad; | 2229 | goto bad; |
2223 | nel = le32_to_cpu(buf[0]); | 2230 | nel = le32_to_cpu(buf[0]); |
2224 | lra = NULL; | 2231 | lra = NULL; |
2225 | for (i = 0; i < nel; i++) { | 2232 | for (i = 0; i < nel; i++) { |
2233 | rc = -ENOMEM; | ||
2226 | ra = kzalloc(sizeof(*ra), GFP_KERNEL); | 2234 | ra = kzalloc(sizeof(*ra), GFP_KERNEL); |
2227 | if (!ra) { | 2235 | if (!ra) |
2228 | rc = -ENOMEM; | ||
2229 | goto bad; | 2236 | goto bad; |
2230 | } | ||
2231 | if (lra) | 2237 | if (lra) |
2232 | lra->next = ra; | 2238 | lra->next = ra; |
2233 | else | 2239 | else |
2234 | p->role_allow = ra; | 2240 | p->role_allow = ra; |
2235 | rc = next_entry(buf, fp, sizeof(u32)*2); | 2241 | rc = next_entry(buf, fp, sizeof(u32)*2); |
2236 | if (rc < 0) | 2242 | if (rc) |
2237 | goto bad; | 2243 | goto bad; |
2244 | |||
2245 | rc = -EINVAL; | ||
2238 | ra->role = le32_to_cpu(buf[0]); | 2246 | ra->role = le32_to_cpu(buf[0]); |
2239 | ra->new_role = le32_to_cpu(buf[1]); | 2247 | ra->new_role = le32_to_cpu(buf[1]); |
2240 | if (!policydb_role_isvalid(p, ra->role) || | 2248 | if (!policydb_role_isvalid(p, ra->role) || |
2241 | !policydb_role_isvalid(p, ra->new_role)) { | 2249 | !policydb_role_isvalid(p, ra->new_role)) |
2242 | rc = -EINVAL; | ||
2243 | goto bad; | 2250 | goto bad; |
2244 | } | ||
2245 | lra = ra; | 2251 | lra = ra; |
2246 | } | 2252 | } |
2247 | 2253 | ||
2248 | rc = policydb_index_classes(p); | 2254 | rc = policydb_index(p); |
2249 | if (rc) | ||
2250 | goto bad; | ||
2251 | |||
2252 | rc = policydb_index_others(p); | ||
2253 | if (rc) | 2255 | if (rc) |
2254 | goto bad; | 2256 | goto bad; |
2255 | 2257 | ||
2258 | rc = -EINVAL; | ||
2256 | p->process_class = string_to_security_class(p, "process"); | 2259 | p->process_class = string_to_security_class(p, "process"); |
2257 | if (!p->process_class) | 2260 | if (!p->process_class) |
2258 | goto bad; | 2261 | goto bad; |
2259 | p->process_trans_perms = string_to_av_perm(p, p->process_class, | 2262 | |
2260 | "transition"); | 2263 | rc = -EINVAL; |
2261 | p->process_trans_perms |= string_to_av_perm(p, p->process_class, | 2264 | p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition"); |
2262 | "dyntransition"); | 2265 | p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition"); |
2263 | if (!p->process_trans_perms) | 2266 | if (!p->process_trans_perms) |
2264 | goto bad; | 2267 | goto bad; |
2265 | 2268 | ||
@@ -2312,8 +2315,6 @@ int policydb_read(struct policydb *p, void *fp) | |||
2312 | out: | 2315 | out: |
2313 | return rc; | 2316 | return rc; |
2314 | bad: | 2317 | bad: |
2315 | if (!rc) | ||
2316 | rc = -EINVAL; | ||
2317 | policydb_destroy(p); | 2318 | policydb_destroy(p); |
2318 | goto out; | 2319 | goto out; |
2319 | } | 2320 | } |
@@ -3076,7 +3077,7 @@ int policydb_write(struct policydb *p, void *fp) | |||
3076 | if (!info) { | 3077 | if (!info) { |
3077 | printk(KERN_ERR "SELinux: compatibility lookup failed for policy " | 3078 | printk(KERN_ERR "SELinux: compatibility lookup failed for policy " |
3078 | "version %d", p->policyvers); | 3079 | "version %d", p->policyvers); |
3079 | return rc; | 3080 | return -EINVAL; |
3080 | } | 3081 | } |
3081 | 3082 | ||
3082 | buf[0] = cpu_to_le32(p->policyvers); | 3083 | buf[0] = cpu_to_le32(p->policyvers); |