diff options
Diffstat (limited to 'security/selinux/ss/policydb.c')
-rw-r--r-- | security/selinux/ss/policydb.c | 109 |
1 files changed, 82 insertions, 27 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index af41fdfe1a7..5adca670e5a 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -254,12 +254,17 @@ static int common_index(void *key, void *datum, void *datap) | |||
254 | { | 254 | { |
255 | struct policydb *p; | 255 | struct policydb *p; |
256 | struct common_datum *comdatum; | 256 | struct common_datum *comdatum; |
257 | struct flex_array *fa; | ||
257 | 258 | ||
258 | comdatum = datum; | 259 | comdatum = datum; |
259 | p = datap; | 260 | p = datap; |
260 | if (!comdatum->value || comdatum->value > p->p_commons.nprim) | 261 | if (!comdatum->value || comdatum->value > p->p_commons.nprim) |
261 | return -EINVAL; | 262 | return -EINVAL; |
262 | 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(); | ||
263 | return 0; | 268 | return 0; |
264 | } | 269 | } |
265 | 270 | ||
@@ -267,12 +272,16 @@ static int class_index(void *key, void *datum, void *datap) | |||
267 | { | 272 | { |
268 | struct policydb *p; | 273 | struct policydb *p; |
269 | struct class_datum *cladatum; | 274 | struct class_datum *cladatum; |
275 | struct flex_array *fa; | ||
270 | 276 | ||
271 | cladatum = datum; | 277 | cladatum = datum; |
272 | p = datap; | 278 | p = datap; |
273 | if (!cladatum->value || cladatum->value > p->p_classes.nprim) | 279 | if (!cladatum->value || cladatum->value > p->p_classes.nprim) |
274 | return -EINVAL; | 280 | return -EINVAL; |
275 | 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(); | ||
276 | p->class_val_to_struct[cladatum->value - 1] = cladatum; | 285 | p->class_val_to_struct[cladatum->value - 1] = cladatum; |
277 | return 0; | 286 | return 0; |
278 | } | 287 | } |
@@ -281,6 +290,7 @@ static int role_index(void *key, void *datum, void *datap) | |||
281 | { | 290 | { |
282 | struct policydb *p; | 291 | struct policydb *p; |
283 | struct role_datum *role; | 292 | struct role_datum *role; |
293 | struct flex_array *fa; | ||
284 | 294 | ||
285 | role = datum; | 295 | role = datum; |
286 | p = datap; | 296 | p = datap; |
@@ -288,7 +298,11 @@ static int role_index(void *key, void *datum, void *datap) | |||
288 | || role->value > p->p_roles.nprim | 298 | || role->value > p->p_roles.nprim |
289 | || role->bounds > p->p_roles.nprim) | 299 | || role->bounds > p->p_roles.nprim) |
290 | return -EINVAL; | 300 | return -EINVAL; |
291 | 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(); | ||
292 | p->role_val_to_struct[role->value - 1] = role; | 306 | p->role_val_to_struct[role->value - 1] = role; |
293 | return 0; | 307 | return 0; |
294 | } | 308 | } |
@@ -297,6 +311,7 @@ static int type_index(void *key, void *datum, void *datap) | |||
297 | { | 311 | { |
298 | struct policydb *p; | 312 | struct policydb *p; |
299 | struct type_datum *typdatum; | 313 | struct type_datum *typdatum; |
314 | struct flex_array *fa; | ||
300 | 315 | ||
301 | typdatum = datum; | 316 | typdatum = datum; |
302 | p = datap; | 317 | p = datap; |
@@ -306,10 +321,13 @@ static int type_index(void *key, void *datum, void *datap) | |||
306 | || typdatum->value > p->p_types.nprim | 321 | || typdatum->value > p->p_types.nprim |
307 | || typdatum->bounds > p->p_types.nprim) | 322 | || typdatum->bounds > p->p_types.nprim) |
308 | return -EINVAL; | 323 | return -EINVAL; |
309 | p->p_type_val_to_name[typdatum->value - 1] = key; | 324 | fa = p->sym_val_to_name[SYM_TYPES]; |
310 | /* this flex array was all preallocated, this cannot fail */ | 325 | if (flex_array_put_ptr(fa, typdatum->value - 1, key, |
311 | if (flex_array_put_ptr(p->type_val_to_struct_array, | 326 | GFP_KERNEL | __GFP_ZERO)) |
312 | typdatum->value - 1, typdatum, | 327 | BUG(); |
328 | |||
329 | fa = p->type_val_to_struct_array; | ||
330 | if (flex_array_put_ptr(fa, typdatum->value - 1, typdatum, | ||
313 | GFP_KERNEL | __GFP_ZERO)) | 331 | GFP_KERNEL | __GFP_ZERO)) |
314 | BUG(); | 332 | BUG(); |
315 | } | 333 | } |
@@ -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; |
@@ -392,9 +423,16 @@ static int policydb_index_classes(struct policydb *p) | |||
392 | int rc; | 423 | int rc; |
393 | 424 | ||
394 | rc = -ENOMEM; | 425 | rc = -ENOMEM; |
395 | p->p_common_val_to_name = | 426 | p->sym_val_to_name[SYM_COMMONS] = flex_array_alloc(sizeof(char *), |
396 | kmalloc(p->p_commons.nprim * sizeof(char *), GFP_KERNEL); | 427 | p->p_commons.nprim, |
397 | if (!p->p_common_val_to_name) | 428 | GFP_KERNEL | __GFP_ZERO); |
429 | if (!p->sym_val_to_name[SYM_COMMONS]) | ||
430 | goto out; | ||
431 | |||
432 | rc = flex_array_prealloc(p->sym_val_to_name[SYM_COMMONS], | ||
433 | 0, p->p_commons.nprim - 1, | ||
434 | GFP_KERNEL | __GFP_ZERO); | ||
435 | if (rc) | ||
398 | goto out; | 436 | goto out; |
399 | 437 | ||
400 | rc = hashtab_map(p->p_commons.table, common_index, p); | 438 | rc = hashtab_map(p->p_commons.table, common_index, p); |
@@ -408,9 +446,16 @@ static int policydb_index_classes(struct policydb *p) | |||
408 | goto out; | 446 | goto out; |
409 | 447 | ||
410 | rc = -ENOMEM; | 448 | rc = -ENOMEM; |
411 | p->p_class_val_to_name = | 449 | p->sym_val_to_name[SYM_CLASSES] = flex_array_alloc(sizeof(char *), |
412 | kmalloc(p->p_classes.nprim * sizeof(char *), GFP_KERNEL); | 450 | p->p_classes.nprim, |
413 | if (!p->p_class_val_to_name) | 451 | GFP_KERNEL | __GFP_ZERO); |
452 | if (!p->sym_val_to_name[SYM_CLASSES]) | ||
453 | goto out; | ||
454 | |||
455 | rc = flex_array_prealloc(p->sym_val_to_name[SYM_CLASSES], | ||
456 | 0, p->p_classes.nprim - 1, | ||
457 | GFP_KERNEL | __GFP_ZERO); | ||
458 | if (rc) | ||
414 | goto out; | 459 | goto out; |
415 | 460 | ||
416 | rc = hashtab_map(p->p_classes.table, class_index, p); | 461 | rc = hashtab_map(p->p_classes.table, class_index, p); |
@@ -507,10 +552,18 @@ static int policydb_index_others(struct policydb *p) | |||
507 | 552 | ||
508 | for (i = SYM_ROLES; i < SYM_NUM; i++) { | 553 | for (i = SYM_ROLES; i < SYM_NUM; i++) { |
509 | rc = -ENOMEM; | 554 | rc = -ENOMEM; |
510 | p->sym_val_to_name[i] = | 555 | p->sym_val_to_name[i] = flex_array_alloc(sizeof(char *), |
511 | kmalloc(p->symtab[i].nprim * sizeof(char *), GFP_KERNEL); | 556 | p->symtab[i].nprim, |
557 | GFP_KERNEL | __GFP_ZERO); | ||
512 | if (!p->sym_val_to_name[i]) | 558 | if (!p->sym_val_to_name[i]) |
513 | goto out; | 559 | goto out; |
560 | |||
561 | rc = flex_array_prealloc(p->sym_val_to_name[i], | ||
562 | 0, p->symtab[i].nprim - 1, | ||
563 | GFP_KERNEL | __GFP_ZERO); | ||
564 | if (rc) | ||
565 | goto out; | ||
566 | |||
514 | rc = hashtab_map(p->symtab[i].table, index_f[i], p); | 567 | rc = hashtab_map(p->symtab[i].table, index_f[i], p); |
515 | if (rc) | 568 | if (rc) |
516 | goto out; | 569 | goto out; |
@@ -703,8 +756,10 @@ void policydb_destroy(struct policydb *p) | |||
703 | hashtab_destroy(p->symtab[i].table); | 756 | hashtab_destroy(p->symtab[i].table); |
704 | } | 757 | } |
705 | 758 | ||
706 | for (i = 0; i < SYM_NUM; i++) | 759 | for (i = 0; i < SYM_NUM; i++) { |
707 | kfree(p->sym_val_to_name[i]); | 760 | if (p->sym_val_to_name[i]) |
761 | flex_array_free(p->sym_val_to_name[i]); | ||
762 | } | ||
708 | 763 | ||
709 | kfree(p->class_val_to_struct); | 764 | kfree(p->class_val_to_struct); |
710 | kfree(p->role_val_to_struct); | 765 | kfree(p->role_val_to_struct); |
@@ -1566,9 +1621,9 @@ static int user_bounds_sanity_check(void *key, void *datum, void *datap) | |||
1566 | printk(KERN_ERR | 1621 | printk(KERN_ERR |
1567 | "SELinux: boundary violated policy: " | 1622 | "SELinux: boundary violated policy: " |
1568 | "user=%s role=%s bounds=%s\n", | 1623 | "user=%s role=%s bounds=%s\n", |
1569 | p->p_user_val_to_name[user->value - 1], | 1624 | sym_name(p, SYM_USERS, user->value - 1), |
1570 | p->p_role_val_to_name[bit], | 1625 | sym_name(p, SYM_ROLES, bit), |
1571 | p->p_user_val_to_name[upper->value - 1]); | 1626 | sym_name(p, SYM_USERS, upper->value - 1)); |
1572 | 1627 | ||
1573 | return -EINVAL; | 1628 | return -EINVAL; |
1574 | } | 1629 | } |
@@ -1603,9 +1658,9 @@ static int role_bounds_sanity_check(void *key, void *datum, void *datap) | |||
1603 | printk(KERN_ERR | 1658 | printk(KERN_ERR |
1604 | "SELinux: boundary violated policy: " | 1659 | "SELinux: boundary violated policy: " |
1605 | "role=%s type=%s bounds=%s\n", | 1660 | "role=%s type=%s bounds=%s\n", |
1606 | p->p_role_val_to_name[role->value - 1], | 1661 | sym_name(p, SYM_ROLES, role->value - 1), |
1607 | p->p_type_val_to_name[bit], | 1662 | sym_name(p, SYM_TYPES, bit), |
1608 | p->p_role_val_to_name[upper->value - 1]); | 1663 | sym_name(p, SYM_ROLES, upper->value - 1)); |
1609 | 1664 | ||
1610 | return -EINVAL; | 1665 | return -EINVAL; |
1611 | } | 1666 | } |
@@ -1637,7 +1692,7 @@ static int type_bounds_sanity_check(void *key, void *datum, void *datap) | |||
1637 | printk(KERN_ERR "SELinux: type %s: " | 1692 | printk(KERN_ERR "SELinux: type %s: " |
1638 | "bounded by attribute %s", | 1693 | "bounded by attribute %s", |
1639 | (char *) key, | 1694 | (char *) key, |
1640 | p->p_type_val_to_name[upper->value - 1]); | 1695 | sym_name(p, SYM_TYPES, upper->value - 1)); |
1641 | return -EINVAL; | 1696 | return -EINVAL; |
1642 | } | 1697 | } |
1643 | } | 1698 | } |