Commit 6f2cc166 authored by Xiaoguang Wang's avatar Xiaoguang Wang Committed by Jens Axboe

io_uring: fix possible race condition against REQ_F_NEED_CLEANUP

In io_read() or io_write(), when io request is submitted successfully,
it'll go through the below sequence:

    kfree(iovec);
    req->flags &= ~REQ_F_NEED_CLEANUP;
    return ret;

But clearing REQ_F_NEED_CLEANUP might be unsafe. The io request may
already have been completed, and then io_complete_rw_iopoll()
and io_complete_rw() will be called, both of which will also modify
req->flags if needed. This causes a race condition, with concurrent
non-atomic modification of req->flags.

To eliminate this race, in io_read() or io_write(), if io request is
submitted successfully, we don't remove REQ_F_NEED_CLEANUP flag. If
REQ_F_NEED_CLEANUP is set, we'll leave __io_req_aux_free() to the
iovec cleanup work correspondingly.

Cc: stable@vger.kernel.org
Signed-off-by: default avatarXiaoguang Wang <xiaoguang.wang@linux.alibaba.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 56952e91
...@@ -2670,8 +2670,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock) ...@@ -2670,8 +2670,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock)
} }
} }
out_free: out_free:
if (!(req->flags & REQ_F_NEED_CLEANUP))
kfree(iovec); kfree(iovec);
req->flags &= ~REQ_F_NEED_CLEANUP;
return ret; return ret;
} }
...@@ -2793,7 +2793,7 @@ static int io_write(struct io_kiocb *req, bool force_nonblock) ...@@ -2793,7 +2793,7 @@ static int io_write(struct io_kiocb *req, bool force_nonblock)
} }
} }
out_free: out_free:
req->flags &= ~REQ_F_NEED_CLEANUP; if (!(req->flags & REQ_F_NEED_CLEANUP))
kfree(iovec); kfree(iovec);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment