Skip to content

Commit

Permalink
io_uring: NULL-deref for IOSQE_{ASYNC,DRAIN}
Browse files Browse the repository at this point in the history
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: [email protected] # 5.5
Signed-off-by: Pavel Begunkov <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
isilence authored and axboe committed Mar 14, 2020
1 parent 805b13a commit f1d96a8
Showing 1 changed file with 8 additions and 0 deletions.
8 changes: 8 additions & 0 deletions fs/io_uring.c
Original file line number Diff line number Diff line change
Expand Up @@ -4131,6 +4131,9 @@ static int io_req_defer_prep(struct io_kiocb *req,
{
ssize_t ret = 0;

if (!sqe)
return 0;

if (io_op_defs[req->opcode].file_table) {
ret = io_grab_files(req);
if (unlikely(ret))
Expand Down Expand Up @@ -4907,6 +4910,11 @@ static bool io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
if (sqe_flags & (IOSQE_IO_LINK|IOSQE_IO_HARDLINK)) {
req->flags |= REQ_F_LINK;
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;
Expand Down

0 comments on commit f1d96a8

Please sign in to comment.