io_uring: fix drain stalls by invalid SQE
authorPavel Begunkov <asml.silence@gmail.com>
Wed, 9 Aug 2023 12:21:41 +0000 (13:21 +0100)
committerJens Axboe <axboe@kernel.dk>
Wed, 9 Aug 2023 16:46:46 +0000 (10:46 -0600)
cq_extra is protected by ->completion_lock, which io_get_sqe() misses.
The bug is harmless as it doesn't happen in real life, requires invalid
SQ index array and racing with submission, and only messes up the
userspace, i.e. stall requests execution but will be cleaned up on
ring destruction.

Fixes: 15641e427070f ("io_uring: don't cache number of dropped SQEs")
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/66096d54651b1a60534bb2023f2947f09f50ef73.1691538547.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/io_uring.c

index 679bea7c41a62c9281a4aea5e7727b862e6714f1..249cab9c86d10ebac6a8bb7309b3962210a40f06 100644 (file)
@@ -2374,7 +2374,9 @@ static bool io_get_sqe(struct io_ring_ctx *ctx, const struct io_uring_sqe **sqe)
        }
 
        /* drop invalid entries */
+       spin_lock(&ctx->completion_lock);
        ctx->cq_extra--;
+       spin_unlock(&ctx->completion_lock);
        WRITE_ONCE(ctx->rings->sq_dropped,
                   READ_ONCE(ctx->rings->sq_dropped) + 1);
        return false;