aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c52
1 files changed, 37 insertions, 15 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 11cf2feb27b3..caf7ca7abfc1 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -433,6 +433,19 @@ static void superblock_free_security(struct super_block *sb)
433 kfree(sbsec); 433 kfree(sbsec);
434} 434}
435 435
436static void selinux_free_mnt_opts(void *mnt_opts)
437{
438 struct security_mnt_opts *opts = mnt_opts;
439 int i;
440
441 if (opts->mnt_opts)
442 for (i = 0; i < opts->num_mnt_opts; i++)
443 kfree(opts->mnt_opts[i]);
444 kfree(opts->mnt_opts);
445 kfree(opts->mnt_opts_flags);
446 kfree(opts);
447}
448
436static inline int inode_doinit(struct inode *inode) 449static inline int inode_doinit(struct inode *inode)
437{ 450{
438 return inode_doinit_with_dentry(inode, NULL); 451 return inode_doinit_with_dentry(inode, NULL);
@@ -616,7 +629,7 @@ static int bad_option(struct superblock_security_struct *sbsec, char flag,
616 * labeling information. 629 * labeling information.
617 */ 630 */
618static int selinux_set_mnt_opts(struct super_block *sb, 631static int selinux_set_mnt_opts(struct super_block *sb,
619 struct security_mnt_opts *opts, 632 void *mnt_opts,
620 unsigned long kern_flags, 633 unsigned long kern_flags,
621 unsigned long *set_kern_flags) 634 unsigned long *set_kern_flags)
622{ 635{
@@ -628,9 +641,10 @@ static int selinux_set_mnt_opts(struct super_block *sb,
628 struct inode_security_struct *root_isec; 641 struct inode_security_struct *root_isec;
629 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; 642 u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
630 u32 defcontext_sid = 0; 643 u32 defcontext_sid = 0;
631 char **mount_options = opts->mnt_opts; 644 struct security_mnt_opts *opts = mnt_opts;
632 int *flags = opts->mnt_opts_flags; 645 char **mount_options = opts ? opts->mnt_opts : NULL;
633 int num_opts = opts->num_mnt_opts; 646 int *flags = opts ? opts->mnt_opts_flags : NULL;
647 int num_opts = opts ? opts->num_mnt_opts : 0;
634 648
635 mutex_lock(&sbsec->lock); 649 mutex_lock(&sbsec->lock);
636 650
@@ -982,12 +996,20 @@ out:
982} 996}
983 997
984static int selinux_parse_opts_str(char *options, 998static int selinux_parse_opts_str(char *options,
985 struct security_mnt_opts *opts) 999 void **mnt_opts)
986{ 1000{
987 char *p; 1001 char *p;
988 char *context = NULL, *defcontext = NULL; 1002 char *context = NULL, *defcontext = NULL;
989 char *fscontext = NULL, *rootcontext = NULL; 1003 char *fscontext = NULL, *rootcontext = NULL;
990 int rc, num_mnt_opts = 0; 1004 int rc, num_mnt_opts = 0;
1005 struct security_mnt_opts *opts = *mnt_opts;
1006
1007 if (!opts) {
1008 opts = kzalloc(sizeof(struct security_mnt_opts), GFP_KERNEL);
1009 *mnt_opts = opts;
1010 if (!opts)
1011 return -ENOMEM;
1012 }
991 1013
992 opts->num_mnt_opts = 0; 1014 opts->num_mnt_opts = 0;
993 1015
@@ -1094,7 +1116,7 @@ static int selinux_parse_opts_str(char *options,
1094 return 0; 1116 return 0;
1095 1117
1096out_err: 1118out_err:
1097 security_free_mnt_opts(opts); 1119 security_free_mnt_opts(mnt_opts);
1098 kfree(context); 1120 kfree(context);
1099 kfree(defcontext); 1121 kfree(defcontext);
1100 kfree(fscontext); 1122 kfree(fscontext);
@@ -2714,7 +2736,7 @@ out:
2714 return rc; 2736 return rc;
2715} 2737}
2716 2738
2717static int selinux_sb_eat_lsm_opts(char *options, struct security_mnt_opts *opts) 2739static int selinux_sb_eat_lsm_opts(char *options, void **mnt_opts)
2718{ 2740{
2719 char *s = (char *)get_zeroed_page(GFP_KERNEL); 2741 char *s = (char *)get_zeroed_page(GFP_KERNEL);
2720 int err; 2742 int err;
@@ -2723,14 +2745,14 @@ static int selinux_sb_eat_lsm_opts(char *options, struct security_mnt_opts *opts
2723 return -ENOMEM; 2745 return -ENOMEM;
2724 err = selinux_sb_copy_data(options, s); 2746 err = selinux_sb_copy_data(options, s);
2725 if (!err) 2747 if (!err)
2726 err = selinux_parse_opts_str(s, opts); 2748 err = selinux_parse_opts_str(s, mnt_opts);
2727 free_page((unsigned long)s); 2749 free_page((unsigned long)s);
2728 return err; 2750 return err;
2729} 2751}
2730 2752
2731static int selinux_sb_remount(struct super_block *sb, 2753static int selinux_sb_remount(struct super_block *sb, void *mnt_opts)
2732 struct security_mnt_opts *opts)
2733{ 2754{
2755 struct security_mnt_opts *opts = mnt_opts;
2734 int i, *flags; 2756 int i, *flags;
2735 char **mount_options; 2757 char **mount_options;
2736 struct superblock_security_struct *sbsec = sb->s_security; 2758 struct superblock_security_struct *sbsec = sb->s_security;
@@ -2738,6 +2760,9 @@ static int selinux_sb_remount(struct super_block *sb,
2738 if (!(sbsec->flags & SE_SBINITIALIZED)) 2760 if (!(sbsec->flags & SE_SBINITIALIZED))
2739 return 0; 2761 return 0;
2740 2762
2763 if (!opts)
2764 return 0;
2765
2741 mount_options = opts->mnt_opts; 2766 mount_options = opts->mnt_opts;
2742 flags = opts->mnt_opts_flags; 2767 flags = opts->mnt_opts_flags;
2743 2768
@@ -6782,6 +6807,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
6782 LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security), 6807 LSM_HOOK_INIT(sb_alloc_security, selinux_sb_alloc_security),
6783 LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security), 6808 LSM_HOOK_INIT(sb_free_security, selinux_sb_free_security),
6784 LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts), 6809 LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts),
6810 LSM_HOOK_INIT(sb_free_mnt_opts, selinux_free_mnt_opts),
6785 LSM_HOOK_INIT(sb_remount, selinux_sb_remount), 6811 LSM_HOOK_INIT(sb_remount, selinux_sb_remount),
6786 LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount), 6812 LSM_HOOK_INIT(sb_kern_mount, selinux_sb_kern_mount),
6787 LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options), 6813 LSM_HOOK_INIT(sb_show_options, selinux_sb_show_options),
@@ -7051,11 +7077,7 @@ static __init int selinux_init(void)
7051 7077
7052static void delayed_superblock_init(struct super_block *sb, void *unused) 7078static void delayed_superblock_init(struct super_block *sb, void *unused)
7053{ 7079{
7054 struct security_mnt_opts opts; 7080 selinux_set_mnt_opts(sb, NULL, 0, NULL);
7055
7056 security_init_mnt_opts(&opts);
7057 selinux_set_mnt_opts(sb, &opts, 0, NULL);
7058 security_free_mnt_opts(&opts);
7059} 7081}
7060 7082
7061void selinux_complete_init(void) 7083void selinux_complete_init(void)