Merge tag 'io_uring-7.3-20260828' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux

Pull io_uring fixes from Jens Axboe:
 "A few smaller fixes for io_uring that should go into the 7.3-rc1
  kernel, all three headed to stable as well. This contains:

   - A few fixes around cancellation and teardown for waitid

   - Cap the user size for the query interface copy-out"

* tag 'io_uring-7.3-20260828' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux:
  io_uring/waitid: avoid siginfo copy during ring teardown
  io_uring/waitid: honor task_work cancellation
  io_uring/query: cap user size passed to copy_struct_to_user
This commit is contained in:
Linus Torvalds
2026-08-28 16:51:14 -07:00
2 changed files with 29 additions and 7 deletions

View File

@@ -76,6 +76,9 @@ static int io_handle_query_entry(union io_query_data *data, void __user *uhdr,
if (copy_from_user(&hdr, uhdr, sizeof(hdr)))
return -EFAULT;
/* copy_struct_to_user() zeros up to usize bytes */
if (hdr.size > PAGE_SIZE)
return -E2BIG;
usize = hdr.size;
hdr.size = min(hdr.size, IO_MAX_QUERY_SIZE);
udata = u64_to_user_ptr(hdr.query_data);

View File

@@ -125,7 +125,7 @@ static void io_waitid_remove_wq(struct io_kiocb *req)
}
}
static void io_waitid_complete(struct io_kiocb *req, int ret)
static void io_waitid_complete(struct io_kiocb *req, int ret, bool copy_si)
{
struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
@@ -137,13 +137,16 @@ static void io_waitid_complete(struct io_kiocb *req, int ret)
hlist_del_init(&req->hash_node);
io_waitid_remove_wq(req);
ret = io_waitid_finish(req, ret);
if (copy_si)
ret = io_waitid_finish(req, ret);
else
io_waitid_free(req);
if (ret < 0)
req_set_fail(req);
io_req_set_res(req, ret, 0);
}
static bool __io_waitid_cancel(struct io_kiocb *req)
static bool __io_waitid_cancel(struct io_kiocb *req, bool copy_si)
{
struct io_waitid *iw = io_kiocb_to_cmd(req, struct io_waitid);
@@ -159,21 +162,32 @@ static bool __io_waitid_cancel(struct io_kiocb *req)
if (atomic_fetch_inc(&iw->refs) & IO_WAITID_REF_MASK)
return false;
io_waitid_complete(req, -ECANCELED);
io_waitid_complete(req, -ECANCELED, copy_si);
io_req_queue_tw_complete(req, -ECANCELED);
return true;
}
static bool io_waitid_cancel_cb(struct io_kiocb *req)
{
return __io_waitid_cancel(req, true);
}
static bool io_waitid_cancel_nocopy_cb(struct io_kiocb *req)
{
return __io_waitid_cancel(req, false);
}
int io_waitid_cancel(struct io_ring_ctx *ctx, struct io_cancel_data *cd,
unsigned int issue_flags)
{
return io_cancel_remove(ctx, cd, issue_flags, &ctx->waitid_list, __io_waitid_cancel);
return io_cancel_remove(ctx, cd, issue_flags, &ctx->waitid_list, io_waitid_cancel_cb);
}
bool io_waitid_remove_all(struct io_ring_ctx *ctx, struct io_uring_task *tctx,
bool cancel_all)
{
return io_cancel_remove_all(ctx, tctx, &ctx->waitid_list, cancel_all, __io_waitid_cancel);
return io_cancel_remove_all(ctx, tctx, &ctx->waitid_list, cancel_all,
tctx ? io_waitid_cancel_cb : io_waitid_cancel_nocopy_cb);
}
static inline bool io_waitid_drop_issue_ref(struct io_kiocb *req)
@@ -202,6 +216,11 @@ static void io_waitid_cb(struct io_tw_req tw_req, io_tw_token_t tw)
int ret;
io_tw_lock(ctx, tw);
if (unlikely(tw.cancel)) {
io_waitid_complete(req, -ECANCELED, false);
io_req_task_complete(tw_req, tw);
return;
}
ret = __do_wait(&iwa->wo);
@@ -229,7 +248,7 @@ static void io_waitid_cb(struct io_tw_req tw_req, io_tw_token_t tw)
}
}
io_waitid_complete(req, ret);
io_waitid_complete(req, ret, true);
io_req_task_complete(tw_req, tw);
}