diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2018-12-16 01:37:06 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-12-21 11:51:02 -0500 |
commit | d2497e12e230c3f1be8ca6a0609a98c8c609fb80 (patch) | |
tree | 91156d8db61b4929b980bc4d4856803a4acb1685 /security | |
parent | c3300aaf95fb4e5be41e731fa6427d0d996d32ac (diff) |
smack: rewrite smack_sb_eat_lsm_opts()
make it use smack_add_opt() and avoid separate copies - gather
non-LSM options by memmove() in place
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'security')
-rw-r--r-- | security/smack/smack_lsm.c | 108 |
1 files changed, 23 insertions, 85 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index d479def4d6a0..24a00d93d8c3 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -599,53 +599,6 @@ static void smack_free_mnt_opts(void *mnt_opts) | |||
599 | kfree(opts); | 599 | kfree(opts); |
600 | } | 600 | } |
601 | 601 | ||
602 | /** | ||
603 | * smack_sb_copy_data - copy mount options data for processing | ||
604 | * @orig: where to start | ||
605 | * @smackopts: mount options string | ||
606 | * | ||
607 | * Returns 0 on success or -ENOMEM on error. | ||
608 | * | ||
609 | * Copy the Smack specific mount options out of the mount | ||
610 | * options list. | ||
611 | */ | ||
612 | static int smack_sb_copy_data(char *orig, char *smackopts) | ||
613 | { | ||
614 | char *cp, *commap, *otheropts, *dp; | ||
615 | |||
616 | otheropts = (char *)get_zeroed_page(GFP_KERNEL); | ||
617 | if (otheropts == NULL) | ||
618 | return -ENOMEM; | ||
619 | |||
620 | for (cp = orig, commap = orig; commap != NULL; cp = commap + 1) { | ||
621 | if (strstr(cp, SMK_FSDEFAULT) == cp) | ||
622 | dp = smackopts; | ||
623 | else if (strstr(cp, SMK_FSFLOOR) == cp) | ||
624 | dp = smackopts; | ||
625 | else if (strstr(cp, SMK_FSHAT) == cp) | ||
626 | dp = smackopts; | ||
627 | else if (strstr(cp, SMK_FSROOT) == cp) | ||
628 | dp = smackopts; | ||
629 | else if (strstr(cp, SMK_FSTRANS) == cp) | ||
630 | dp = smackopts; | ||
631 | else | ||
632 | dp = otheropts; | ||
633 | |||
634 | commap = strchr(cp, ','); | ||
635 | if (commap != NULL) | ||
636 | *commap = '\0'; | ||
637 | |||
638 | if (*dp != '\0') | ||
639 | strcat(dp, ","); | ||
640 | strcat(dp, cp); | ||
641 | } | ||
642 | |||
643 | strcpy(orig, otheropts); | ||
644 | free_page((unsigned long)otheropts); | ||
645 | |||
646 | return 0; | ||
647 | } | ||
648 | |||
649 | static int smack_add_opt(int token, const char *s, void **mnt_opts) | 602 | static int smack_add_opt(int token, const char *s, void **mnt_opts) |
650 | { | 603 | { |
651 | struct smack_mnt_opts *opts = *mnt_opts; | 604 | struct smack_mnt_opts *opts = *mnt_opts; |
@@ -656,7 +609,6 @@ static int smack_add_opt(int token, const char *s, void **mnt_opts) | |||
656 | return -ENOMEM; | 609 | return -ENOMEM; |
657 | *mnt_opts = opts; | 610 | *mnt_opts = opts; |
658 | } | 611 | } |
659 | |||
660 | if (!s) | 612 | if (!s) |
661 | return -ENOMEM; | 613 | return -ENOMEM; |
662 | 614 | ||
@@ -694,22 +646,10 @@ out_opt_err: | |||
694 | return -EINVAL; | 646 | return -EINVAL; |
695 | } | 647 | } |
696 | 648 | ||
697 | /** | 649 | static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts) |
698 | * smack_parse_opts_str - parse Smack specific mount options | ||
699 | * @options: mount options string | ||
700 | * @opts: where to store converted mount opts | ||
701 | * | ||
702 | * Returns 0 on success or -ENOMEM on error. | ||
703 | * | ||
704 | * converts Smack specific mount options to generic security option format | ||
705 | */ | ||
706 | static int smack_parse_opts_str(char *options, | ||
707 | void **mnt_opts) | ||
708 | { | 650 | { |
709 | char *from = options; | 651 | char *from = options, *to = options; |
710 | 652 | bool first = true; | |
711 | if (!options) | ||
712 | return 0; | ||
713 | 653 | ||
714 | while (1) { | 654 | while (1) { |
715 | char *next = strchr(from, ','); | 655 | char *next = strchr(from, ','); |
@@ -722,36 +662,34 @@ static int smack_parse_opts_str(char *options, | |||
722 | len = strlen(from); | 662 | len = strlen(from); |
723 | 663 | ||
724 | token = match_opt_prefix(from, len, &arg); | 664 | token = match_opt_prefix(from, len, &arg); |
725 | arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL); | 665 | if (token != Opt_error) { |
726 | rc = smack_add_opt(token, arg, mnt_opts); | 666 | arg = kmemdup_nul(arg, from + len - arg, GFP_KERNEL); |
727 | if (unlikely(rc)) { | 667 | rc = smack_add_opt(token, arg, mnt_opts); |
728 | kfree(arg); | 668 | if (unlikely(rc)) { |
729 | if (*mnt_opts) | 669 | kfree(arg); |
730 | smack_free_mnt_opts(*mnt_opts); | 670 | if (*mnt_opts) |
731 | *mnt_opts = NULL; | 671 | smack_free_mnt_opts(*mnt_opts); |
732 | return rc; | 672 | *mnt_opts = NULL; |
673 | return rc; | ||
674 | } | ||
675 | } else { | ||
676 | if (!first) { // copy with preceding comma | ||
677 | from--; | ||
678 | len++; | ||
679 | } | ||
680 | if (to != from) | ||
681 | memmove(to, from, len); | ||
682 | to += len; | ||
683 | first = false; | ||
733 | } | 684 | } |
734 | if (!from[len]) | 685 | if (!from[len]) |
735 | break; | 686 | break; |
736 | from += len + 1; | 687 | from += len + 1; |
737 | } | 688 | } |
689 | *to = '\0'; | ||
738 | return 0; | 690 | return 0; |
739 | } | 691 | } |
740 | 692 | ||
741 | static int smack_sb_eat_lsm_opts(char *options, void **mnt_opts) | ||
742 | { | ||
743 | char *s = (char *)get_zeroed_page(GFP_KERNEL); | ||
744 | int err; | ||
745 | |||
746 | if (!s) | ||
747 | return -ENOMEM; | ||
748 | err = smack_sb_copy_data(options, s); | ||
749 | if (!err) | ||
750 | err = smack_parse_opts_str(s, mnt_opts); | ||
751 | free_page((unsigned long)s); | ||
752 | return err; | ||
753 | } | ||
754 | |||
755 | /** | 693 | /** |
756 | * smack_set_mnt_opts - set Smack specific mount options | 694 | * smack_set_mnt_opts - set Smack specific mount options |
757 | * @sb: the file system superblock | 695 | * @sb: the file system superblock |