io_uring: io_allocate_scq_urings() should return a sane state
authorJens Axboe <axboe@kernel.dk>
Wed, 20 Nov 2019 16:26:29 +0000 (09:26 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 4 Jan 2020 18:18:24 +0000 (19:18 +0100)
[ Upstream commit eb065d301e8c83643367bdb0898becc364046bda ]

We currently rely on the ring destroy on cleaning things up in case of
failure, but io_allocate_scq_urings() can leave things half initialized
if only parts of it fails.

Be nice and return with either everything setup in success, or return an
error with things nicely cleaned up.

Reported-by: syzbot+0d818c0d39399188f393@syzkaller.appspotmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/io_uring.c

index a340147387ec3a9828142c98499b41bc2bc15a66..74e786578c775a2a4f11ac901b27a98f3b980d32 100644 (file)
@@ -3773,12 +3773,18 @@ static int io_allocate_scq_urings(struct io_ring_ctx *ctx,
        ctx->cq_entries = rings->cq_ring_entries;
 
        size = array_size(sizeof(struct io_uring_sqe), p->sq_entries);
-       if (size == SIZE_MAX)
+       if (size == SIZE_MAX) {
+               io_mem_free(ctx->rings);
+               ctx->rings = NULL;
                return -EOVERFLOW;
+       }
 
        ctx->sq_sqes = io_mem_alloc(size);
-       if (!ctx->sq_sqes)
+       if (!ctx->sq_sqes) {
+               io_mem_free(ctx->rings);
+               ctx->rings = NULL;
                return -ENOMEM;
+       }
 
        return 0;
 }