io_uring: don't touch ctx in setup after ring fd install
authorJens Axboe <axboe@kernel.dk>
Mon, 28 Oct 2019 15:15:33 +0000 (09:15 -0600)
committerJens Axboe <axboe@kernel.dk>
Mon, 28 Oct 2019 15:15:33 +0000 (09:15 -0600)
syzkaller reported an issue where it looks like a malicious app can
trigger a use-after-free of reading the ctx ->sq_array and ->rings
value right after having installed the ring fd in the process file
table.

Defer ring fd installation until after we're done reading those
values.

Fixes: 75b28affdd6a ("io_uring: allocate the two rings together")
Reported-by: syzbot+6f03d895a6cd0d06187f@syzkaller.appspotmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c

index ba1431046c983fc10a87f508fe658a9d686af093..c11c4157a4c22c6c0d718749fd0e68beefda409b 100644 (file)
@@ -3829,10 +3829,6 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p)
        if (ret)
                goto err;
 
-       ret = io_uring_get_fd(ctx);
-       if (ret < 0)
-               goto err;
-
        memset(&p->sq_off, 0, sizeof(p->sq_off));
        p->sq_off.head = offsetof(struct io_rings, sq.head);
        p->sq_off.tail = offsetof(struct io_rings, sq.tail);
@@ -3850,6 +3846,14 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p)
        p->cq_off.overflow = offsetof(struct io_rings, cq_overflow);
        p->cq_off.cqes = offsetof(struct io_rings, cqes);
 
+       /*
+        * Install ring fd as the very last thing, so we don't risk someone
+        * having closed it before we finish setup
+        */
+       ret = io_uring_get_fd(ctx);
+       if (ret < 0)
+               goto err;
+
        p->features = IORING_FEAT_SINGLE_MMAP;
        return ret;
 err: