aboutsummaryrefslogtreecommitdiff
path: root/fs/nfs
diff options
context:
space:
mode:
authorLinus Torvalds2019-01-05 13:25:58 -0800
committerLinus Torvalds2019-01-05 13:25:58 -0800
commit505b050fdf42097883b2d37b8e796e1f11dbef50 (patch)
tree21f5b43505a5771d13533ac675c785a9bf480fdc /fs/nfs
parent9b286efeb5eb5aaa2712873fc1f928b2f879dbde (diff)
parent718c43038f287e843c2f63d946977de90014cb11 (diff)
Merge branch 'mount.part1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs mount API prep from Al Viro: "Mount API prereqs. Mostly that's LSM mount options cleanups. There are several minor fixes in there, but nothing earth-shattering (leaks on failure exits, mostly)" * 'mount.part1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (27 commits) mount_fs: suppress MAC on MS_SUBMOUNT as well as MS_KERNMOUNT smack: rewrite smack_sb_eat_lsm_opts() smack: get rid of match_token() smack: take the guts of smack_parse_opts_str() into a new helper LSM: new method: ->sb_add_mnt_opt() selinux: rewrite selinux_sb_eat_lsm_opts() selinux: regularize Opt_... names a bit selinux: switch away from match_token() selinux: new helper - selinux_add_opt() LSM: bury struct security_mnt_opts smack: switch to private smack_mnt_opts selinux: switch to private struct selinux_mnt_opts LSM: hide struct security_mnt_opts from any generic code selinux: kill selinux_sb_get_mnt_opts() LSM: turn sb_eat_lsm_opts() into a method nfs_remount(): don't leak, don't ignore LSM options quietly btrfs: sanitize security_mnt_opts use selinux; don't open-code a loop in sb_finish_set_opts() LSM: split ->sb_set_mnt_opts() out of ->sb_kern_mount() new helper: security_sb_eat_lsm_opts() ...
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/internal.h2
-rw-r--r--fs/nfs/super.c34
2 files changed, 11 insertions, 25 deletions
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 7f80f036ebd9..b1e577302518 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -123,7 +123,7 @@ struct nfs_parsed_mount_data {
unsigned short protocol;
} nfs_server;
- struct security_mnt_opts lsm_opts;
+ void *lsm_opts;
struct net *net;
};
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 7c942462d8c6..22ce3c8a2f46 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -929,7 +929,7 @@ static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
data->minorversion = 0;
data->need_mount = true;
data->net = current->nsproxy->net_ns;
- security_init_mnt_opts(&data->lsm_opts);
+ data->lsm_opts = NULL;
}
return data;
}
@@ -1206,7 +1206,7 @@ static int nfs_get_option_ul_bound(substring_t args[], unsigned long *option,
static int nfs_parse_mount_options(char *raw,
struct nfs_parsed_mount_data *mnt)
{
- char *p, *string, *secdata;
+ char *p, *string;
int rc, sloppy = 0, invalid_option = 0;
unsigned short protofamily = AF_UNSPEC;
unsigned short mountfamily = AF_UNSPEC;
@@ -1217,20 +1217,10 @@ static int nfs_parse_mount_options(char *raw,
}
dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw);
- secdata = alloc_secdata();
- if (!secdata)
- goto out_nomem;
-
- rc = security_sb_copy_data(raw, secdata);
+ rc = security_sb_eat_lsm_opts(raw, &mnt->lsm_opts);
if (rc)
goto out_security_failure;
- rc = security_sb_parse_opts_str(secdata, &mnt->lsm_opts);
- if (rc)
- goto out_security_failure;
-
- free_secdata(secdata);
-
while ((p = strsep(&raw, ",")) != NULL) {
substring_t args[MAX_OPT_ARGS];
unsigned long option;
@@ -1682,7 +1672,6 @@ out_nomem:
printk(KERN_INFO "NFS: not enough memory to parse option\n");
return 0;
out_security_failure:
- free_secdata(secdata);
printk(KERN_INFO "NFS: security options invalid: %d\n", rc);
return 0;
}
@@ -2081,14 +2070,9 @@ static int nfs23_validate_mount_data(void *options,
if (data->context[0]){
#ifdef CONFIG_SECURITY_SELINUX
int rc;
- char *opts_str = kmalloc(sizeof(data->context) + 8, GFP_KERNEL);
- if (!opts_str)
- return -ENOMEM;
- strcpy(opts_str, "context=");
data->context[NFS_MAX_CONTEXT_LEN] = '\0';
- strcat(opts_str, &data->context[0]);
- rc = security_sb_parse_opts_str(opts_str, &args->lsm_opts);
- kfree(opts_str);
+ rc = security_add_mnt_opt("context", data->context,
+ strlen(data->context), &args->lsm_opts);
if (rc)
return rc;
#else
@@ -2271,7 +2255,7 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
options->version <= 6))))
return 0;
- data = kzalloc(sizeof(*data), GFP_KERNEL);
+ data = nfs_alloc_parsed_mount_data();
if (data == NULL)
return -ENOMEM;
@@ -2310,8 +2294,10 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
/* compare new mount options with old ones */
error = nfs_compare_remount_data(nfss, data);
+ if (!error)
+ error = security_sb_remount(sb, data->lsm_opts);
out:
- kfree(data);
+ nfs_free_parsed_mount_data(data);
return error;
}
EXPORT_SYMBOL_GPL(nfs_remount);
@@ -2548,7 +2534,7 @@ int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot,
if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL)
kflags |= SECURITY_LSM_NATIVE_LABELS;
- error = security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts,
+ error = security_sb_set_mnt_opts(s, mount_info->parsed->lsm_opts,
kflags, &kflags_out);
if (error)
goto err;