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>
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ba229d4..ba3e291 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2812,39 +2812,22 @@ static int selinux_sb_copy_data(char *orig, char *copy)
 	return rc;
 }
 
-static int selinux_sb_remount(struct super_block *sb, void *data)
+static int selinux_sb_remount(struct super_block *sb,
+			      struct security_mnt_opts *opts)
 {
-	int rc, i, *flags;
-	struct security_mnt_opts opts;
-	char *secdata, **mount_options;
+	int i, *flags;
+	char **mount_options;
 	struct superblock_security_struct *sbsec = sb->s_security;
 
 	if (!(sbsec->flags & SE_SBINITIALIZED))
 		return 0;
 
-	if (!data)
-		return 0;
+	mount_options = opts->mnt_opts;
+	flags = opts->mnt_opts_flags;
 
-	if (sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)
-		return 0;
-
-	security_init_mnt_opts(&opts);
-	secdata = alloc_secdata();
-	if (!secdata)
-		return -ENOMEM;
-	rc = selinux_sb_copy_data(data, secdata);
-	if (rc)
-		goto out_free_secdata;
-
-	rc = selinux_parse_opts_str(secdata, &opts);
-	if (rc)
-		goto out_free_secdata;
-
-	mount_options = opts.mnt_opts;
-	flags = opts.mnt_opts_flags;
-
-	for (i = 0; i < opts.num_mnt_opts; i++) {
+	for (i = 0; i < opts->num_mnt_opts; i++) {
 		u32 sid;
+		int rc;
 
 		if (flags[i] == SBLABEL_MNT)
 			continue;
@@ -2855,9 +2838,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
 			pr_warn("SELinux: security_context_str_to_sid"
 			       "(%s) failed for (dev %s, type %s) errno=%d\n",
 			       mount_options[i], sb->s_id, sb->s_type->name, rc);
-			goto out_free_opts;
+			return rc;
 		}
-		rc = -EINVAL;
 		switch (flags[i]) {
 		case FSCONTEXT_MNT:
 			if (bad_option(sbsec, FSCONTEXT_MNT, sbsec->sid, sid))
@@ -2880,21 +2862,16 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
 				goto out_bad_option;
 			break;
 		default:
-			goto out_free_opts;
+			return -EINVAL;
 		}
 	}
+	return 0;
 
-	rc = 0;
-out_free_opts:
-	security_free_mnt_opts(&opts);
-out_free_secdata:
-	free_secdata(secdata);
-	return rc;
 out_bad_option:
 	pr_warn("SELinux: unable to change security options "
 	       "during remount (dev %s, type=%s)\n", sb->s_id,
 	       sb->s_type->name);
-	goto out_free_opts;
+	return -EINVAL;
 }
 
 static int selinux_sb_kern_mount(struct super_block *sb, int flags,