mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
io_uring/msg_ring: reject CQE32 flag pass-through to normal rings
IORING_OP_MSG_RING with IORING_MSG_RING_FLAGS_PASS allows a sender to
pass completion flags through sqe->file_index. If the sender sets
IORING_CQE_F_32 in file_index, the target-side completion path treats it
as a 32b CQE and writes big_cqe[0] and big_cqe[1] into the CQ ring
regardless of whether the target ring was created with
IORING_SETUP_CQE32 or IORING_SETUP_CQE_MIXED.
On a normal 16b CQE ring, this writes 16 extra bytes (two u64 big_cqe
fields) into the next CQE slot in the ring buffer. As the receiving ring
doesn't understand 32b CQEs, this is incorrect and they should be
rejected.
Fixes: cbeb47a7b5 ("io_uring/msg_ring: Pass custom flags to the cqe")
Signed-off-by: Melbin K Mathew <mlbnkm1@gmail.com>
Link: https://patch.msgid.link/20260701081145.196730-1-mlbnkm1@gmail.com
[axboe: edit commit message]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
committed by
Jens Axboe
parent
df645b7459
commit
15cd3ccf9b
@@ -93,19 +93,38 @@ static void io_msg_remote_post(struct io_ring_ctx *ctx, struct io_kiocb *req,
|
||||
io_req_task_work_add_remote(req, IOU_F_TWQ_LAZY_WAKE);
|
||||
}
|
||||
|
||||
static int io_msg_ring_cqe_flags(struct io_ring_ctx *target_ctx,
|
||||
const struct io_msg *msg, u32 *flags)
|
||||
{
|
||||
*flags = 0;
|
||||
|
||||
if (!(msg->flags & IORING_MSG_RING_FLAGS_PASS))
|
||||
return 0;
|
||||
|
||||
*flags = msg->cqe_flags;
|
||||
if ((*flags & IORING_CQE_F_32) &&
|
||||
!(target_ctx->flags & (IORING_SETUP_CQE32 |
|
||||
IORING_SETUP_CQE_MIXED)))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int io_msg_data_remote(struct io_ring_ctx *target_ctx,
|
||||
struct io_msg *msg)
|
||||
{
|
||||
struct io_kiocb *target;
|
||||
u32 flags = 0;
|
||||
u32 flags;
|
||||
int ret;
|
||||
|
||||
target = kmem_cache_alloc(req_cachep, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO) ;
|
||||
ret = io_msg_ring_cqe_flags(target_ctx, msg, &flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
target = kmem_cache_alloc(req_cachep, GFP_KERNEL | __GFP_NOWARN | __GFP_ZERO);
|
||||
if (unlikely(!target))
|
||||
return -ENOMEM;
|
||||
|
||||
if (msg->flags & IORING_MSG_RING_FLAGS_PASS)
|
||||
flags = msg->cqe_flags;
|
||||
|
||||
io_msg_remote_post(target_ctx, target, msg->len, flags, msg->user_data);
|
||||
return 0;
|
||||
}
|
||||
@@ -130,8 +149,9 @@ static int __io_msg_ring_data(struct io_ring_ctx *target_ctx,
|
||||
if (io_msg_need_remote(target_ctx))
|
||||
return io_msg_data_remote(target_ctx, msg);
|
||||
|
||||
if (msg->flags & IORING_MSG_RING_FLAGS_PASS)
|
||||
flags = msg->cqe_flags;
|
||||
ret = io_msg_ring_cqe_flags(target_ctx, msg, &flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = -EOVERFLOW;
|
||||
if (target_ctx->flags & IORING_SETUP_IOPOLL) {
|
||||
|
||||
Reference in New Issue
Block a user