Commit ef36b9af authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pull-fd' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull vfs fget updates from Al Viro:
 "fget() to fdget() conversions"

* tag 'pull-fd' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  fuse_dev_ioctl(): switch to fdget()
  cgroup_get_from_fd(): switch to fdget_raw()
  bpf: switch to fdget_raw()
  build_mount_idmapped(): switch to fdget()
  kill the last remaining user of proc_ns_fget()
  SVM-SEV: convert the rest of fget() uses to fdget() in there
  convert sgx_set_attribute() to fdget()/fdput()
  convert setns(2) to fdget()/fdput()
parents 61d325dc 4a892c0f
...@@ -892,20 +892,19 @@ static struct miscdevice sgx_dev_provision = { ...@@ -892,20 +892,19 @@ static struct miscdevice sgx_dev_provision = {
int sgx_set_attribute(unsigned long *allowed_attributes, int sgx_set_attribute(unsigned long *allowed_attributes,
unsigned int attribute_fd) unsigned int attribute_fd)
{ {
struct file *file; struct fd f = fdget(attribute_fd);
file = fget(attribute_fd); if (!f.file)
if (!file)
return -EINVAL; return -EINVAL;
if (file->f_op != &sgx_provision_fops) { if (f.file->f_op != &sgx_provision_fops) {
fput(file); fdput(f);
return -EINVAL; return -EINVAL;
} }
*allowed_attributes |= SGX_ATTR_PROVISIONKEY; *allowed_attributes |= SGX_ATTR_PROVISIONKEY;
fput(file); fdput(f);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(sgx_set_attribute); EXPORT_SYMBOL_GPL(sgx_set_attribute);
......
...@@ -1767,18 +1767,20 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd) ...@@ -1767,18 +1767,20 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)
{ {
struct kvm_sev_info *dst_sev = &to_kvm_svm(kvm)->sev_info; struct kvm_sev_info *dst_sev = &to_kvm_svm(kvm)->sev_info;
struct kvm_sev_info *src_sev, *cg_cleanup_sev; struct kvm_sev_info *src_sev, *cg_cleanup_sev;
struct file *source_kvm_file; struct fd f = fdget(source_fd);
struct kvm *source_kvm; struct kvm *source_kvm;
bool charged = false; bool charged = false;
int ret; int ret;
source_kvm_file = fget(source_fd); if (!f.file)
if (!file_is_kvm(source_kvm_file)) { return -EBADF;
if (!file_is_kvm(f.file)) {
ret = -EBADF; ret = -EBADF;
goto out_fput; goto out_fput;
} }
source_kvm = source_kvm_file->private_data; source_kvm = f.file->private_data;
ret = sev_lock_two_vms(kvm, source_kvm); ret = sev_lock_two_vms(kvm, source_kvm);
if (ret) if (ret)
goto out_fput; goto out_fput;
...@@ -1828,8 +1830,7 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd) ...@@ -1828,8 +1830,7 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)
out_unlock: out_unlock:
sev_unlock_two_vms(kvm, source_kvm); sev_unlock_two_vms(kvm, source_kvm);
out_fput: out_fput:
if (source_kvm_file) fdput(f);
fput(source_kvm_file);
return ret; return ret;
} }
...@@ -2046,18 +2047,20 @@ int sev_mem_enc_unregister_region(struct kvm *kvm, ...@@ -2046,18 +2047,20 @@ int sev_mem_enc_unregister_region(struct kvm *kvm,
int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd) int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
{ {
struct file *source_kvm_file; struct fd f = fdget(source_fd);
struct kvm *source_kvm; struct kvm *source_kvm;
struct kvm_sev_info *source_sev, *mirror_sev; struct kvm_sev_info *source_sev, *mirror_sev;
int ret; int ret;
source_kvm_file = fget(source_fd); if (!f.file)
if (!file_is_kvm(source_kvm_file)) { return -EBADF;
if (!file_is_kvm(f.file)) {
ret = -EBADF; ret = -EBADF;
goto e_source_fput; goto e_source_fput;
} }
source_kvm = source_kvm_file->private_data; source_kvm = f.file->private_data;
ret = sev_lock_two_vms(kvm, source_kvm); ret = sev_lock_two_vms(kvm, source_kvm);
if (ret) if (ret)
goto e_source_fput; goto e_source_fput;
...@@ -2103,8 +2106,7 @@ int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd) ...@@ -2103,8 +2106,7 @@ int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
e_unlock: e_unlock:
sev_unlock_two_vms(kvm, source_kvm); sev_unlock_two_vms(kvm, source_kvm);
e_source_fput: e_source_fput:
if (source_kvm_file) fdput(f);
fput(source_kvm_file);
return ret; return ret;
} }
......
...@@ -2257,30 +2257,31 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd, ...@@ -2257,30 +2257,31 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
int res; int res;
int oldfd; int oldfd;
struct fuse_dev *fud = NULL; struct fuse_dev *fud = NULL;
struct fd f;
switch (cmd) { switch (cmd) {
case FUSE_DEV_IOC_CLONE: case FUSE_DEV_IOC_CLONE:
res = -EFAULT; if (get_user(oldfd, (__u32 __user *)arg))
if (!get_user(oldfd, (__u32 __user *)arg)) { return -EFAULT;
struct file *old = fget(oldfd);
f = fdget(oldfd);
res = -EINVAL; if (!f.file)
if (old) { return -EINVAL;
/*
* Check against file->f_op because CUSE /*
* uses the same ioctl handler. * Check against file->f_op because CUSE
*/ * uses the same ioctl handler.
if (old->f_op == file->f_op) */
fud = fuse_get_dev(old); if (f.file->f_op == file->f_op)
fud = fuse_get_dev(f.file);
if (fud) {
mutex_lock(&fuse_mutex); res = -EINVAL;
res = fuse_device_clone(fud->fc, file); if (fud) {
mutex_unlock(&fuse_mutex); mutex_lock(&fuse_mutex);
} res = fuse_device_clone(fud->fc, file);
fput(old); mutex_unlock(&fuse_mutex);
}
} }
fdput(f);
break; break;
default: default:
res = -ENOTTY; res = -ENOTTY;
......
...@@ -4194,7 +4194,7 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize, ...@@ -4194,7 +4194,7 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
int err = 0; int err = 0;
struct ns_common *ns; struct ns_common *ns;
struct user_namespace *mnt_userns; struct user_namespace *mnt_userns;
struct file *file; struct fd f;
if (!((attr->attr_set | attr->attr_clr) & MOUNT_ATTR_IDMAP)) if (!((attr->attr_set | attr->attr_clr) & MOUNT_ATTR_IDMAP))
return 0; return 0;
...@@ -4210,16 +4210,16 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize, ...@@ -4210,16 +4210,16 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
if (attr->userns_fd > INT_MAX) if (attr->userns_fd > INT_MAX)
return -EINVAL; return -EINVAL;
file = fget(attr->userns_fd); f = fdget(attr->userns_fd);
if (!file) if (!f.file)
return -EBADF; return -EBADF;
if (!proc_ns_file(file)) { if (!proc_ns_file(f.file)) {
err = -EINVAL; err = -EINVAL;
goto out_fput; goto out_fput;
} }
ns = get_proc_ns(file_inode(file)); ns = get_proc_ns(file_inode(f.file));
if (ns->ops->type != CLONE_NEWUSER) { if (ns->ops->type != CLONE_NEWUSER) {
err = -EINVAL; err = -EINVAL;
goto out_fput; goto out_fput;
...@@ -4248,7 +4248,7 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize, ...@@ -4248,7 +4248,7 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
kattr->mnt_userns = get_user_ns(mnt_userns); kattr->mnt_userns = get_user_ns(mnt_userns);
out_fput: out_fput:
fput(file); fdput(f);
return err; return err;
} }
......
...@@ -235,24 +235,6 @@ bool proc_ns_file(const struct file *file) ...@@ -235,24 +235,6 @@ bool proc_ns_file(const struct file *file)
return file->f_op == &ns_file_operations; return file->f_op == &ns_file_operations;
} }
struct file *proc_ns_fget(int fd)
{
struct file *file;
file = fget(fd);
if (!file)
return ERR_PTR(-EBADF);
if (file->f_op != &ns_file_operations)
goto out_invalid;
return file;
out_invalid:
fput(file);
return ERR_PTR(-EINVAL);
}
/** /**
* ns_match() - Returns true if current namespace matches dev/ino provided. * ns_match() - Returns true if current namespace matches dev/ino provided.
* @ns: current namespace * @ns: current namespace
......
...@@ -72,7 +72,6 @@ static inline int ns_alloc_inum(struct ns_common *ns) ...@@ -72,7 +72,6 @@ static inline int ns_alloc_inum(struct ns_common *ns)
#define ns_free_inum(ns) proc_free_inum((ns)->inum) #define ns_free_inum(ns) proc_free_inum((ns)->inum)
extern struct file *proc_ns_fget(int fd);
#define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private) #define get_proc_ns(inode) ((struct ns_common *)(inode)->i_private)
extern int ns_get_path(struct path *path, struct task_struct *task, extern int ns_get_path(struct path *path, struct task_struct *task,
const struct proc_ns_operations *ns_ops); const struct proc_ns_operations *ns_ops);
......
...@@ -84,16 +84,13 @@ void bpf_inode_storage_free(struct inode *inode) ...@@ -84,16 +84,13 @@ void bpf_inode_storage_free(struct inode *inode)
static void *bpf_fd_inode_storage_lookup_elem(struct bpf_map *map, void *key) static void *bpf_fd_inode_storage_lookup_elem(struct bpf_map *map, void *key)
{ {
struct bpf_local_storage_data *sdata; struct bpf_local_storage_data *sdata;
struct file *f; struct fd f = fdget_raw(*(int *)key);
int fd;
fd = *(int *)key; if (!f.file)
f = fget_raw(fd);
if (!f)
return ERR_PTR(-EBADF); return ERR_PTR(-EBADF);
sdata = inode_storage_lookup(f->f_inode, map, true); sdata = inode_storage_lookup(file_inode(f.file), map, true);
fput(f); fdput(f);
return sdata ? sdata->data : NULL; return sdata ? sdata->data : NULL;
} }
...@@ -101,22 +98,19 @@ static int bpf_fd_inode_storage_update_elem(struct bpf_map *map, void *key, ...@@ -101,22 +98,19 @@ static int bpf_fd_inode_storage_update_elem(struct bpf_map *map, void *key,
void *value, u64 map_flags) void *value, u64 map_flags)
{ {
struct bpf_local_storage_data *sdata; struct bpf_local_storage_data *sdata;
struct file *f; struct fd f = fdget_raw(*(int *)key);
int fd;
fd = *(int *)key; if (!f.file)
f = fget_raw(fd);
if (!f)
return -EBADF; return -EBADF;
if (!inode_storage_ptr(f->f_inode)) { if (!inode_storage_ptr(file_inode(f.file))) {
fput(f); fdput(f);
return -EBADF; return -EBADF;
} }
sdata = bpf_local_storage_update(f->f_inode, sdata = bpf_local_storage_update(file_inode(f.file),
(struct bpf_local_storage_map *)map, (struct bpf_local_storage_map *)map,
value, map_flags, GFP_ATOMIC); value, map_flags, GFP_ATOMIC);
fput(f); fdput(f);
return PTR_ERR_OR_ZERO(sdata); return PTR_ERR_OR_ZERO(sdata);
} }
...@@ -135,16 +129,14 @@ static int inode_storage_delete(struct inode *inode, struct bpf_map *map) ...@@ -135,16 +129,14 @@ static int inode_storage_delete(struct inode *inode, struct bpf_map *map)
static int bpf_fd_inode_storage_delete_elem(struct bpf_map *map, void *key) static int bpf_fd_inode_storage_delete_elem(struct bpf_map *map, void *key)
{ {
struct file *f; struct fd f = fdget_raw(*(int *)key);
int fd, err; int err;
fd = *(int *)key; if (!f.file)
f = fget_raw(fd);
if (!f)
return -EBADF; return -EBADF;
err = inode_storage_delete(f->f_inode, map); err = inode_storage_delete(file_inode(f.file), map);
fput(f); fdput(f);
return err; return err;
} }
......
...@@ -6856,14 +6856,12 @@ EXPORT_SYMBOL_GPL(cgroup_get_from_path); ...@@ -6856,14 +6856,12 @@ EXPORT_SYMBOL_GPL(cgroup_get_from_path);
struct cgroup *cgroup_v1v2_get_from_fd(int fd) struct cgroup *cgroup_v1v2_get_from_fd(int fd)
{ {
struct cgroup *cgrp; struct cgroup *cgrp;
struct file *f; struct fd f = fdget_raw(fd);
if (!f.file)
f = fget_raw(fd);
if (!f)
return ERR_PTR(-EBADF); return ERR_PTR(-EBADF);
cgrp = cgroup_v1v2_get_from_file(f); cgrp = cgroup_v1v2_get_from_file(f.file);
fput(f); fdput(f);
return cgrp; return cgrp;
} }
......
...@@ -545,21 +545,20 @@ static void commit_nsset(struct nsset *nsset) ...@@ -545,21 +545,20 @@ static void commit_nsset(struct nsset *nsset)
SYSCALL_DEFINE2(setns, int, fd, int, flags) SYSCALL_DEFINE2(setns, int, fd, int, flags)
{ {
struct file *file; struct fd f = fdget(fd);
struct ns_common *ns = NULL; struct ns_common *ns = NULL;
struct nsset nsset = {}; struct nsset nsset = {};
int err = 0; int err = 0;
file = fget(fd); if (!f.file)
if (!file)
return -EBADF; return -EBADF;
if (proc_ns_file(file)) { if (proc_ns_file(f.file)) {
ns = get_proc_ns(file_inode(file)); ns = get_proc_ns(file_inode(f.file));
if (flags && (ns->ops->type != flags)) if (flags && (ns->ops->type != flags))
err = -EINVAL; err = -EINVAL;
flags = ns->ops->type; flags = ns->ops->type;
} else if (!IS_ERR(pidfd_pid(file))) { } else if (!IS_ERR(pidfd_pid(f.file))) {
err = check_setns_flags(flags); err = check_setns_flags(flags);
} else { } else {
err = -EINVAL; err = -EINVAL;
...@@ -571,17 +570,17 @@ SYSCALL_DEFINE2(setns, int, fd, int, flags) ...@@ -571,17 +570,17 @@ SYSCALL_DEFINE2(setns, int, fd, int, flags)
if (err) if (err)
goto out; goto out;
if (proc_ns_file(file)) if (proc_ns_file(f.file))
err = validate_ns(&nsset, ns); err = validate_ns(&nsset, ns);
else else
err = validate_nsset(&nsset, file->private_data); err = validate_nsset(&nsset, f.file->private_data);
if (!err) { if (!err) {
commit_nsset(&nsset); commit_nsset(&nsset);
perf_event_namespaces(current); perf_event_namespaces(current);
} }
put_nsset(&nsset); put_nsset(&nsset);
out: out:
fput(file); fdput(f);
return err; return err;
} }
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/sched/task.h> #include <linux/sched/task.h>
#include <linux/uidgid.h> #include <linux/uidgid.h>
#include <linux/cookie.h> #include <linux/cookie.h>
#include <linux/proc_fs.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/netlink.h> #include <net/netlink.h>
...@@ -676,21 +677,19 @@ EXPORT_SYMBOL_GPL(get_net_ns); ...@@ -676,21 +677,19 @@ EXPORT_SYMBOL_GPL(get_net_ns);
struct net *get_net_ns_by_fd(int fd) struct net *get_net_ns_by_fd(int fd)
{ {
struct file *file; struct fd f = fdget(fd);
struct ns_common *ns; struct net *net = ERR_PTR(-EINVAL);
struct net *net;
file = proc_ns_fget(fd); if (!f.file)
if (IS_ERR(file)) return ERR_PTR(-EBADF);
return ERR_CAST(file);
ns = get_proc_ns(file_inode(file)); if (proc_ns_file(f.file)) {
if (ns->ops == &netns_operations) struct ns_common *ns = get_proc_ns(file_inode(f.file));
net = get_net(container_of(ns, struct net, ns)); if (ns->ops == &netns_operations)
else net = get_net(container_of(ns, struct net, ns));
net = ERR_PTR(-EINVAL); }
fdput(f);
fput(file);
return net; return net;
} }
EXPORT_SYMBOL_GPL(get_net_ns_by_fd); EXPORT_SYMBOL_GPL(get_net_ns_by_fd);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment