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 = {
int sgx_set_attribute(unsigned long *allowed_attributes,
unsigned int attribute_fd)
{
struct file *file;
struct fd f = fdget(attribute_fd);
file = fget(attribute_fd);
if (!file)
if (!f.file)
return -EINVAL;
if (file->f_op != &sgx_provision_fops) {
fput(file);
if (f.file->f_op != &sgx_provision_fops) {
fdput(f);
return -EINVAL;
}
*allowed_attributes |= SGX_ATTR_PROVISIONKEY;
fput(file);
fdput(f);
return 0;
}
EXPORT_SYMBOL_GPL(sgx_set_attribute);
......
......@@ -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 *src_sev, *cg_cleanup_sev;
struct file *source_kvm_file;
struct fd f = fdget(source_fd);
struct kvm *source_kvm;
bool charged = false;
int ret;
source_kvm_file = fget(source_fd);
if (!file_is_kvm(source_kvm_file)) {
if (!f.file)
return -EBADF;
if (!file_is_kvm(f.file)) {
ret = -EBADF;
goto out_fput;
}
source_kvm = source_kvm_file->private_data;
source_kvm = f.file->private_data;
ret = sev_lock_two_vms(kvm, source_kvm);
if (ret)
goto out_fput;
......@@ -1828,8 +1830,7 @@ int sev_vm_move_enc_context_from(struct kvm *kvm, unsigned int source_fd)
out_unlock:
sev_unlock_two_vms(kvm, source_kvm);
out_fput:
if (source_kvm_file)
fput(source_kvm_file);
fdput(f);
return ret;
}
......@@ -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)
{
struct file *source_kvm_file;
struct fd f = fdget(source_fd);
struct kvm *source_kvm;
struct kvm_sev_info *source_sev, *mirror_sev;
int ret;
source_kvm_file = fget(source_fd);
if (!file_is_kvm(source_kvm_file)) {
if (!f.file)
return -EBADF;
if (!file_is_kvm(f.file)) {
ret = -EBADF;
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);
if (ret)
goto e_source_fput;
......@@ -2103,8 +2106,7 @@ int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
e_unlock:
sev_unlock_two_vms(kvm, source_kvm);
e_source_fput:
if (source_kvm_file)
fput(source_kvm_file);
fdput(f);
return ret;
}
......
......@@ -2257,30 +2257,31 @@ static long fuse_dev_ioctl(struct file *file, unsigned int cmd,
int res;
int oldfd;
struct fuse_dev *fud = NULL;
struct fd f;
switch (cmd) {
case FUSE_DEV_IOC_CLONE:
res = -EFAULT;
if (!get_user(oldfd, (__u32 __user *)arg)) {
struct file *old = fget(oldfd);
res = -EINVAL;
if (old) {
/*
* 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 (fud) {
mutex_lock(&fuse_mutex);
res = fuse_device_clone(fud->fc, file);
mutex_unlock(&fuse_mutex);
}
fput(old);
}
if (get_user(oldfd, (__u32 __user *)arg))
return -EFAULT;
f = fdget(oldfd);
if (!f.file)
return -EINVAL;
/*
* Check against file->f_op because CUSE
* uses the same ioctl handler.
*/
if (f.file->f_op == file->f_op)
fud = fuse_get_dev(f.file);
res = -EINVAL;
if (fud) {
mutex_lock(&fuse_mutex);
res = fuse_device_clone(fud->fc, file);
mutex_unlock(&fuse_mutex);
}
fdput(f);
break;
default:
res = -ENOTTY;
......
......@@ -4194,7 +4194,7 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
int err = 0;
struct ns_common *ns;
struct user_namespace *mnt_userns;
struct file *file;
struct fd f;
if (!((attr->attr_set | attr->attr_clr) & MOUNT_ATTR_IDMAP))
return 0;
......@@ -4210,16 +4210,16 @@ static int build_mount_idmapped(const struct mount_attr *attr, size_t usize,
if (attr->userns_fd > INT_MAX)
return -EINVAL;
file = fget(attr->userns_fd);
if (!file)
f = fdget(attr->userns_fd);
if (!f.file)
return -EBADF;
if (!proc_ns_file(file)) {
if (!proc_ns_file(f.file)) {
err = -EINVAL;
goto out_fput;
}
ns = get_proc_ns(file_inode(file));
ns = get_proc_ns(file_inode(f.file));
if (ns->ops->type != CLONE_NEWUSER) {
err = -EINVAL;
goto out_fput;
......@@ -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);
out_fput:
fput(file);
fdput(f);
return err;
}
......
......@@ -235,24 +235,6 @@ bool proc_ns_file(const struct file *file)
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: current namespace
......
......@@ -72,7 +72,6 @@ static inline int ns_alloc_inum(struct ns_common *ns)
#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)
extern int ns_get_path(struct path *path, struct task_struct *task,
const struct proc_ns_operations *ns_ops);
......
......@@ -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)
{
struct bpf_local_storage_data *sdata;
struct file *f;
int fd;
struct fd f = fdget_raw(*(int *)key);
fd = *(int *)key;
f = fget_raw(fd);
if (!f)
if (!f.file)
return ERR_PTR(-EBADF);
sdata = inode_storage_lookup(f->f_inode, map, true);
fput(f);
sdata = inode_storage_lookup(file_inode(f.file), map, true);
fdput(f);
return sdata ? sdata->data : NULL;
}
......@@ -101,22 +98,19 @@ static int bpf_fd_inode_storage_update_elem(struct bpf_map *map, void *key,
void *value, u64 map_flags)
{
struct bpf_local_storage_data *sdata;
struct file *f;
int fd;
struct fd f = fdget_raw(*(int *)key);
fd = *(int *)key;
f = fget_raw(fd);
if (!f)
if (!f.file)
return -EBADF;
if (!inode_storage_ptr(f->f_inode)) {
fput(f);
if (!inode_storage_ptr(file_inode(f.file))) {
fdput(f);
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,
value, map_flags, GFP_ATOMIC);
fput(f);
fdput(f);
return PTR_ERR_OR_ZERO(sdata);
}
......@@ -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)
{
struct file *f;
int fd, err;
struct fd f = fdget_raw(*(int *)key);
int err;
fd = *(int *)key;
f = fget_raw(fd);
if (!f)
if (!f.file)
return -EBADF;
err = inode_storage_delete(f->f_inode, map);
fput(f);
err = inode_storage_delete(file_inode(f.file), map);
fdput(f);
return err;
}
......
......@@ -6856,14 +6856,12 @@ EXPORT_SYMBOL_GPL(cgroup_get_from_path);
struct cgroup *cgroup_v1v2_get_from_fd(int fd)
{
struct cgroup *cgrp;
struct file *f;
f = fget_raw(fd);
if (!f)
struct fd f = fdget_raw(fd);
if (!f.file)
return ERR_PTR(-EBADF);
cgrp = cgroup_v1v2_get_from_file(f);
fput(f);
cgrp = cgroup_v1v2_get_from_file(f.file);
fdput(f);
return cgrp;
}
......
......@@ -545,21 +545,20 @@ static void commit_nsset(struct nsset *nsset)
SYSCALL_DEFINE2(setns, int, fd, int, flags)
{
struct file *file;
struct fd f = fdget(fd);
struct ns_common *ns = NULL;
struct nsset nsset = {};
int err = 0;
file = fget(fd);
if (!file)
if (!f.file)
return -EBADF;
if (proc_ns_file(file)) {
ns = get_proc_ns(file_inode(file));
if (proc_ns_file(f.file)) {
ns = get_proc_ns(file_inode(f.file));
if (flags && (ns->ops->type != flags))
err = -EINVAL;
flags = ns->ops->type;
} else if (!IS_ERR(pidfd_pid(file))) {
} else if (!IS_ERR(pidfd_pid(f.file))) {
err = check_setns_flags(flags);
} else {
err = -EINVAL;
......@@ -571,17 +570,17 @@ SYSCALL_DEFINE2(setns, int, fd, int, flags)
if (err)
goto out;
if (proc_ns_file(file))
if (proc_ns_file(f.file))
err = validate_ns(&nsset, ns);
else
err = validate_nsset(&nsset, file->private_data);
err = validate_nsset(&nsset, f.file->private_data);
if (!err) {
commit_nsset(&nsset);
perf_event_namespaces(current);
}
put_nsset(&nsset);
out:
fput(file);
fdput(f);
return err;
}
......
......@@ -20,6 +20,7 @@
#include <linux/sched/task.h>
#include <linux/uidgid.h>
#include <linux/cookie.h>
#include <linux/proc_fs.h>
#include <net/sock.h>
#include <net/netlink.h>
......@@ -676,21 +677,19 @@ EXPORT_SYMBOL_GPL(get_net_ns);
struct net *get_net_ns_by_fd(int fd)
{
struct file *file;
struct ns_common *ns;
struct net *net;
struct fd f = fdget(fd);
struct net *net = ERR_PTR(-EINVAL);
file = proc_ns_fget(fd);
if (IS_ERR(file))
return ERR_CAST(file);
if (!f.file)
return ERR_PTR(-EBADF);
ns = get_proc_ns(file_inode(file));
if (ns->ops == &netns_operations)
net = get_net(container_of(ns, struct net, ns));
else
net = ERR_PTR(-EINVAL);
if (proc_ns_file(f.file)) {
struct ns_common *ns = get_proc_ns(file_inode(f.file));
if (ns->ops == &netns_operations)
net = get_net(container_of(ns, struct net, ns));
}
fdput(f);
fput(file);
return net;
}
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