Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 204cc0cc authored by Al Viro's avatar Al Viro
Browse files

LSM: hide struct security_mnt_opts from any generic code



Keep void * instead, allocate on demand (in parse_str_opts, at the
moment).  Eventually both selinux and smack will be better off
with private structures with several strings in those, rather than
this "counter and two pointers to dynamically allocated arrays"
ugliness.  This commit allows to do that at leisure, without
disrupting anything outside of given module.

Changes:
	* instead of struct security_mnt_opt use an opaque pointer
initialized to NULL.
	* security_sb_eat_lsm_opts(), security_sb_parse_opts_str() and
security_free_mnt_opts() take it as var argument (i.e. as void **);
call sites are unchanged.
	* security_sb_set_mnt_opts() and security_sb_remount() take
it by value (i.e. as void *).
	* new method: ->sb_free_mnt_opts().  Takes void *, does
whatever freeing that needs to be done.
	* ->sb_set_mnt_opts() and ->sb_remount() might get NULL as
mnt_opts argument, meaning "empty".

Reviewed-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent e3489f89
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -1472,14 +1472,13 @@ 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 = security_sb_eat_lsm_opts(data, &new_sec_opts);
		if (error)
@@ -1551,7 +1550,7 @@ static struct dentry *btrfs_mount_root(struct file_system_type *fs_type,
		error = btrfs_fill_super(s, fs_devices, data);
	}
	if (!error)
		error = security_sb_set_mnt_opts(s, &new_sec_opts, 0, NULL);
		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);
@@ -1724,12 +1723,11 @@ 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 = security_sb_eat_lsm_opts(data, &new_sec_opts);
		if (!ret)
			ret = security_sb_remount(sb, &new_sec_opts);
			ret = security_sb_remount(sb, new_sec_opts);
		security_free_mnt_opts(&new_sec_opts);
		if (ret)
			goto restore;
+4 −5
Original line number Diff line number Diff line
@@ -2299,7 +2299,7 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags,
	int err;
	struct super_block *sb = path->mnt->mnt_sb;
	struct mount *mnt = real_mount(path->mnt);
	struct security_mnt_opts opts;
	void *sec_opts = NULL;

	if (!check_mnt(mnt))
		return -EINVAL;
@@ -2310,14 +2310,13 @@ static int do_remount(struct path *path, int ms_flags, int sb_flags,
	if (!can_change_locked_flags(mnt, mnt_flags))
		return -EPERM;

	security_init_mnt_opts(&opts);
	if (data && !(sb->s_type->fs_flags & FS_BINARY_MOUNTDATA)) {
		err = security_sb_eat_lsm_opts(data, &opts);
		err = security_sb_eat_lsm_opts(data, &sec_opts);
		if (err)
			return err;
	}
	err = security_sb_remount(sb, &opts);
	security_free_mnt_opts(&opts);
	err = security_sb_remount(sb, sec_opts);
	security_free_mnt_opts(&sec_opts);
	if (err)
		return err;

+1 −1
Original line number Diff line number Diff line
@@ -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;
};

+3 −3
Original line number Diff line number Diff line
@@ -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;
}
@@ -2294,7 +2294,7 @@ 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);
		error = security_sb_remount(sb, data->lsm_opts);
out:
	nfs_free_parsed_mount_data(data);
	return error;
@@ -2534,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;
+5 −7
Original line number Diff line number Diff line
@@ -1247,12 +1247,10 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
	struct dentry *root;
	struct super_block *sb;
	int error = -ENOMEM;
	struct security_mnt_opts opts;

	security_init_mnt_opts(&opts);
	void *sec_opts = NULL;

	if (data && !(type->fs_flags & FS_BINARY_MOUNTDATA)) {
		error = security_sb_eat_lsm_opts(data, &opts);
		error = security_sb_eat_lsm_opts(data, &sec_opts);
		if (error)
			return ERR_PTR(error);
	}
@@ -1275,7 +1273,7 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
	smp_wmb();
	sb->s_flags |= SB_BORN;

	error = security_sb_set_mnt_opts(sb, &opts, 0, NULL);
	error = security_sb_set_mnt_opts(sb, sec_opts, 0, NULL);
	if (error)
		goto out_sb;

@@ -1295,13 +1293,13 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data)
		"negative value (%lld)\n", type->name, sb->s_maxbytes);

	up_write(&sb->s_umount);
	security_free_mnt_opts(&opts);
	security_free_mnt_opts(&sec_opts);
	return root;
out_sb:
	dput(root);
	deactivate_locked_super(sb);
out_free_secdata:
	security_free_mnt_opts(&opts);
	security_free_mnt_opts(&sec_opts);
	return ERR_PTR(error);
}

Loading