Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* Filesystem access-by-fd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/fs_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/fs_parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/security.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/anon_inodes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/namei.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <uapi/linux/mount.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * Allow the user to read back any error, warning or informational messages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static ssize_t fscontext_read(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 			      char __user *_buf, size_t len, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	struct fs_context *fc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	struct fc_log *log = fc->log.log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	unsigned int logsize = ARRAY_SIZE(log->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	bool need_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	int index, n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	ret = mutex_lock_interruptible(&fc->uapi_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	if (log->head == log->tail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		mutex_unlock(&fc->uapi_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 		return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	index = log->tail & (logsize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	p = log->buffer[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	need_free = log->need_free & (1 << index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	log->buffer[index] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	log->need_free &= ~(1 << index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	log->tail++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	mutex_unlock(&fc->uapi_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	ret = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	n = strlen(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	if (n > len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	if (copy_to_user(_buf, p, n) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	ret = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	if (need_free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) static int fscontext_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	struct fs_context *fc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (fc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		file->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		put_fs_context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) const struct file_operations fscontext_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	.read		= fscontext_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	.release	= fscontext_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	.llseek		= no_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  * Attach a filesystem context to a file and an fd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) static int fscontext_create_fd(struct fs_context *fc, unsigned int o_flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	int fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	fd = anon_inode_getfd("[fscontext]", &fscontext_fops, fc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			      O_RDWR | o_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		put_fs_context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) static int fscontext_alloc_log(struct fs_context *fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	fc->log.log = kzalloc(sizeof(*fc->log.log), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if (!fc->log.log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	refcount_set(&fc->log.log->usage, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	fc->log.log->owner = fc->fs_type->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * Open a filesystem by name so that it can be configured for mounting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  * We are allowed to specify a container in which the filesystem will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * opened, thereby indicating which namespaces will be used (notably, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * network namespace will be used for network filesystems).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) SYSCALL_DEFINE2(fsopen, const char __user *, _fs_name, unsigned int, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	struct file_system_type *fs_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	struct fs_context *fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	const char *fs_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	if (!ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	if (flags & ~FSOPEN_CLOEXEC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	fs_name = strndup_user(_fs_name, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	if (IS_ERR(fs_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		return PTR_ERR(fs_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	fs_type = get_fs_type(fs_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	kfree(fs_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	if (!fs_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	fc = fs_context_for_mount(fs_type, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	put_filesystem(fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	if (IS_ERR(fc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 		return PTR_ERR(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	fc->phase = FS_CONTEXT_CREATE_PARAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	ret = fscontext_alloc_log(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		goto err_fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	return fscontext_create_fd(fc, flags & FSOPEN_CLOEXEC ? O_CLOEXEC : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) err_fc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	put_fs_context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)  * Pick a superblock into a context for reconfiguration.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) SYSCALL_DEFINE3(fspick, int, dfd, const char __user *, path, unsigned int, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	struct fs_context *fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	struct path target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	unsigned int lookup_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (!ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	if ((flags & ~(FSPICK_CLOEXEC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		       FSPICK_SYMLINK_NOFOLLOW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		       FSPICK_NO_AUTOMOUNT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		       FSPICK_EMPTY_PATH)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	if (flags & FSPICK_SYMLINK_NOFOLLOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 		lookup_flags &= ~LOOKUP_FOLLOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if (flags & FSPICK_NO_AUTOMOUNT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		lookup_flags &= ~LOOKUP_AUTOMOUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	if (flags & FSPICK_EMPTY_PATH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		lookup_flags |= LOOKUP_EMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	ret = user_path_at(dfd, path, lookup_flags, &target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	if (target.mnt->mnt_root != target.dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		goto err_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	fc = fs_context_for_reconfigure(target.dentry, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	if (IS_ERR(fc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		ret = PTR_ERR(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		goto err_path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	fc->phase = FS_CONTEXT_RECONF_PARAMS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	ret = fscontext_alloc_log(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		goto err_fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	path_put(&target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	return fscontext_create_fd(fc, flags & FSPICK_CLOEXEC ? O_CLOEXEC : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) err_fc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	put_fs_context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) err_path:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	path_put(&target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)  * Check the state and apply the configuration.  Note that this function is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * allowed to 'steal' the value by setting param->xxx to NULL before returning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static int vfs_fsconfig_locked(struct fs_context *fc, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 			       struct fs_parameter *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	struct super_block *sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	ret = finish_clean_context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	case FSCONFIG_CMD_CREATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		if (fc->phase != FS_CONTEXT_CREATE_PARAMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		if (!mount_capable(fc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		fc->phase = FS_CONTEXT_CREATING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		ret = vfs_get_tree(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		sb = fc->root->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		ret = security_sb_kern_mount(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		if (unlikely(ret)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			fc_drop_locked(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		up_write(&sb->s_umount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		fc->phase = FS_CONTEXT_AWAITING_MOUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	case FSCONFIG_CMD_RECONFIGURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		if (fc->phase != FS_CONTEXT_RECONF_PARAMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		fc->phase = FS_CONTEXT_RECONFIGURING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 		sb = fc->root->d_sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		if (!ns_capable(sb->s_user_ns, CAP_SYS_ADMIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 			ret = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		down_write(&sb->s_umount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		ret = reconfigure_super(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		up_write(&sb->s_umount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		vfs_clean_context(fc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 		if (fc->phase != FS_CONTEXT_CREATE_PARAMS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		    fc->phase != FS_CONTEXT_RECONF_PARAMS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		return vfs_parse_fs_param(fc, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	fc->phase = FS_CONTEXT_FAILED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)  * sys_fsconfig - Set parameters and trigger actions on a context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)  * @fd: The filesystem context to act upon
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)  * @cmd: The action to take
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)  * @_key: Where appropriate, the parameter key to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)  * @_value: Where appropriate, the parameter value to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)  * @aux: Additional information for the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)  * This system call is used to set parameters on a context, including
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)  * superblock settings, data source and security labelling.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)  * Actions include triggering the creation of a superblock and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)  * reconfiguration of the superblock attached to the specified context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)  * When setting a parameter, @cmd indicates the type of value being proposed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)  * and @_key indicates the parameter to be altered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)  * @_value and @aux are used to specify the value, should a value be required:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)  * (*) fsconfig_set_flag: No value is specified.  The parameter must be boolean
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)  *     in nature.  The key may be prefixed with "no" to invert the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)  *     setting. @_value must be NULL and @aux must be 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)  * (*) fsconfig_set_string: A string value is specified.  The parameter can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)  *     expecting boolean, integer, string or take a path.  A conversion to an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)  *     appropriate type will be attempted (which may include looking up as a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)  *     path).  @_value points to a NUL-terminated string and @aux must be 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)  * (*) fsconfig_set_binary: A binary blob is specified.  @_value points to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)  *     blob and @aux indicates its size.  The parameter must be expecting a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)  *     blob.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)  * (*) fsconfig_set_path: A non-empty path is specified.  The parameter must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)  *     expecting a path object.  @_value points to a NUL-terminated string that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)  *     is the path and @aux is a file descriptor at which to start a relative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)  *     lookup or AT_FDCWD.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)  * (*) fsconfig_set_path_empty: As fsconfig_set_path, but with AT_EMPTY_PATH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)  *     implied.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)  * (*) fsconfig_set_fd: An open file descriptor is specified.  @_value must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)  *     NULL and @aux indicates the file descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) SYSCALL_DEFINE5(fsconfig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		int, fd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 		unsigned int, cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		const char __user *, _key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		const void __user *, _value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		int, aux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	struct fs_context *fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	struct fd f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	int lookup_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	struct fs_parameter param = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 		.type	= fs_value_is_undefined,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	if (fd < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	case FSCONFIG_SET_FLAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		if (!_key || _value || aux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	case FSCONFIG_SET_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		if (!_key || !_value || aux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	case FSCONFIG_SET_BINARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		if (!_key || !_value || aux <= 0 || aux > 1024 * 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	case FSCONFIG_SET_PATH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	case FSCONFIG_SET_PATH_EMPTY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		if (!_key || !_value || (aux != AT_FDCWD && aux < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	case FSCONFIG_SET_FD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		if (!_key || _value || aux < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	case FSCONFIG_CMD_CREATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	case FSCONFIG_CMD_RECONFIGURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		if (_key || _value || aux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	f = fdget(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	if (!f.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		return -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (f.file->f_op != &fscontext_fops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		goto out_f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	fc = f.file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	if (fc->ops == &legacy_fs_context_ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		case FSCONFIG_SET_BINARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		case FSCONFIG_SET_PATH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		case FSCONFIG_SET_PATH_EMPTY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		case FSCONFIG_SET_FD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 			ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 			goto out_f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	if (_key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		param.key = strndup_user(_key, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		if (IS_ERR(param.key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 			ret = PTR_ERR(param.key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 			goto out_f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	case FSCONFIG_SET_FLAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		param.type = fs_value_is_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	case FSCONFIG_SET_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		param.type = fs_value_is_string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 		param.string = strndup_user(_value, 256);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		if (IS_ERR(param.string)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 			ret = PTR_ERR(param.string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 			goto out_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		param.size = strlen(param.string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	case FSCONFIG_SET_BINARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 		param.type = fs_value_is_blob;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		param.size = aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		param.blob = memdup_user_nul(_value, aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		if (IS_ERR(param.blob)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 			ret = PTR_ERR(param.blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 			goto out_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	case FSCONFIG_SET_PATH_EMPTY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 		lookup_flags = LOOKUP_EMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	case FSCONFIG_SET_PATH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 		param.type = fs_value_is_filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		param.name = getname_flags(_value, lookup_flags, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		if (IS_ERR(param.name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 			ret = PTR_ERR(param.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 			goto out_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		param.dirfd = aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		param.size = strlen(param.name->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	case FSCONFIG_SET_FD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 		param.type = fs_value_is_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		ret = -EBADF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		param.file = fget(aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		if (!param.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			goto out_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	ret = mutex_lock_interruptible(&fc->uapi_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		ret = vfs_fsconfig_locked(fc, cmd, &param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		mutex_unlock(&fc->uapi_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	/* Clean up the our record of any value that we obtained from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	 * userspace.  Note that the value may have been stolen by the LSM or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	 * filesystem, in which case the value pointer will have been cleared.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	case FSCONFIG_SET_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	case FSCONFIG_SET_BINARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		kfree(param.string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	case FSCONFIG_SET_PATH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	case FSCONFIG_SET_PATH_EMPTY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 		if (param.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 			putname(param.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	case FSCONFIG_SET_FD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 		if (param.file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 			fput(param.file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) out_key:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	kfree(param.key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) out_f:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	fdput(f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }