]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
io_uring: NULL-deref for IOSQE_{ASYNC,DRAIN}
authorPavel Begunkov <asml.silence@gmail.com>
Fri, 13 Mar 2020 19:29:14 +0000 (22:29 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 25 Mar 2020 07:27:08 +0000 (08:27 +0100)
[ Upstream commit f1d96a8fcbbbb22d4fbc1d69eaaa678bbb0ff6e2 ]

Processing links, io_submit_sqe() prepares requests, drops sqes, and
passes them with sqe=NULL to io_queue_sqe(). There IOSQE_DRAIN and/or
IOSQE_ASYNC requests will go through the same prep, which doesn't expect
sqe=NULL and fail with NULL pointer deference.

Always do full prepare including io_alloc_async_ctx() for linked
requests, and then it can skip the second preparation.

Cc: stable@vger.kernel.org # 5.5
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/io_uring.c

index 44ae2641b4b06427242e6e32bfab665345a7e33a..faa0198c99ffd43c011b995a60b8b5e19e363d3b 100644 (file)
@@ -3098,6 +3098,9 @@ static int io_req_defer_prep(struct io_kiocb *req,
 {
        ssize_t ret = 0;
 
+       if (!sqe)
+               return 0;
+
        switch (req->opcode) {
        case IORING_OP_NOP:
                break;
@@ -3681,6 +3684,11 @@ err_req:
                        req->flags |= REQ_F_HARDLINK;
 
                INIT_LIST_HEAD(&req->link_list);
+
+               if (io_alloc_async_ctx(req)) {
+                       ret = -EAGAIN;
+                       goto err_req;
+               }
                ret = io_req_defer_prep(req, sqe);
                if (ret)
                        req->flags |= REQ_F_FAIL_LINK;