Skip to content

Commit 0df96fb

Browse files
committed
io_uring/rw: don't attempt to allocate async data if opcode doesn't need it
The new read multishot method doesn't need to allocate async data ever, as it doesn't do vectored IO and it must only be used with provided buffers. While it doesn't have ->prep_async() set, it also sets ->async_size to 0, which is different from any other read/write type we otherwise support. If it's used on a file type that isn't pollable, we do try and allocate this async data, and then try and use that data. But since we passed in a size of 0 for the data, we get a NULL back on data allocation. We then proceed to dereference that to copy state, and that obviously won't end well. Add a check in io_setup_async_rw() for this condition, and avoid copying state. Also add a check for whether or not buffer selection is specified in prep while at it. Fixes: fc68fcd ("io_uring/rw: add support for IORING_OP_READ_MULTISHOT") Link: https://bugzilla.kernel.org/show_bug.cgi?id=218101 Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 8f6f76a commit 0df96fb

File tree

1 file changed

+7
-0
lines changed

1 file changed

+7
-0
lines changed

io_uring/rw.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ int io_read_mshot_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
131131
{
132132
int ret;
133133

134+
/* must be used with provided buffers */
135+
if (!(req->flags & REQ_F_BUFFER_SELECT))
136+
return -EINVAL;
137+
134138
ret = io_prep_rw(req, sqe);
135139
if (unlikely(ret))
136140
return ret;
@@ -542,6 +546,9 @@ static int io_setup_async_rw(struct io_kiocb *req, const struct iovec *iovec,
542546
{
543547
if (!force && !io_cold_defs[req->opcode].prep_async)
544548
return 0;
549+
/* opcode type doesn't need async data */
550+
if (!io_cold_defs[req->opcode].async_size)
551+
return 0;
545552
if (!req_has_async_data(req)) {
546553
struct io_async_rw *iorw;
547554

0 commit comments

Comments
 (0)