summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2018-12-13 15:18:05 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2018-12-21 11:48:54 -0500
commit12085b14a4440a6d12ff7966702c010df87caef0 (patch)
treed9c8192f4183f7f807f81953b685f041da1eb395
parentbd3236557bb256d6491df125e5e9d0393c70e4d2 (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.c157
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
570struct smack_mnt_opts {
571 const char *fsdefault, *fsfloor, *fshat, *fsroot, *fstransmute;
572};
573
570static void smack_free_mnt_opts(void *mnt_opts) 574static 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)
639static int smack_parse_opts_str(char *options, 641static 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
748out_opt_err: 711out_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
752out_err: 715out_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