]> Gentwo Git Trees - linux/.git/commitdiff
io_uring/fdinfo: cap SQ iteration at max SQ entries
authorJens Axboe <axboe@kernel.dk>
Tue, 28 Oct 2025 01:09:28 +0000 (19:09 -0600)
committerJens Axboe <axboe@kernel.dk>
Tue, 28 Oct 2025 01:19:13 +0000 (19:19 -0600)
A previous commit changed the logic around how SQ entries are iterated,
and as a result, had a few bugs. One is that it fully trusts the SQ
head and tail, which are user exposed. Another is that it fails to
increment the SQ head if the SQ index is out of range.

Fix both of those up, reverting to the previous logic of how to
iterate SQ entries.

Link: https://lore.kernel.org/io-uring/68ffdf18.050a0220.3344a1.039e.GAE@google.com/
Fixes: 1cba30bf9fdd ("io_uring: add support for IORING_SETUP_SQE_MIXED")
Reported-by: syzbot+10a9b495f54a17b607a6@syzkaller.appspotmail.com
Tested-by: syzbot+10a9b495f54a17b607a6@syzkaller.appspotmail.com
Reviewed-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/fdinfo.c

index a3ce9218354065a110f9eb4d0731c2b701f3c010..248006424cabaca18a78f4d695fbf0007b67618b 100644 (file)
@@ -67,6 +67,7 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
        unsigned int cq_head = READ_ONCE(r->cq.head);
        unsigned int cq_tail = READ_ONCE(r->cq.tail);
        unsigned int sq_shift = 0;
+       unsigned int sq_entries;
        int sq_pid = -1, sq_cpu = -1;
        u64 sq_total_time = 0, sq_work_time = 0;
        unsigned int i;
@@ -89,17 +90,18 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
        seq_printf(m, "CqTail:\t%u\n", cq_tail);
        seq_printf(m, "CachedCqTail:\t%u\n", data_race(ctx->cached_cq_tail));
        seq_printf(m, "SQEs:\t%u\n", sq_tail - sq_head);
-       while (sq_head < sq_tail) {
+       sq_entries = min(sq_tail - sq_head, ctx->sq_entries);
+       for (i = 0; i < sq_entries; i++) {
+               unsigned int entry = i + sq_head;
                struct io_uring_sqe *sqe;
                unsigned int sq_idx;
                bool sqe128 = false;
                u8 opcode;
 
                if (ctx->flags & IORING_SETUP_NO_SQARRAY)
-                       sq_idx = sq_head & sq_mask;
+                       sq_idx = entry & sq_mask;
                else
-                       sq_idx = READ_ONCE(ctx->sq_array[sq_head & sq_mask]);
-
+                       sq_idx = READ_ONCE(ctx->sq_array[entry & sq_mask]);
                if (sq_idx > sq_mask)
                        continue;
 
@@ -141,7 +143,6 @@ static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
                        }
                }
                seq_printf(m, "\n");
-               sq_head++;
        }
        seq_printf(m, "CQEs:\t%u\n", cq_tail - cq_head);
        while (cq_head < cq_tail) {