Skip to content

Commit 73363c2

Browse files
committed
io_uring: use fget/fput consistently
Normally within a syscall it's fine to use fdget/fdput for grabbing a file from the file table, and it's fine within io_uring as well. We do that via io_uring_enter(2), io_uring_register(2), and then also for cancel which is invoked from the latter. io_uring cannot close its own file descriptors as that is explicitly rejected, and for the cancel side of things, the file itself is just used as a lookup cookie. However, it is more prudent to ensure that full references are always grabbed. For anything threaded, either explicitly in the application itself or through use of the io-wq worker threads, this is what happens anyway. Generalize it and use fget/fput throughout. Also see the below link for more details. Link: https://lore.kernel.org/io-uring/CAG48ez1htVSO3TqmrF8QcX2WFuYTRM-VZ_N10i-VZgbtg=NNqw@mail.gmail.com/ Suggested-by: Jann Horn <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 5cf4f52 commit 73363c2

File tree

2 files changed

+24
-23
lines changed

2 files changed

+24
-23
lines changed

io_uring/cancel.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ int io_sync_cancel(struct io_ring_ctx *ctx, void __user *arg)
273273
};
274274
ktime_t timeout = KTIME_MAX;
275275
struct io_uring_sync_cancel_reg sc;
276-
struct fd f = { };
276+
struct file *file = NULL;
277277
DEFINE_WAIT(wait);
278278
int ret, i;
279279

@@ -295,10 +295,10 @@ int io_sync_cancel(struct io_ring_ctx *ctx, void __user *arg)
295295
/* we can grab a normal file descriptor upfront */
296296
if ((cd.flags & IORING_ASYNC_CANCEL_FD) &&
297297
!(cd.flags & IORING_ASYNC_CANCEL_FD_FIXED)) {
298-
f = fdget(sc.fd);
299-
if (!f.file)
298+
file = fget(sc.fd);
299+
if (!file)
300300
return -EBADF;
301-
cd.file = f.file;
301+
cd.file = file;
302302
}
303303

304304
ret = __io_sync_cancel(current->io_uring, &cd, sc.fd);
@@ -348,6 +348,7 @@ int io_sync_cancel(struct io_ring_ctx *ctx, void __user *arg)
348348
if (ret == -ENOENT || ret > 0)
349349
ret = 0;
350350
out:
351-
fdput(f);
351+
if (file)
352+
fput(file);
352353
return ret;
353354
}

io_uring/io_uring.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3652,7 +3652,7 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,
36523652
size_t, argsz)
36533653
{
36543654
struct io_ring_ctx *ctx;
3655-
struct fd f;
3655+
struct file *file;
36563656
long ret;
36573657

36583658
if (unlikely(flags & ~(IORING_ENTER_GETEVENTS | IORING_ENTER_SQ_WAKEUP |
@@ -3670,20 +3670,19 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,
36703670
if (unlikely(!tctx || fd >= IO_RINGFD_REG_MAX))
36713671
return -EINVAL;
36723672
fd = array_index_nospec(fd, IO_RINGFD_REG_MAX);
3673-
f.file = tctx->registered_rings[fd];
3674-
f.flags = 0;
3675-
if (unlikely(!f.file))
3673+
file = tctx->registered_rings[fd];
3674+
if (unlikely(!file))
36763675
return -EBADF;
36773676
} else {
3678-
f = fdget(fd);
3679-
if (unlikely(!f.file))
3677+
file = fget(fd);
3678+
if (unlikely(!file))
36803679
return -EBADF;
36813680
ret = -EOPNOTSUPP;
3682-
if (unlikely(!io_is_uring_fops(f.file)))
3681+
if (unlikely(!io_is_uring_fops(file)))
36833682
goto out;
36843683
}
36853684

3686-
ctx = f.file->private_data;
3685+
ctx = file->private_data;
36873686
ret = -EBADFD;
36883687
if (unlikely(ctx->flags & IORING_SETUP_R_DISABLED))
36893688
goto out;
@@ -3777,7 +3776,8 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,
37773776
}
37783777
}
37793778
out:
3780-
fdput(f);
3779+
if (!(flags & IORING_ENTER_REGISTERED_RING))
3780+
fput(file);
37813781
return ret;
37823782
}
37833783

@@ -4618,7 +4618,7 @@ SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode,
46184618
{
46194619
struct io_ring_ctx *ctx;
46204620
long ret = -EBADF;
4621-
struct fd f;
4621+
struct file *file;
46224622
bool use_registered_ring;
46234623

46244624
use_registered_ring = !!(opcode & IORING_REGISTER_USE_REGISTERED_RING);
@@ -4637,27 +4637,27 @@ SYSCALL_DEFINE4(io_uring_register, unsigned int, fd, unsigned int, opcode,
46374637
if (unlikely(!tctx || fd >= IO_RINGFD_REG_MAX))
46384638
return -EINVAL;
46394639
fd = array_index_nospec(fd, IO_RINGFD_REG_MAX);
4640-
f.file = tctx->registered_rings[fd];
4641-
f.flags = 0;
4642-
if (unlikely(!f.file))
4640+
file = tctx->registered_rings[fd];
4641+
if (unlikely(!file))
46434642
return -EBADF;
46444643
} else {
4645-
f = fdget(fd);
4646-
if (unlikely(!f.file))
4644+
file = fget(fd);
4645+
if (unlikely(!file))
46474646
return -EBADF;
46484647
ret = -EOPNOTSUPP;
4649-
if (!io_is_uring_fops(f.file))
4648+
if (!io_is_uring_fops(file))
46504649
goto out_fput;
46514650
}
46524651

4653-
ctx = f.file->private_data;
4652+
ctx = file->private_data;
46544653

46554654
mutex_lock(&ctx->uring_lock);
46564655
ret = __io_uring_register(ctx, opcode, arg, nr_args);
46574656
mutex_unlock(&ctx->uring_lock);
46584657
trace_io_uring_register(ctx, opcode, ctx->nr_user_files, ctx->nr_user_bufs, ret);
46594658
out_fput:
4660-
fdput(f);
4659+
if (!use_registered_ring)
4660+
fput(file);
46614661
return ret;
46624662
}
46634663

0 commit comments

Comments
 (0)