diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2018-12-01 23:06:57 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-12-21 11:45:41 -0500 |
commit | c039bc3c2498724946304a8f964244a9b6af1043 (patch) | |
tree | ce98ee8e698a28cbaed969460457941e8b34f2e3 /security/selinux/hooks.c | |
parent | 6be8750b4cba8c37170f46b29841d112f1be749b (diff) |
LSM: lift extracting and parsing LSM options into the caller of ->sb_remount()
This paves the way for retaining the LSM options from a common filesystem
mount context during a mount parameter parsing phase to be instituted prior
to actual mount/reconfiguration actions.
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r-- | security/selinux/hooks.c | 47 |
1 files changed, 12 insertions, 35 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ba229d4a64d3..ba3e2917bd24 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -2812,39 +2812,22 @@ out: | |||
2812 | return rc; | 2812 | return rc; |
2813 | } | 2813 | } |
2814 | 2814 | ||
2815 | static int selinux_sb_remount(struct super_block *sb, void *data) | 2815 | static int selinux_sb_remount(struct super_block *sb, |
2816 | struct security_mnt_opts *opts) | ||
2816 | { | 2817 | { |
2817 | int rc, i, *flags; | 2818 | int i, *flags; |
2818 | struct security_mnt_opts opts; | 2819 | char **mount_options; |
2819 | char *secdata, **mount_options; | ||
2820 | struct superblock_security_struct *sbsec = sb->s_security; | 2820 | struct superblock_security_struct *sbsec = sb->s_security; |
2821 | 2821 | ||
2822 | if (!(sbsec->flags & SE_SBINITIALIZED)) | 2822 | if (!(sbsec->flags & SE_SBINITIALIZED)) |
2823 | return 0; | 2823 | return 0; |
2824 | 2824 | ||
2825 | if (!data) | 2825 | mount_options = opts->mnt_opts; |
2826 | return 0; | 2826 | flags = opts->mnt_opts_flags; |
2827 | |||
2828 | if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA) | ||
2829 | return 0; | ||
2830 | |||
2831 | security_init_mnt_opts(&opts); | ||
2832 | secdata = alloc_secdata(); | ||
2833 | if (!secdata) | ||
2834 | return -ENOMEM; | ||
2835 | rc = selinux_sb_copy_data(data, secdata); | ||
2836 | if (rc) | ||
2837 | goto out_free_secdata; | ||
2838 | |||
2839 | rc = selinux_parse_opts_str(secdata, &opts); | ||
2840 | if (rc) | ||
2841 | goto out_free_secdata; | ||
2842 | 2827 | ||
2843 | mount_options = opts.mnt_opts; | 2828 | for (i = 0; i < opts->num_mnt_opts; i++) { |
2844 | flags = opts.mnt_opts_flags; | ||
2845 | |||
2846 | for (i = 0; i < opts.num_mnt_opts; i++) { | ||
2847 | u32 sid; | 2829 | u32 sid; |
2830 | int rc; | ||
2848 | 2831 | ||
2849 | if (flags[i] == SBLABEL_MNT) | 2832 | if (flags[i] == SBLABEL_MNT) |
2850 | continue; | 2833 | continue; |
@@ -2855,9 +2838,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data) | |||
2855 | pr_warn("SELinux: security_context_str_to_sid" | 2838 | pr_warn("SELinux: security_context_str_to_sid" |
2856 | "(%s) failed for (dev %s, type %s) errno=%d\n", | 2839 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
2857 | mount_options[i], sb->s_id, sb->s_type->name, rc); | 2840 | mount_options[i], sb->s_id, sb->s_type->name, rc); |
2858 | goto out_free_opts; | 2841 | return rc; |
2859 | } | 2842 | } |
2860 | rc = -EINVAL; | ||
2861 | switch (flags[i]) { | 2843 | switch (flags[i]) { |
2862 | case FSCONTEXT_MNT: | 2844 | case FSCONTEXT_MNT: |
2863 | if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid)) | 2845 | if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid)) |
@@ -2880,21 +2862,16 @@ static int selinux_sb_remount(struct super_block *sb, void *data) | |||
2880 | goto out_bad_option; | 2862 | goto out_bad_option; |
2881 | break; | 2863 | break; |
2882 | default: | 2864 | default: |
2883 | goto out_free_opts; | 2865 | return -EINVAL; |
2884 | } | 2866 | } |
2885 | } | 2867 | } |
2868 | return 0; | ||
2886 | 2869 | ||
2887 | rc = 0; | ||
2888 | out_free_opts: | ||
2889 | security_free_mnt_opts(&opts); | ||
2890 | out_free_secdata: | ||
2891 | free_secdata(secdata); | ||
2892 | return rc; | ||
2893 | out_bad_option: | 2870 | out_bad_option: |
2894 | pr_warn("SELinux: unable to change security options " | 2871 | pr_warn("SELinux: unable to change security options " |
2895 | "during remount (dev %s, type=%s)\n", sb->s_id, | 2872 | "during remount (dev %s, type=%s)\n", sb->s_id, |
2896 | sb->s_type->name); | 2873 | sb->s_type->name); |
2897 | goto out_free_opts; | 2874 | return -EINVAL; |
2898 | } | 2875 | } |
2899 | 2876 | ||
2900 | static int selinux_sb_kern_mount(struct super_block *sb, int flags, | 2877 | static int selinux_sb_kern_mount(struct super_block *sb, int flags, |