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

Pull 'struct fd' class updates from Al Viro:
 "The bulk of struct fd memory safety stuff

  Making sure that struct fd instances are destroyed in the same scope
  where they'd been created, getting rid of reassignments and passing
  them by reference, converting to CLASS(fd{,_pos,_raw}).

  We are getting very close to having the memory safety of that stuff
  trivial to verify"

* tag 'pull-fd' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (28 commits)
  deal with the last remaing boolean uses of fd_file()
  css_set_fork(): switch to CLASS(fd_raw, ...)
  memcg_write_event_control(): switch to CLASS(fd)
  assorted variants of irqfd setup: convert to CLASS(fd)
  do_pollfd(): convert to CLASS(fd)
  convert do_select()
  convert vfs_dedupe_file_range().
  convert cifs_ioctl_copychunk()
  convert media_request_get_by_fd()
  convert spu_run(2)
  switch spufs_calls_{get,put}() to CLASS() use
  convert cachestat(2)
  convert do_preadv()/do_pwritev()
  fdget(), more trivial conversions
  fdget(), trivial conversions
  privcmd_ioeventfd_assign(): don't open-code eventfd_ctx_fdget()
  o2hb_region_dev_store(): avoid goto around fdget()/fdput()
  introduce "fd_pos" class, convert fdget_pos() users to it.
  fdget_raw() users: switch to CLASS(fd_raw)
  convert vmsplice() to CLASS(fd)
  ...
This commit is contained in:
Linus Torvalds
2024-11-18 12:24:06 -08:00
77 changed files with 750 additions and 1394 deletions

View File

@@ -152,7 +152,7 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
long __user *, basep)
{
int error;
struct fd arg = fdget_pos(fd);
CLASS(fd_pos, arg)(fd);
struct osf_dirent_callback buf = {
.ctx.actor = osf_filldir,
.dirent = dirent,
@@ -160,7 +160,7 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
.count = count
};
if (!fd_file(arg))
if (fd_empty(arg))
return -EBADF;
error = iterate_dir(fd_file(arg), &buf.ctx);
@@ -169,7 +169,6 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
if (count != buf.count)
error = count - buf.count;
fdput_pos(arg);
return error;
}

View File

@@ -235,12 +235,12 @@ asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
unsigned long arg)
{
void __user *argp = (void __user *)arg;
struct fd f = fdget_raw(fd);
CLASS(fd_raw, f)(fd);
struct flock64 flock;
long err = -EBADF;
long err;
if (!fd_file(f))
goto out;
if (fd_empty(f))
return -EBADF;
switch (cmd) {
case F_GETLK64:
@@ -271,8 +271,6 @@ asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
err = sys_fcntl64(fd, cmd, arg);
break;
}
fdput(f);
out:
return err;
}

View File

@@ -115,10 +115,9 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
struct iommu_table_group *table_group;
long i;
struct kvmppc_spapr_tce_iommu_table *stit;
struct fd f;
CLASS(fd, f)(tablefd);
f = fdget(tablefd);
if (!fd_file(f))
if (fd_empty(f))
return -EBADF;
rcu_read_lock();
@@ -130,16 +129,12 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
}
rcu_read_unlock();
if (!found) {
fdput(f);
if (!found)
return -EINVAL;
}
table_group = iommu_group_get_iommudata(grp);
if (WARN_ON(!table_group)) {
fdput(f);
if (WARN_ON(!table_group))
return -EFAULT;
}
for (i = 0; i < IOMMU_TABLE_GROUP_MAX_TABLES; ++i) {
struct iommu_table *tbltmp = table_group->tables[i];
@@ -160,10 +155,8 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
break;
}
}
if (!tbl) {
fdput(f);
if (!tbl)
return -EINVAL;
}
rcu_read_lock();
list_for_each_entry_rcu(stit, &stt->iommu_tables, next) {
@@ -174,7 +167,6 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
/* stit is being destroyed */
iommu_tce_table_put(tbl);
rcu_read_unlock();
fdput(f);
return -ENOTTY;
}
/*
@@ -182,7 +174,6 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
* its KVM reference counter and can return.
*/
rcu_read_unlock();
fdput(f);
return 0;
}
rcu_read_unlock();
@@ -190,7 +181,6 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
stit = kzalloc(sizeof(*stit), GFP_KERNEL);
if (!stit) {
iommu_tce_table_put(tbl);
fdput(f);
return -ENOMEM;
}
@@ -199,7 +189,6 @@ long kvm_spapr_tce_attach_iommu_group(struct kvm *kvm, int tablefd,
list_add_rcu(&stit->next, &stt->iommu_tables);
fdput(f);
return 0;
}

View File

@@ -1933,12 +1933,11 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
#endif
#ifdef CONFIG_KVM_MPIC
case KVM_CAP_IRQ_MPIC: {
struct fd f;
CLASS(fd, f)(cap->args[0]);
struct kvm_device *dev;
r = -EBADF;
f = fdget(cap->args[0]);
if (!fd_file(f))
if (fd_empty(f))
break;
r = -EPERM;
@@ -1946,18 +1945,16 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
if (dev)
r = kvmppc_mpic_connect_vcpu(dev, vcpu, cap->args[1]);
fdput(f);
break;
}
#endif
#ifdef CONFIG_KVM_XICS
case KVM_CAP_IRQ_XICS: {
struct fd f;
CLASS(fd, f)(cap->args[0]);
struct kvm_device *dev;
r = -EBADF;
f = fdget(cap->args[0]);
if (!fd_file(f))
if (fd_empty(f))
break;
r = -EPERM;
@@ -1968,34 +1965,27 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
else
r = kvmppc_xics_connect_vcpu(dev, vcpu, cap->args[1]);
}
fdput(f);
break;
}
#endif /* CONFIG_KVM_XICS */
#ifdef CONFIG_KVM_XIVE
case KVM_CAP_PPC_IRQ_XIVE: {
struct fd f;
CLASS(fd, f)(cap->args[0]);
struct kvm_device *dev;
r = -EBADF;
f = fdget(cap->args[0]);
if (!fd_file(f))
if (fd_empty(f))
break;
r = -ENXIO;
if (!xive_enabled()) {
fdput(f);
if (!xive_enabled())
break;
}
r = -EPERM;
dev = kvm_device_from_filp(fd_file(f));
if (dev)
r = kvmppc_xive_native_connect_vcpu(dev, vcpu,
cap->args[1]);
fdput(f);
break;
}
#endif /* CONFIG_KVM_XIVE */

View File

@@ -36,6 +36,9 @@ static inline struct spufs_calls *spufs_calls_get(void)
static inline void spufs_calls_put(struct spufs_calls *calls)
{
if (!calls)
return;
BUG_ON(calls != spufs_calls);
/* we don't need to rcu this, as we hold a reference to the module */
@@ -53,82 +56,55 @@ static inline void spufs_calls_put(struct spufs_calls *calls) { }
#endif /* CONFIG_SPU_FS_MODULE */
DEFINE_CLASS(spufs_calls, struct spufs_calls *, spufs_calls_put(_T), spufs_calls_get(), void)
SYSCALL_DEFINE4(spu_create, const char __user *, name, unsigned int, flags,
umode_t, mode, int, neighbor_fd)
{
long ret;
struct spufs_calls *calls;
calls = spufs_calls_get();
CLASS(spufs_calls, calls)();
if (!calls)
return -ENOSYS;
if (flags & SPU_CREATE_AFFINITY_SPU) {
struct fd neighbor = fdget(neighbor_fd);
ret = -EBADF;
if (fd_file(neighbor)) {
ret = calls->create_thread(name, flags, mode, fd_file(neighbor));
fdput(neighbor);
}
} else
ret = calls->create_thread(name, flags, mode, NULL);
spufs_calls_put(calls);
return ret;
CLASS(fd, neighbor)(neighbor_fd);
if (fd_empty(neighbor))
return -EBADF;
return calls->create_thread(name, flags, mode, fd_file(neighbor));
} else {
return calls->create_thread(name, flags, mode, NULL);
}
}
SYSCALL_DEFINE3(spu_run,int, fd, __u32 __user *, unpc, __u32 __user *, ustatus)
{
long ret;
struct fd arg;
struct spufs_calls *calls;
calls = spufs_calls_get();
CLASS(spufs_calls, calls)();
if (!calls)
return -ENOSYS;
ret = -EBADF;
arg = fdget(fd);
if (fd_file(arg)) {
ret = calls->spu_run(fd_file(arg), unpc, ustatus);
fdput(arg);
}
CLASS(fd, arg)(fd);
if (fd_empty(arg))
return -EBADF;
spufs_calls_put(calls);
return ret;
return calls->spu_run(fd_file(arg), unpc, ustatus);
}
#ifdef CONFIG_COREDUMP
int elf_coredump_extra_notes_size(void)
{
struct spufs_calls *calls;
int ret;
calls = spufs_calls_get();
CLASS(spufs_calls, calls)();
if (!calls)
return 0;
ret = calls->coredump_extra_notes_size();
spufs_calls_put(calls);
return ret;
return calls->coredump_extra_notes_size();
}
int elf_coredump_extra_notes_write(struct coredump_params *cprm)
{
struct spufs_calls *calls;
int ret;
calls = spufs_calls_get();
CLASS(spufs_calls, calls)();
if (!calls)
return 0;
ret = calls->coredump_extra_notes_write(cprm);
spufs_calls_put(calls);
return ret;
return calls->coredump_extra_notes_write(cprm);
}
#endif

View File

@@ -901,19 +901,15 @@ static struct miscdevice sgx_dev_provision = {
int sgx_set_attribute(unsigned long *allowed_attributes,
unsigned int attribute_fd)
{
struct fd f = fdget(attribute_fd);
CLASS(fd, f)(attribute_fd);
if (!fd_file(f))
if (fd_empty(f))
return -EINVAL;
if (fd_file(f)->f_op != &sgx_provision_fops) {
fdput(f);
if (fd_file(f)->f_op != &sgx_provision_fops)
return -EINVAL;
}
*allowed_attributes |= SGX_ATTR_PROVISIONKEY;
fdput(f);
return 0;
}
EXPORT_SYMBOL_GPL(sgx_set_attribute);

View File

@@ -533,17 +533,12 @@ static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error)
static int __sev_issue_cmd(int fd, int id, void *data, int *error)
{
struct fd f;
int ret;
CLASS(fd, f)(fd);
f = fdget(fd);
if (!fd_file(f))
if (fd_empty(f))
return -EBADF;
ret = sev_issue_cmd_external_user(fd_file(f), id, data, error);
fdput(f);
return ret;
return sev_issue_cmd_external_user(fd_file(f), id, data, error);
}
static int sev_issue_cmd(struct kvm *kvm, int id, void *data, int *error)
@@ -2076,23 +2071,21 @@ 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 fd f = fdget(source_fd);
CLASS(fd, f)(source_fd);
struct kvm *source_kvm;
bool charged = false;
int ret;
if (!fd_file(f))
if (fd_empty(f))
return -EBADF;
if (!file_is_kvm(fd_file(f))) {
ret = -EBADF;
goto out_fput;
}
if (!file_is_kvm(fd_file(f)))
return -EBADF;
source_kvm = fd_file(f)->private_data;
ret = sev_lock_two_vms(kvm, source_kvm);
if (ret)
goto out_fput;
return ret;
if (kvm->arch.vm_type != source_kvm->arch.vm_type ||
sev_guest(kvm) || !sev_guest(source_kvm)) {
@@ -2139,8 +2132,6 @@ out_dst_cgroup:
cg_cleanup_sev->misc_cg = NULL;
out_unlock:
sev_unlock_two_vms(kvm, source_kvm);
out_fput:
fdput(f);
return ret;
}
@@ -2801,23 +2792,21 @@ failed:
int sev_vm_copy_enc_context_from(struct kvm *kvm, unsigned int source_fd)
{
struct fd f = fdget(source_fd);
CLASS(fd, f)(source_fd);
struct kvm *source_kvm;
struct kvm_sev_info *source_sev, *mirror_sev;
int ret;
if (!fd_file(f))
if (fd_empty(f))
return -EBADF;
if (!file_is_kvm(fd_file(f))) {
ret = -EBADF;
goto e_source_fput;
}
if (!file_is_kvm(fd_file(f)))
return -EBADF;
source_kvm = fd_file(f)->private_data;
ret = sev_lock_two_vms(kvm, source_kvm);
if (ret)
goto e_source_fput;
return ret;
/*
* Mirrors of mirrors should work, but let's not get silly. Also
@@ -2860,8 +2849,6 @@ 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:
fdput(f);
return ret;
}

View File

@@ -35,21 +35,19 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
int fd,
int32_t priority)
{
struct fd f = fdget(fd);
CLASS(fd, f)(fd);
struct amdgpu_fpriv *fpriv;
struct amdgpu_ctx_mgr *mgr;
struct amdgpu_ctx *ctx;
uint32_t id;
int r;
if (!fd_file(f))
if (fd_empty(f))
return -EINVAL;
r = amdgpu_file_to_fpriv(fd_file(f), &fpriv);
if (r) {
fdput(f);
if (r)
return r;
}
mgr = &fpriv->ctx_mgr;
mutex_lock(&mgr->lock);
@@ -57,7 +55,6 @@ static int amdgpu_sched_process_priority_override(struct amdgpu_device *adev,
amdgpu_ctx_priority_override(ctx, priority);
mutex_unlock(&mgr->lock);
fdput(f);
return 0;
}
@@ -66,31 +63,25 @@ static int amdgpu_sched_context_priority_override(struct amdgpu_device *adev,
unsigned ctx_id,
int32_t priority)
{
struct fd f = fdget(fd);
CLASS(fd, f)(fd);
struct amdgpu_fpriv *fpriv;
struct amdgpu_ctx *ctx;
int r;
if (!fd_file(f))
if (fd_empty(f))
return -EINVAL;
r = amdgpu_file_to_fpriv(fd_file(f), &fpriv);
if (r) {
fdput(f);
if (r)
return r;
}
ctx = amdgpu_ctx_get(fpriv, ctx_id);
if (!ctx) {
fdput(f);
if (!ctx)
return -EINVAL;
}
amdgpu_ctx_priority_override(ctx, priority);
amdgpu_ctx_put(ctx);
fdput(f);
return 0;
}

View File

@@ -712,16 +712,14 @@ static int drm_syncobj_fd_to_handle(struct drm_file *file_private,
int fd, u32 *handle)
{
struct drm_syncobj *syncobj;
struct fd f = fdget(fd);
CLASS(fd, f)(fd);
int ret;
if (!fd_file(f))
if (fd_empty(f))
return -EINVAL;
if (fd_file(f)->f_op != &drm_syncobj_file_fops) {
fdput(f);
if (fd_file(f)->f_op != &drm_syncobj_file_fops)
return -EINVAL;
}
/* take a reference to put in the idr */
syncobj = fd_file(f)->private_data;
@@ -739,7 +737,6 @@ static int drm_syncobj_fd_to_handle(struct drm_file *file_private,
} else
drm_syncobj_put(syncobj);
fdput(f);
return ret;
}

View File

@@ -1615,7 +1615,6 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
struct ucma_event *uevent, *tmp;
struct ucma_context *ctx;
LIST_HEAD(event_list);
struct fd f;
struct ucma_file *cur_file;
int ret = 0;
@@ -1623,21 +1622,17 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
return -EFAULT;
/* Get current fd to protect against it being closed */
f = fdget(cmd.fd);
if (!fd_file(f))
CLASS(fd, f)(cmd.fd);
if (fd_empty(f))
return -ENOENT;
if (fd_file(f)->f_op != &ucma_fops) {
ret = -EINVAL;
goto file_put;
}
if (fd_file(f)->f_op != &ucma_fops)
return -EINVAL;
cur_file = fd_file(f)->private_data;
/* Validate current fd and prevent destruction of id. */
ctx = ucma_get_ctx(cur_file, cmd.id);
if (IS_ERR(ctx)) {
ret = PTR_ERR(ctx);
goto file_put;
}
if (IS_ERR(ctx))
return PTR_ERR(ctx);
rdma_lock_handler(ctx->cm_id);
/*
@@ -1678,8 +1673,6 @@ static ssize_t ucma_migrate_id(struct ucma_file *new_file,
err_unlock:
rdma_unlock_handler(ctx->cm_id);
ucma_put_ctx(ctx);
file_put:
fdput(f);
return ret;
}

View File

@@ -584,7 +584,7 @@ static int ib_uverbs_open_xrcd(struct uverbs_attr_bundle *attrs)
if (cmd.fd != -1) {
/* search for file descriptor */
f = fdget(cmd.fd);
if (!fd_file(f)) {
if (fd_empty(f)) {
ret = -EBADF;
goto err_tree_mutex_unlock;
}
@@ -632,8 +632,7 @@ static int ib_uverbs_open_xrcd(struct uverbs_attr_bundle *attrs)
atomic_inc(&xrcd->usecnt);
}
if (fd_file(f))
fdput(f);
fdput(f);
mutex_unlock(&ibudev->xrcd_tree_mutex);
uobj_finalize_uobj_create(&obj->uobject, attrs);
@@ -648,8 +647,7 @@ err:
uobj_alloc_abort(&obj->uobject, attrs);
err_tree_mutex_unlock:
if (fd_file(f))
fdput(f);
fdput(f);
mutex_unlock(&ibudev->xrcd_tree_mutex);

View File

@@ -246,22 +246,21 @@ static const struct file_operations request_fops = {
struct media_request *
media_request_get_by_fd(struct media_device *mdev, int request_fd)
{
struct fd f;
struct media_request *req;
if (!mdev || !mdev->ops ||
!mdev->ops->req_validate || !mdev->ops->req_queue)
return ERR_PTR(-EBADR);
f = fdget(request_fd);
if (!fd_file(f))
goto err_no_req_fd;
CLASS(fd, f)(request_fd);
if (fd_empty(f))
goto err;
if (fd_file(f)->f_op != &request_fops)
goto err_fput;
goto err;
req = fd_file(f)->private_data;
if (req->mdev != mdev)
goto err_fput;
goto err;
/*
* Note: as long as someone has an open filehandle of the request,
@@ -272,14 +271,9 @@ media_request_get_by_fd(struct media_device *mdev, int request_fd)
* before media_request_get() is called.
*/
media_request_get(req);
fdput(f);
return req;
err_fput:
fdput(f);
err_no_req_fd:
err:
dev_dbg(mdev->dev, "cannot find request_fd %d\n", request_fd);
return ERR_PTR(-EINVAL);
}

View File

@@ -815,28 +815,23 @@ void __exit lirc_dev_exit(void)
struct rc_dev *rc_dev_get_from_fd(int fd, bool write)
{
struct fd f = fdget(fd);
CLASS(fd, f)(fd);
struct lirc_fh *fh;
struct rc_dev *dev;
if (!fd_file(f))
if (fd_empty(f))
return ERR_PTR(-EBADF);
if (fd_file(f)->f_op != &lirc_fops) {
fdput(f);
if (fd_file(f)->f_op != &lirc_fops)
return ERR_PTR(-EINVAL);
}
if (write && !(fd_file(f)->f_mode & FMODE_WRITE)) {
fdput(f);
if (write && !(fd_file(f)->f_mode & FMODE_WRITE))
return ERR_PTR(-EPERM);
}
fh = fd_file(f)->private_data;
dev = fh->rc;
get_device(&dev->dev);
fdput(f);
return dev;
}

View File

@@ -104,15 +104,14 @@ static int vfio_group_ioctl_set_container(struct vfio_group *group,
{
struct vfio_container *container;
struct iommufd_ctx *iommufd;
struct fd f;
int ret;
int fd;
if (get_user(fd, arg))
return -EFAULT;
f = fdget(fd);
if (!fd_file(f))
CLASS(fd, f)(fd);
if (fd_empty(f))
return -EBADF;
mutex_lock(&group->group_lock);
@@ -153,7 +152,6 @@ static int vfio_group_ioctl_set_container(struct vfio_group *group,
out_unlock:
mutex_unlock(&group->group_lock);
fdput(f);
return ret;
}

View File

@@ -113,7 +113,6 @@ int vfio_virqfd_enable(void *opaque,
void (*thread)(void *, void *),
void *data, struct virqfd **pvirqfd, int fd)
{
struct fd irqfd;
struct eventfd_ctx *ctx;
struct virqfd *virqfd;
int ret = 0;
@@ -133,8 +132,8 @@ int vfio_virqfd_enable(void *opaque,
INIT_WORK(&virqfd->inject, virqfd_inject);
INIT_WORK(&virqfd->flush_inject, virqfd_flush_inject);
irqfd = fdget(fd);
if (!fd_file(irqfd)) {
CLASS(fd, irqfd)(fd);
if (fd_empty(irqfd)) {
ret = -EBADF;
goto err_fd;
}
@@ -142,7 +141,7 @@ int vfio_virqfd_enable(void *opaque,
ctx = eventfd_ctx_fileget(fd_file(irqfd));
if (IS_ERR(ctx)) {
ret = PTR_ERR(ctx);
goto err_ctx;
goto err_fd;
}
virqfd->eventfd = ctx;
@@ -181,18 +180,9 @@ int vfio_virqfd_enable(void *opaque,
if ((!handler || handler(opaque, data)) && thread)
schedule_work(&virqfd->inject);
}
/*
* Do not drop the file until the irqfd is fully initialized,
* otherwise we might race against the EPOLLHUP.
*/
fdput(irqfd);
return 0;
err_busy:
eventfd_ctx_put(ctx);
err_ctx:
fdput(irqfd);
err_fd:
kfree(virqfd);

View File

@@ -112,7 +112,6 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
struct eventfd_ctx *eventfd = NULL;
struct hsm_irqfd *irqfd, *tmp;
__poll_t events;
struct fd f;
int ret = 0;
irqfd = kzalloc(sizeof(*irqfd), GFP_KERNEL);
@@ -124,8 +123,8 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
INIT_LIST_HEAD(&irqfd->list);
INIT_WORK(&irqfd->shutdown, hsm_irqfd_shutdown_work);
f = fdget(args->fd);
if (!fd_file(f)) {
CLASS(fd, f)(args->fd);
if (fd_empty(f)) {
ret = -EBADF;
goto out;
}
@@ -133,7 +132,7 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
eventfd = eventfd_ctx_fileget(fd_file(f));
if (IS_ERR(eventfd)) {
ret = PTR_ERR(eventfd);
goto fail;
goto out;
}
irqfd->eventfd = eventfd;
@@ -162,13 +161,9 @@ static int acrn_irqfd_assign(struct acrn_vm *vm, struct acrn_irqfd *args)
if (events & EPOLLIN)
acrn_irqfd_inject(irqfd);
fdput(f);
return 0;
fail:
if (eventfd && !IS_ERR(eventfd))
eventfd_ctx_put(eventfd);
fdput(f);
eventfd_ctx_put(eventfd);
out:
kfree(irqfd);
return ret;

View File

@@ -965,10 +965,11 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
struct privcmd_kernel_irqfd *kirqfd, *tmp;
unsigned long flags;
__poll_t events;
struct fd f;
void *dm_op;
int ret, idx;
CLASS(fd, f)(irqfd->fd);
kirqfd = kzalloc(sizeof(*kirqfd) + irqfd->size, GFP_KERNEL);
if (!kirqfd)
return -ENOMEM;
@@ -984,8 +985,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
kirqfd->dom = irqfd->dom;
INIT_WORK(&kirqfd->shutdown, irqfd_shutdown);
f = fdget(irqfd->fd);
if (!fd_file(f)) {
if (fd_empty(f)) {
ret = -EBADF;
goto error_kfree;
}
@@ -993,7 +993,7 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
kirqfd->eventfd = eventfd_ctx_fileget(fd_file(f));
if (IS_ERR(kirqfd->eventfd)) {
ret = PTR_ERR(kirqfd->eventfd);
goto error_fd_put;
goto error_kfree;
}
/*
@@ -1026,20 +1026,11 @@ static int privcmd_irqfd_assign(struct privcmd_irqfd *irqfd)
irqfd_inject(kirqfd);
srcu_read_unlock(&irqfds_srcu, idx);
/*
* Do not drop the file until the kirqfd is fully initialized, otherwise
* we might race against the EPOLLHUP.
*/
fdput(f);
return 0;
error_eventfd:
eventfd_ctx_put(kirqfd->eventfd);
error_fd_put:
fdput(f);
error_kfree:
kfree(kirqfd);
return ret;
@@ -1350,7 +1341,6 @@ static int privcmd_ioeventfd_assign(struct privcmd_ioeventfd *ioeventfd)
struct privcmd_kernel_ioeventfd *kioeventfd;
struct privcmd_kernel_ioreq *kioreq;
unsigned long flags;
struct fd f;
int ret;
/* Check for range overflow */
@@ -1370,15 +1360,7 @@ static int privcmd_ioeventfd_assign(struct privcmd_ioeventfd *ioeventfd)
if (!kioeventfd)
return -ENOMEM;
f = fdget(ioeventfd->event_fd);
if (!fd_file(f)) {
ret = -EBADF;
goto error_kfree;
}
kioeventfd->eventfd = eventfd_ctx_fileget(fd_file(f));
fdput(f);
kioeventfd->eventfd = eventfd_ctx_fdget(ioeventfd->event_fd);
if (IS_ERR(kioeventfd->eventfd)) {
ret = PTR_ERR(kioeventfd->eventfd);
goto error_kfree;

View File

@@ -1308,9 +1308,9 @@ static noinline int __btrfs_ioctl_snap_create(struct file *file,
ret = btrfs_mksubvol(&file->f_path, idmap, name,
namelen, NULL, readonly, inherit);
} else {
struct fd src = fdget(fd);
CLASS(fd, src)(fd);
struct inode *src_inode;
if (!fd_file(src)) {
if (fd_empty(src)) {
ret = -EINVAL;
goto out_drop_write;
}
@@ -1341,7 +1341,6 @@ static noinline int __btrfs_ioctl_snap_create(struct file *file,
BTRFS_I(src_inode)->root,
readonly, inherit);
}
fdput(src);
}
out_drop_write:
mnt_drop_write_file(file);

View File

@@ -347,13 +347,10 @@ EXPORT_SYMBOL_GPL(eventfd_fget);
*/
struct eventfd_ctx *eventfd_ctx_fdget(int fd)
{
struct eventfd_ctx *ctx;
struct fd f = fdget(fd);
if (!fd_file(f))
CLASS(fd, f)(fd);
if (fd_empty(f))
return ERR_PTR(-EBADF);
ctx = eventfd_ctx_fileget(fd_file(f));
fdput(f);
return ctx;
return eventfd_ctx_fileget(fd_file(f));
}
EXPORT_SYMBOL_GPL(eventfd_ctx_fdget);

View File

@@ -2259,25 +2259,22 @@ int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *epds,
{
int error;
int full_check = 0;
struct fd f, tf;
struct eventpoll *ep;
struct epitem *epi;
struct eventpoll *tep = NULL;
error = -EBADF;
f = fdget(epfd);
if (!fd_file(f))
goto error_return;
CLASS(fd, f)(epfd);
if (fd_empty(f))
return -EBADF;
/* Get the "struct file *" for the target file */
tf = fdget(fd);
if (!fd_file(tf))
goto error_fput;
CLASS(fd, tf)(fd);
if (fd_empty(tf))
return -EBADF;
/* The target file descriptor must support poll */
error = -EPERM;
if (!file_can_poll(fd_file(tf)))
goto error_tgt_fput;
return -EPERM;
/* Check if EPOLLWAKEUP is allowed */
if (ep_op_has_event(op))
@@ -2396,12 +2393,6 @@ error_tgt_fput:
loop_check_gen++;
mutex_unlock(&epnested_mutex);
}
fdput(tf);
error_fput:
fdput(f);
error_return:
return error;
}
@@ -2429,8 +2420,6 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
static int do_epoll_wait(int epfd, struct epoll_event __user *events,
int maxevents, struct timespec64 *to)
{
int error;
struct fd f;
struct eventpoll *ep;
/* The maximum number of event must be greater than zero */
@@ -2442,17 +2431,16 @@ static int do_epoll_wait(int epfd, struct epoll_event __user *events,
return -EFAULT;
/* Get the "struct file *" for the eventpoll file */
f = fdget(epfd);
if (!fd_file(f))
CLASS(fd, f)(epfd);
if (fd_empty(f))
return -EBADF;
/*
* We have to check that the file structure underneath the fd
* the user passed to us _is_ an eventpoll file.
*/
error = -EINVAL;
if (!is_file_epoll(fd_file(f)))
goto error_fput;
return -EINVAL;
/*
* At this point it is safe to assume that the "private_data" contains
@@ -2461,11 +2449,7 @@ static int do_epoll_wait(int epfd, struct epoll_event __user *events,
ep = fd_file(f)->private_data;
/* Time to fish for events ... */
error = ep_poll(ep, events, maxevents, to);
error_fput:
fdput(f);
return error;
return ep_poll(ep, events, maxevents, to);
}
SYSCALL_DEFINE4(epoll_wait, int, epfd, struct epoll_event __user *, events,

Some files were not shown because too many files have changed in this diff Show More