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() ...
This commit is contained in:
@@ -1458,56 +1458,6 @@ out:
|
||||
return root;
|
||||
}
|
||||
|
||||
static int parse_security_options(char *orig_opts,
|
||||
struct security_mnt_opts *sec_opts)
|
||||
{
|
||||
char *secdata = NULL;
|
||||
int ret = 0;
|
||||
|
||||
secdata = alloc_secdata();
|
||||
if (!secdata)
|
||||
return -ENOMEM;
|
||||
ret = security_sb_copy_data(orig_opts, secdata);
|
||||
if (ret) {
|
||||
free_secdata(secdata);
|
||||
return ret;
|
||||
}
|
||||
ret = security_sb_parse_opts_str(secdata, sec_opts);
|
||||
free_secdata(secdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int setup_security_options(struct btrfs_fs_info *fs_info,
|
||||
struct super_block *sb,
|
||||
struct security_mnt_opts *sec_opts)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* Call security_sb_set_mnt_opts() to check whether new sec_opts
|
||||
* is valid.
|
||||
*/
|
||||
ret = security_sb_set_mnt_opts(sb, sec_opts, 0, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
#ifdef CONFIG_SECURITY
|
||||
if (!fs_info->security_opts.num_mnt_opts) {
|
||||
/* first time security setup, copy sec_opts to fs_info */
|
||||
memcpy(&fs_info->security_opts, sec_opts, sizeof(*sec_opts));
|
||||
} else {
|
||||
/*
|
||||
* Since SELinux (the only one supporting security_mnt_opts)
|
||||
* does NOT support changing context during remount/mount of
|
||||
* the same sb, this must be the same or part of the same
|
||||
* security options, just free it.
|
||||
*/
|
||||
security_free_mnt_opts(sec_opts);
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Find a superblock for the given device / mount point.
|
||||
*
|
||||
@@ -1522,16 +1472,15 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
|
||||
struct btrfs_device *device = NULL;
|
||||
struct btrfs_fs_devices *fs_devices = NULL;
|
||||
struct btrfs_fs_info *fs_info = NULL;
|
||||
struct security_mnt_opts new_sec_opts;
|
||||
void *new_sec_opts = NULL;
|
||||
fmode_t mode = FMODE_READ;
|
||||
int error = 0;
|
||||
|
||||
if (!(flags & SB_RDONLY))
|
||||
mode |= FMODE_WRITE;
|
||||
|
||||
security_init_mnt_opts(&new_sec_opts);
|
||||
if (data) {
|
||||
error = parse_security_options(data, &new_sec_opts);
|
||||
error = security_sb_eat_lsm_opts(data, &new_sec_opts);
|
||||
if (error)
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
@@ -1550,7 +1499,6 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
|
||||
|
||||
fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL);
|
||||
fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL);
|
||||
security_init_mnt_opts(&fs_info->security_opts);
|
||||
if (!fs_info->super_copy || !fs_info->super_for_commit) {
|
||||
error = -ENOMEM;
|
||||
goto error_fs_info;
|
||||
@@ -1601,16 +1549,12 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
|
||||
btrfs_sb(s)->bdev_holder = fs_type;
|
||||
error = btrfs_fill_super(s, fs_devices, data);
|
||||
}
|
||||
if (!error)
|
||||
error = security_sb_set_mnt_opts(s, new_sec_opts, 0, NULL);
|
||||
security_free_mnt_opts(&new_sec_opts);
|
||||
if (error) {
|
||||
deactivate_locked_super(s);
|
||||
goto error_sec_opts;
|
||||
}
|
||||
|
||||
fs_info = btrfs_sb(s);
|
||||
error = setup_security_options(fs_info, s, &new_sec_opts);
|
||||
if (error) {
|
||||
deactivate_locked_super(s);
|
||||
goto error_sec_opts;
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
return dget(s->s_root);
|
||||
@@ -1779,18 +1723,14 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
|
||||
btrfs_remount_prepare(fs_info);
|
||||
|
||||
if (data) {
|
||||
struct security_mnt_opts new_sec_opts;
|
||||
void *new_sec_opts = NULL;
|
||||
|
||||
security_init_mnt_opts(&new_sec_opts);
|
||||
ret = parse_security_options(data, &new_sec_opts);
|
||||
ret = security_sb_eat_lsm_opts(data, &new_sec_opts);
|
||||
if (!ret)
|
||||
ret = security_sb_remount(sb, new_sec_opts);
|
||||
security_free_mnt_opts(&new_sec_opts);
|
||||
if (ret)
|
||||
goto restore;
|
||||
ret = setup_security_options(fs_info, sb,
|
||||
&new_sec_opts);
|
||||
if (ret) {
|
||||
security_free_mnt_opts(&new_sec_opts);
|
||||
goto restore;
|
||||
}
|
||||
}
|
||||
|
||||
ret = btrfs_parse_options(fs_info, data, *flags);
|
||||
|
Reference in New Issue
Block a user