diff options
Diffstat (limited to 'security/selinux/ss/conditional.c')
-rw-r--r-- | security/selinux/ss/conditional.c | 131 |
1 files changed, 129 insertions, 2 deletions
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c index c91e150c3087..a53373207fb4 100644 --- a/security/selinux/ss/conditional.c +++ b/security/selinux/ss/conditional.c | |||
@@ -178,7 +178,7 @@ int cond_init_bool_indexes(struct policydb *p) | |||
178 | p->bool_val_to_struct = (struct cond_bool_datum **) | 178 | p->bool_val_to_struct = (struct cond_bool_datum **) |
179 | kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum *), GFP_KERNEL); | 179 | kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum *), GFP_KERNEL); |
180 | if (!p->bool_val_to_struct) | 180 | if (!p->bool_val_to_struct) |
181 | return -1; | 181 | return -ENOMEM; |
182 | return 0; | 182 | return 0; |
183 | } | 183 | } |
184 | 184 | ||
@@ -193,6 +193,7 @@ int cond_index_bool(void *key, void *datum, void *datap) | |||
193 | { | 193 | { |
194 | struct policydb *p; | 194 | struct policydb *p; |
195 | struct cond_bool_datum *booldatum; | 195 | struct cond_bool_datum *booldatum; |
196 | struct flex_array *fa; | ||
196 | 197 | ||
197 | booldatum = datum; | 198 | booldatum = datum; |
198 | p = datap; | 199 | p = datap; |
@@ -200,7 +201,10 @@ int cond_index_bool(void *key, void *datum, void *datap) | |||
200 | if (!booldatum->value || booldatum->value > p->p_bools.nprim) | 201 | if (!booldatum->value || booldatum->value > p->p_bools.nprim) |
201 | return -EINVAL; | 202 | return -EINVAL; |
202 | 203 | ||
203 | p->p_bool_val_to_name[booldatum->value - 1] = key; | 204 | fa = p->sym_val_to_name[SYM_BOOLS]; |
205 | if (flex_array_put_ptr(fa, booldatum->value - 1, key, | ||
206 | GFP_KERNEL | __GFP_ZERO)) | ||
207 | BUG(); | ||
204 | p->bool_val_to_struct[booldatum->value - 1] = booldatum; | 208 | p->bool_val_to_struct[booldatum->value - 1] = booldatum; |
205 | 209 | ||
206 | return 0; | 210 | return 0; |
@@ -490,6 +494,129 @@ err: | |||
490 | return rc; | 494 | return rc; |
491 | } | 495 | } |
492 | 496 | ||
497 | int cond_write_bool(void *vkey, void *datum, void *ptr) | ||
498 | { | ||
499 | char *key = vkey; | ||
500 | struct cond_bool_datum *booldatum = datum; | ||
501 | struct policy_data *pd = ptr; | ||
502 | void *fp = pd->fp; | ||
503 | __le32 buf[3]; | ||
504 | u32 len; | ||
505 | int rc; | ||
506 | |||
507 | len = strlen(key); | ||
508 | buf[0] = cpu_to_le32(booldatum->value); | ||
509 | buf[1] = cpu_to_le32(booldatum->state); | ||
510 | buf[2] = cpu_to_le32(len); | ||
511 | rc = put_entry(buf, sizeof(u32), 3, fp); | ||
512 | if (rc) | ||
513 | return rc; | ||
514 | rc = put_entry(key, 1, len, fp); | ||
515 | if (rc) | ||
516 | return rc; | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | /* | ||
521 | * cond_write_cond_av_list doesn't write out the av_list nodes. | ||
522 | * Instead it writes out the key/value pairs from the avtab. This | ||
523 | * is necessary because there is no way to uniquely identifying rules | ||
524 | * in the avtab so it is not possible to associate individual rules | ||
525 | * in the avtab with a conditional without saving them as part of | ||
526 | * the conditional. This means that the avtab with the conditional | ||
527 | * rules will not be saved but will be rebuilt on policy load. | ||
528 | */ | ||
529 | static int cond_write_av_list(struct policydb *p, | ||
530 | struct cond_av_list *list, struct policy_file *fp) | ||
531 | { | ||
532 | __le32 buf[1]; | ||
533 | struct cond_av_list *cur_list; | ||
534 | u32 len; | ||
535 | int rc; | ||
536 | |||
537 | len = 0; | ||
538 | for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) | ||
539 | len++; | ||
540 | |||
541 | buf[0] = cpu_to_le32(len); | ||
542 | rc = put_entry(buf, sizeof(u32), 1, fp); | ||
543 | if (rc) | ||
544 | return rc; | ||
545 | |||
546 | if (len == 0) | ||
547 | return 0; | ||
548 | |||
549 | for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) { | ||
550 | rc = avtab_write_item(p, cur_list->node, fp); | ||
551 | if (rc) | ||
552 | return rc; | ||
553 | } | ||
554 | |||
555 | return 0; | ||
556 | } | ||
557 | |||
558 | int cond_write_node(struct policydb *p, struct cond_node *node, | ||
559 | struct policy_file *fp) | ||
560 | { | ||
561 | struct cond_expr *cur_expr; | ||
562 | __le32 buf[2]; | ||
563 | int rc; | ||
564 | u32 len = 0; | ||
565 | |||
566 | buf[0] = cpu_to_le32(node->cur_state); | ||
567 | rc = put_entry(buf, sizeof(u32), 1, fp); | ||
568 | if (rc) | ||
569 | return rc; | ||
570 | |||
571 | for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) | ||
572 | len++; | ||
573 | |||
574 | buf[0] = cpu_to_le32(len); | ||
575 | rc = put_entry(buf, sizeof(u32), 1, fp); | ||
576 | if (rc) | ||
577 | return rc; | ||
578 | |||
579 | for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) { | ||
580 | buf[0] = cpu_to_le32(cur_expr->expr_type); | ||
581 | buf[1] = cpu_to_le32(cur_expr->bool); | ||
582 | rc = put_entry(buf, sizeof(u32), 2, fp); | ||
583 | if (rc) | ||
584 | return rc; | ||
585 | } | ||
586 | |||
587 | rc = cond_write_av_list(p, node->true_list, fp); | ||
588 | if (rc) | ||
589 | return rc; | ||
590 | rc = cond_write_av_list(p, node->false_list, fp); | ||
591 | if (rc) | ||
592 | return rc; | ||
593 | |||
594 | return 0; | ||
595 | } | ||
596 | |||
597 | int cond_write_list(struct policydb *p, struct cond_node *list, void *fp) | ||
598 | { | ||
599 | struct cond_node *cur; | ||
600 | u32 len; | ||
601 | __le32 buf[1]; | ||
602 | int rc; | ||
603 | |||
604 | len = 0; | ||
605 | for (cur = list; cur != NULL; cur = cur->next) | ||
606 | len++; | ||
607 | buf[0] = cpu_to_le32(len); | ||
608 | rc = put_entry(buf, sizeof(u32), 1, fp); | ||
609 | if (rc) | ||
610 | return rc; | ||
611 | |||
612 | for (cur = list; cur != NULL; cur = cur->next) { | ||
613 | rc = cond_write_node(p, cur, fp); | ||
614 | if (rc) | ||
615 | return rc; | ||
616 | } | ||
617 | |||
618 | return 0; | ||
619 | } | ||
493 | /* Determine whether additional permissions are granted by the conditional | 620 | /* Determine whether additional permissions are granted by the conditional |
494 | * av table, and if so, add them to the result | 621 | * av table, and if so, add them to the result |
495 | */ | 622 | */ |