]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
io_uring/fdinfo: fix OOB read in SQE_MIXED wrap check
authorNicholas Carlini <nicholas@carlini.com>
Fri, 27 Mar 2026 02:18:23 +0000 (02:18 +0000)
committerJens Axboe <axboe@kernel.dk>
Fri, 27 Mar 2026 02:28:28 +0000 (20:28 -0600)
__io_uring_show_fdinfo() iterates over pending SQEs and, for 128-byte
SQEs on an IORING_SETUP_SQE_MIXED ring, needs to detect when the second
half of the SQE would be past the end of the sq_sqes array. The current
check tests (++sq_head & sq_mask) == 0, but sq_head is only incremented
when a 128-byte SQE is encountered, not on every iteration. The actual
array index is sq_idx = (i + sq_head) & sq_mask, which can be sq_mask
(the last slot) while the wrap check passes.

Fix by checking sq_idx directly. Keep the sq_head increment so the loop
still skips the second half of the 128-byte SQE on the next iteration.

Fixes: 1cba30bf9fdd ("io_uring: add support for IORING_SETUP_SQE_MIXED")
Signed-off-by: Nicholas Carlini <nicholas@carlini.com>
Link: https://patch.msgid.link/20260327021823.3138396-1-nicholas@carlini.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/fdinfo.c

index 25c92ace18bd13c685ba2a358b3122476ded3295..c2d3e45544bb4ef4e6a3a6cda4393d9563382bc1 100644 (file)
@@ -119,12 +119,13 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
                                        sq_idx);
                                break;
                        }
-                       if ((++sq_head & sq_mask) == 0) {
+                       if (sq_idx == sq_mask) {
                                seq_printf(m,
                                        "%5u: corrupted sqe, wrapping 128B entry\n",
                                        sq_idx);
                                break;
                        }
+                       sq_head++;
                        i++;
                        sqe128 = true;
                }