diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2018-12-13 15:18:05 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-12-21 11:48:54 -0500 |
commit | 12085b14a4440a6d12ff7966702c010df87caef0 (patch) | |
tree | d9c8192f4183f7f807f81953b685f041da1eb395 | |
parent | bd3236557bb256d6491df125e5e9d0393c70e4d2 (diff) |
smack: switch to private smack_mnt_opts
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | security/smack/smack_lsm.c | 157 |
1 files changed, 55 insertions, 102 deletions
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 81a8112975d4..99aec9f42be3 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -567,16 +567,18 @@ static void smack_sb_free_security(struct super_block *sb) | |||
567 | sb->s_security = NULL; | 567 | sb->s_security = NULL; |
568 | } | 568 | } |
569 | 569 | ||
570 | struct smack_mnt_opts { | ||
571 | const char *fsdefault, *fsfloor, *fshat, *fsroot, *fstransmute; | ||
572 | }; | ||
573 | |||
570 | static void smack_free_mnt_opts(void *mnt_opts) | 574 | static void smack_free_mnt_opts(void *mnt_opts) |
571 | { | 575 | { |
572 | struct security_mnt_opts *opts = mnt_opts; | 576 | struct smack_mnt_opts *opts = mnt_opts; |
573 | int i; | 577 | kfree(opts->fsdefault); |
574 | 578 | kfree(opts->fsfloor); | |
575 | if (opts->mnt_opts) | 579 | kfree(opts->fshat); |
576 | for (i = 0; i < opts->num_mnt_opts; i++) | 580 | kfree(opts->fsroot); |
577 | kfree(opts->mnt_opts[i]); | 581 | kfree(opts->fstransmute); |
578 | kfree(opts->mnt_opts); | ||
579 | kfree(opts->mnt_opts_flags); | ||
580 | kfree(opts); | 582 | kfree(opts); |
581 | } | 583 | } |
582 | 584 | ||
@@ -639,28 +641,14 @@ static int smack_sb_copy_data(char *orig, char *smackopts) | |||
639 | static int smack_parse_opts_str(char *options, | 641 | static int smack_parse_opts_str(char *options, |
640 | void **mnt_opts) | 642 | void **mnt_opts) |
641 | { | 643 | { |
642 | struct security_mnt_opts *opts = *mnt_opts; | 644 | struct smack_mnt_opts *opts = *mnt_opts; |
643 | char *p; | 645 | char *p; |
644 | char *fsdefault = NULL; | ||
645 | char *fsfloor = NULL; | ||
646 | char *fshat = NULL; | ||
647 | char *fsroot = NULL; | ||
648 | char *fstransmute = NULL; | ||
649 | int rc = -ENOMEM; | 646 | int rc = -ENOMEM; |
650 | int num_mnt_opts = 0; | ||
651 | int token; | 647 | int token; |
652 | 648 | ||
653 | if (!options) | 649 | if (!options) |
654 | return 0; | 650 | return 0; |
655 | 651 | ||
656 | if (!opts) { | ||
657 | opts = kzalloc(sizeof(struct security_mnt_opts), GFP_KERNEL); | ||
658 | *mnt_opts = opts; | ||
659 | if (!opts) | ||
660 | return -ENOMEM; | ||
661 | } | ||
662 | opts->num_mnt_opts = 0; | ||
663 | |||
664 | while ((p = strsep(&options, ",")) != NULL) { | 652 | while ((p = strsep(&options, ",")) != NULL) { |
665 | substring_t args[MAX_OPT_ARGS]; | 653 | substring_t args[MAX_OPT_ARGS]; |
666 | 654 | ||
@@ -669,40 +657,46 @@ static int smack_parse_opts_str(char *options, | |||
669 | 657 | ||
670 | token = match_token(p, smk_mount_tokens, args); | 658 | token = match_token(p, smk_mount_tokens, args); |
671 | 659 | ||
660 | if (!opts) { | ||
661 | opts = kzalloc(sizeof(struct smack_mnt_opts), GFP_KERNEL); | ||
662 | if (!opts) | ||
663 | return -ENOMEM; | ||
664 | } | ||
665 | |||
672 | switch (token) { | 666 | switch (token) { |
673 | case Opt_fsdefault: | 667 | case Opt_fsdefault: |
674 | if (fsdefault) | 668 | if (opts->fsdefault) |
675 | goto out_opt_err; | 669 | goto out_opt_err; |
676 | fsdefault = match_strdup(&args[0]); | 670 | opts->fsdefault = match_strdup(&args[0]); |
677 | if (!fsdefault) | 671 | if (!opts->fsdefault) |
678 | goto out_err; | 672 | goto out_err; |
679 | break; | 673 | break; |
680 | case Opt_fsfloor: | 674 | case Opt_fsfloor: |
681 | if (fsfloor) | 675 | if (opts->fsfloor) |
682 | goto out_opt_err; | 676 | goto out_opt_err; |
683 | fsfloor = match_strdup(&args[0]); | 677 | opts->fsfloor = match_strdup(&args[0]); |
684 | if (!fsfloor) | 678 | if (!opts->fsfloor) |
685 | goto out_err; | 679 | goto out_err; |
686 | break; | 680 | break; |
687 | case Opt_fshat: | 681 | case Opt_fshat: |
688 | if (fshat) | 682 | if (opts->fshat) |
689 | goto out_opt_err; | 683 | goto out_opt_err; |
690 | fshat = match_strdup(&args[0]); | 684 | opts->fshat = match_strdup(&args[0]); |
691 | if (!fshat) | 685 | if (!opts->fshat) |
692 | goto out_err; | 686 | goto out_err; |
693 | break; | 687 | break; |
694 | case Opt_fsroot: | 688 | case Opt_fsroot: |
695 | if (fsroot) | 689 | if (opts->fsroot) |
696 | goto out_opt_err; | 690 | goto out_opt_err; |
697 | fsroot = match_strdup(&args[0]); | 691 | opts->fsroot = match_strdup(&args[0]); |
698 | if (!fsroot) | 692 | if (!opts->fsroot) |
699 | goto out_err; | 693 | goto out_err; |
700 | break; | 694 | break; |
701 | case Opt_fstransmute: | 695 | case Opt_fstransmute: |
702 | if (fstransmute) | 696 | if (opts->fstransmute) |
703 | goto out_opt_err; | 697 | goto out_opt_err; |
704 | fstransmute = match_strdup(&args[0]); | 698 | opts->fstransmute = match_strdup(&args[0]); |
705 | if (!fstransmute) | 699 | if (!opts->fstransmute) |
706 | goto out_err; | 700 | goto out_err; |
707 | break; | 701 | break; |
708 | default: | 702 | default: |
@@ -711,38 +705,7 @@ static int smack_parse_opts_str(char *options, | |||
711 | goto out_err; | 705 | goto out_err; |
712 | } | 706 | } |
713 | } | 707 | } |
714 | 708 | *mnt_opts = opts; | |
715 | opts->mnt_opts = kcalloc(NUM_SMK_MNT_OPTS, sizeof(char *), GFP_KERNEL); | ||
716 | if (!opts->mnt_opts) | ||
717 | goto out_err; | ||
718 | |||
719 | opts->mnt_opts_flags = kcalloc(NUM_SMK_MNT_OPTS, sizeof(int), | ||
720 | GFP_KERNEL); | ||
721 | if (!opts->mnt_opts_flags) | ||
722 | goto out_err; | ||
723 | |||
724 | if (fsdefault) { | ||
725 | opts->mnt_opts[num_mnt_opts] = fsdefault; | ||
726 | opts->mnt_opts_flags[num_mnt_opts++] = FSDEFAULT_MNT; | ||
727 | } | ||
728 | if (fsfloor) { | ||
729 | opts->mnt_opts[num_mnt_opts] = fsfloor; | ||
730 | opts->mnt_opts_flags[num_mnt_opts++] = FSFLOOR_MNT; | ||
731 | } | ||
732 | if (fshat) { | ||
733 | opts->mnt_opts[num_mnt_opts] = fshat; | ||
734 | opts->mnt_opts_flags[num_mnt_opts++] = FSHAT_MNT; | ||
735 | } | ||
736 | if (fsroot) { | ||
737 | opts->mnt_opts[num_mnt_opts] = fsroot; | ||
738 | opts->mnt_opts_flags[num_mnt_opts++] = FSROOT_MNT; | ||
739 | } | ||
740 | if (fstransmute) { | ||
741 | opts->mnt_opts[num_mnt_opts] = fstransmute; | ||
742 | opts->mnt_opts_flags[num_mnt_opts++] = FSTRANS_MNT; | ||
743 | } | ||
744 | |||
745 | opts->num_mnt_opts = num_mnt_opts; | ||
746 | return 0; | 709 | return 0; |
747 | 710 | ||
748 | out_opt_err: | 711 | out_opt_err: |
@@ -750,12 +713,8 @@ out_opt_err: | |||
750 | pr_warn("Smack: duplicate mount options\n"); | 713 | pr_warn("Smack: duplicate mount options\n"); |
751 | 714 | ||
752 | out_err: | 715 | out_err: |
753 | kfree(fsdefault); | 716 | if (opts) |
754 | kfree(fsfloor); | 717 | smack_free_mnt_opts(opts); |
755 | kfree(fshat); | ||
756 | kfree(fsroot); | ||
757 | kfree(fstransmute); | ||
758 | security_free_mnt_opts(mnt_opts); | ||
759 | return rc; | 718 | return rc; |
760 | } | 719 | } |
761 | 720 | ||
@@ -795,10 +754,8 @@ static int smack_set_mnt_opts(struct super_block *sb, | |||
795 | struct superblock_smack *sp = sb->s_security; | 754 | struct superblock_smack *sp = sb->s_security; |
796 | struct inode_smack *isp; | 755 | struct inode_smack *isp; |
797 | struct smack_known *skp; | 756 | struct smack_known *skp; |
798 | int i; | 757 | struct smack_mnt_opts *opts = mnt_opts; |
799 | struct security_mnt_opts *opts = mnt_opts; | 758 | bool transmute = false; |
800 | int num_opts = opts ? opts->num_mnt_opts : 0; | ||
801 | int transmute = 0; | ||
802 | 759 | ||
803 | if (sp->smk_flags & SMK_SB_INITIALIZED) | 760 | if (sp->smk_flags & SMK_SB_INITIALIZED) |
804 | return 0; | 761 | return 0; |
@@ -807,7 +764,7 @@ static int smack_set_mnt_opts(struct super_block *sb, | |||
807 | /* | 764 | /* |
808 | * Unprivileged mounts don't get to specify Smack values. | 765 | * Unprivileged mounts don't get to specify Smack values. |
809 | */ | 766 | */ |
810 | if (num_opts) | 767 | if (opts) |
811 | return -EPERM; | 768 | return -EPERM; |
812 | /* | 769 | /* |
813 | * Unprivileged mounts get root and default from the caller. | 770 | * Unprivileged mounts get root and default from the caller. |
@@ -823,48 +780,44 @@ static int smack_set_mnt_opts(struct super_block *sb, | |||
823 | if (sb->s_user_ns != &init_user_ns && | 780 | if (sb->s_user_ns != &init_user_ns && |
824 | sb->s_magic != SYSFS_MAGIC && sb->s_magic != TMPFS_MAGIC && | 781 | sb->s_magic != SYSFS_MAGIC && sb->s_magic != TMPFS_MAGIC && |
825 | sb->s_magic != RAMFS_MAGIC) { | 782 | sb->s_magic != RAMFS_MAGIC) { |
826 | transmute = 1; | 783 | transmute = true; |
827 | sp->smk_flags |= SMK_SB_UNTRUSTED; | 784 | sp->smk_flags |= SMK_SB_UNTRUSTED; |
828 | } | 785 | } |
829 | } | 786 | } |
830 | 787 | ||
831 | sp->smk_flags |= SMK_SB_INITIALIZED; | 788 | sp->smk_flags |= SMK_SB_INITIALIZED; |
832 | 789 | ||
833 | for (i = 0; i < num_opts; i++) { | 790 | if (opts) { |
834 | switch (opts->mnt_opts_flags[i]) { | 791 | if (opts->fsdefault) { |
835 | case FSDEFAULT_MNT: | 792 | skp = smk_import_entry(opts->fsdefault, 0); |
836 | skp = smk_import_entry(opts->mnt_opts[i], 0); | ||
837 | if (IS_ERR(skp)) | 793 | if (IS_ERR(skp)) |
838 | return PTR_ERR(skp); | 794 | return PTR_ERR(skp); |
839 | sp->smk_default = skp; | 795 | sp->smk_default = skp; |
840 | break; | 796 | } |
841 | case FSFLOOR_MNT: | 797 | if (opts->fsfloor) { |
842 | skp = smk_import_entry(opts->mnt_opts[i], 0); | 798 | skp = smk_import_entry(opts->fsfloor, 0); |
843 | if (IS_ERR(skp)) | 799 | if (IS_ERR(skp)) |
844 | return PTR_ERR(skp); | 800 | return PTR_ERR(skp); |
845 | sp->smk_floor = skp; | 801 | sp->smk_floor = skp; |
846 | break; | 802 | } |
847 | case FSHAT_MNT: | 803 | if (opts->fshat) { |
848 | skp = smk_import_entry(opts->mnt_opts[i], 0); | 804 | skp = smk_import_entry(opts->fshat, 0); |
849 | if (IS_ERR(skp)) | 805 | if (IS_ERR(skp)) |
850 | return PTR_ERR(skp); | 806 | return PTR_ERR(skp); |
851 | sp->smk_hat = skp; | 807 | sp->smk_hat = skp; |
852 | break; | 808 | } |
853 | case FSROOT_MNT: | 809 | if (opts->fsroot) { |
854 | skp = smk_import_entry(opts->mnt_opts[i], 0); | 810 | skp = smk_import_entry(opts->fsroot, 0); |
855 | if (IS_ERR(skp)) | 811 | if (IS_ERR(skp)) |
856 | return PTR_ERR(skp); | 812 | return PTR_ERR(skp); |
857 | sp->smk_root = skp; | 813 | sp->smk_root = skp; |
858 | break; | 814 | } |
859 | case FSTRANS_MNT: | 815 | if (opts->fstransmute) { |
860 | skp = smk_import_entry(opts->mnt_opts[i], 0); | 816 | skp = smk_import_entry(opts->fstransmute, 0); |
861 | if (IS_ERR(skp)) | 817 | if (IS_ERR(skp)) |
862 | return PTR_ERR(skp); | 818 | return PTR_ERR(skp); |
863 | sp->smk_root = skp; | 819 | sp->smk_root = skp; |
864 | transmute = 1; | 820 | transmute = true; |
865 | break; | ||
866 | default: | ||
867 | break; | ||
868 | } | 821 | } |
869 | } | 822 | } |
870 | 823 | ||