Skip to content

Commit ea71732

Browse files
committed
Merge tag 'io_uring-6.14-20250214' of git://git.kernel.dk/linux
Pull io_uring fixes from Jens Axboe: - fixes for a potential data corruption issue with IORING_OP_URING_CMD, where not all the SQE data is stable. Will be revisited in the future, for now it ends up with just always copying it beyond prep to provide the same guarantees as all other opcodes - make the waitid opcode setup async data like any other opcodes (no real fix here, just a consistency thing) - fix for waitid io_tw_state abuse - when a buffer group is type is changed, do so by allocating a new buffer group entry and discard the old one, rather than migrating * tag 'io_uring-6.14-20250214' of git://git.kernel.dk/linux: io_uring/uring_cmd: unconditionally copy SQEs at prep time io_uring/waitid: setup async data in the prep handler io_uring/uring_cmd: remove dead req_has_async_data() check io_uring/uring_cmd: switch sqe to async_data on EAGAIN io_uring/uring_cmd: don't assume io_uring_cmd_data layout io_uring/kbuf: reallocate buf lists on upgrade io_uring/waitid: don't abuse io_tw_state
2 parents 04f41cb + d6211eb commit ea71732

File tree

3 files changed

+30
-32
lines changed

3 files changed

+30
-32
lines changed

io_uring/kbuf.c

+12-4
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,13 @@ void io_destroy_buffers(struct io_ring_ctx *ctx)
415415
}
416416
}
417417

418+
static void io_destroy_bl(struct io_ring_ctx *ctx, struct io_buffer_list *bl)
419+
{
420+
scoped_guard(mutex, &ctx->mmap_lock)
421+
WARN_ON_ONCE(xa_erase(&ctx->io_bl_xa, bl->bgid) != bl);
422+
io_put_bl(ctx, bl);
423+
}
424+
418425
int io_remove_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
419426
{
420427
struct io_provide_buf *p = io_kiocb_to_cmd(req, struct io_provide_buf);
@@ -636,12 +643,13 @@ int io_register_pbuf_ring(struct io_ring_ctx *ctx, void __user *arg)
636643
/* if mapped buffer ring OR classic exists, don't allow */
637644
if (bl->flags & IOBL_BUF_RING || !list_empty(&bl->buf_list))
638645
return -EEXIST;
639-
} else {
640-
free_bl = bl = kzalloc(sizeof(*bl), GFP_KERNEL);
641-
if (!bl)
642-
return -ENOMEM;
646+
io_destroy_bl(ctx, bl);
643647
}
644648

649+
free_bl = bl = kzalloc(sizeof(*bl), GFP_KERNEL);
650+
if (!bl)
651+
return -ENOMEM;
652+
645653
mmap_offset = (unsigned long)reg.bgid << IORING_OFF_PBUF_SHIFT;
646654
ring_size = flex_array_size(br, bufs, reg.ring_entries);
647655

io_uring/uring_cmd.c

+9-19
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,6 @@ bool io_uring_try_cancel_uring_cmd(struct io_ring_ctx *ctx,
5454
continue;
5555

5656
if (cmd->flags & IORING_URING_CMD_CANCELABLE) {
57-
/* ->sqe isn't available if no async data */
58-
if (!req_has_async_data(req))
59-
cmd->sqe = NULL;
6057
file->f_op->uring_cmd(cmd, IO_URING_F_CANCEL |
6158
IO_URING_F_COMPLETE_DEFER);
6259
ret = true;
@@ -179,12 +176,13 @@ static int io_uring_cmd_prep_setup(struct io_kiocb *req,
179176
return -ENOMEM;
180177
cache->op_data = NULL;
181178

182-
if (!(req->flags & REQ_F_FORCE_ASYNC)) {
183-
/* defer memcpy until we need it */
184-
ioucmd->sqe = sqe;
185-
return 0;
186-
}
187-
179+
/*
180+
* Unconditionally cache the SQE for now - this is only needed for
181+
* requests that go async, but prep handlers must ensure that any
182+
* sqe data is stable beyond prep. Since uring_cmd is special in
183+
* that it doesn't read in per-op data, play it safe and ensure that
184+
* any SQE data is stable beyond prep. This can later get relaxed.
185+
*/
188186
memcpy(cache->sqes, sqe, uring_sqe_size(req->ctx));
189187
ioucmd->sqe = cache->sqes;
190188
return 0;
@@ -249,16 +247,8 @@ int io_uring_cmd(struct io_kiocb *req, unsigned int issue_flags)
249247
}
250248

251249
ret = file->f_op->uring_cmd(ioucmd, issue_flags);
252-
if (ret == -EAGAIN) {
253-
struct io_uring_cmd_data *cache = req->async_data;
254-
255-
if (ioucmd->sqe != (void *) cache)
256-
memcpy(cache->sqes, ioucmd->sqe, uring_sqe_size(req->ctx));
257-
return -EAGAIN;
258-
} else if (ret == -EIOCBQUEUED) {
259-
return -EIOCBQUEUED;
260-
}
261-
250+
if (ret == -EAGAIN || ret == -EIOCBQUEUED)
251+
return ret;
262252
if (ret < 0)
263253
req_set_fail(req);
264254
io_req_uring_cleanup(req, issue_flags);

io_uring/waitid.c

+9-9
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ static int io_waitid_finish(struct io_kiocb *req, int ret)
118118
static void io_waitid_complete(struct io_kiocb *req, int ret)
119119
{
120120
struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
121-
struct io_tw_state ts = {};
122121

123122
/* anyone completing better be holding a reference */
124123
WARN_ON_ONCE(!(atomic_read(&iw->refs) & IO_WAITID_REF_MASK));
@@ -131,7 +130,6 @@ static void io_waitid_complete(struct io_kiocb *req, int ret)
131130
if (ret < 0)
132131
req_set_fail(req);
133132
io_req_set_res(req, ret, 0);
134-
io_req_task_complete(req, &ts);
135133
}
136134

137135
static bool __io_waitid_cancel(struct io_ring_ctx *ctx, struct io_kiocb *req)
@@ -153,6 +151,7 @@ static bool __io_waitid_cancel(struct io_ring_ctx *ctx, struct io_kiocb *req)
153151
list_del_init(&iwa->wo.child_wait.entry);
154152
spin_unlock_irq(&iw->head->lock);
155153
io_waitid_complete(req, -ECANCELED);
154+
io_req_queue_tw_complete(req, -ECANCELED);
156155
return true;
157156
}
158157

@@ -258,6 +257,7 @@ static void io_waitid_cb(struct io_kiocb *req, struct io_tw_state *ts)
258257
}
259258

260259
io_waitid_complete(req, ret);
260+
io_req_task_complete(req, ts);
261261
}
262262

263263
static int io_waitid_wait(struct wait_queue_entry *wait, unsigned mode,
@@ -285,10 +285,16 @@ static int io_waitid_wait(struct wait_queue_entry *wait, unsigned mode,
285285
int io_waitid_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
286286
{
287287
struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
288+
struct io_waitid_async *iwa;
288289

289290
if (sqe->addr || sqe->buf_index || sqe->addr3 || sqe->waitid_flags)
290291
return -EINVAL;
291292

293+
iwa = io_uring_alloc_async_data(NULL, req);
294+
if (!unlikely(iwa))
295+
return -ENOMEM;
296+
iwa->req = req;
297+
292298
iw->which = READ_ONCE(sqe->len);
293299
iw->upid = READ_ONCE(sqe->fd);
294300
iw->options = READ_ONCE(sqe->file_index);
@@ -299,16 +305,10 @@ int io_waitid_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
299305
int io_waitid(struct io_kiocb *req, unsigned int issue_flags)
300306
{
301307
struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
308+
struct io_waitid_async *iwa = req->async_data;
302309
struct io_ring_ctx *ctx = req->ctx;
303-
struct io_waitid_async *iwa;
304310
int ret;
305311

306-
iwa = io_uring_alloc_async_data(NULL, req);
307-
if (!iwa)
308-
return -ENOMEM;
309-
310-
iwa->req = req;
311-
312312
ret = kernel_waitid_prepare(&iwa->wo, iw->which, iw->upid, &iw->info,
313313
iw->options, NULL);
314314
if (ret)

0 commit comments

Comments
 (0)