Skip to content

Commit

Permalink
Merge tag 'pull-fd' of git://git.kernel.org/pub/scm/linux/kernel/git/…
Browse files Browse the repository at this point in the history
…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)
  ...
  • Loading branch information
torvalds committed Nov 18, 2024
2 parents 23acd17 + 38052c2 commit 0f25f0e
Show file tree
Hide file tree
Showing 77 changed files with 751 additions and 1,395 deletions.
5 changes: 2 additions & 3 deletions arch/alpha/kernel/osf_sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,15 @@ 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,
.basep = basep,
.count = count
};

if (!fd_file(arg))
if (fd_empty(arg))
return -EBADF;

error = iterate_dir(fd_file(arg), &buf.ctx);
Expand All @@ -169,7 +169,6 @@ SYSCALL_DEFINE4(osf_getdirentries, unsigned int, fd,
if (count != buf.count)
error = count - buf.count;

fdput_pos(arg);
return error;
}

Expand Down
10 changes: 4 additions & 6 deletions arch/arm/kernel/sys_oabi-compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
}

Expand Down
21 changes: 5 additions & 16 deletions arch/powerpc/kvm/book3s_64_vio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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];
Expand All @@ -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) {
Expand All @@ -174,23 +167,20 @@ 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;
}
/*
* The table is already known to this KVM, we just increased
* its KVM reference counter and can return.
*/
rcu_read_unlock();
fdput(f);
return 0;
}
rcu_read_unlock();

stit = kzalloc(sizeof(*stit), GFP_KERNEL);
if (!stit) {
iommu_tce_table_put(tbl);
fdput(f);
return -ENOMEM;
}

Expand All @@ -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;
}

Expand Down
24 changes: 7 additions & 17 deletions arch/powerpc/kvm/powerpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1933,31 +1933,28 @@ 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;
dev = kvm_device_from_filp(fd_file(f));
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;
Expand All @@ -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 */
Expand Down
68 changes: 22 additions & 46 deletions arch/powerpc/platforms/cell/spu_syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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

Expand Down
10 changes: 3 additions & 7 deletions arch/x86/kernel/cpu/sgx/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 0f25f0e

Please sign in to comment.