io_uring: fix multishot accept request leaks
commit9148286476
upstream. Having REQ_F_POLLED set doesn't guarantee that the request is executed as a multishot from the polling path. Fortunately for us, if the code thinks it's multishot issue when it's not, it can only ask to skip completion so leaking the request. Use issue_flags to mark multipoll issues. Cc: stable@vger.kernel.org Fixes:390ed29b5e
("io_uring: add IORING_ACCEPT_MULTISHOT for accept") Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Link: https://lore.kernel.org/r/7700ac57653f2823e30b34dc74da68678c0c5f13.1668710222.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
1e0767f7b0
commit
0e4626de85
|
@ -15,6 +15,9 @@ enum io_uring_cmd_flags {
|
|||
IO_URING_F_SQE128 = 4,
|
||||
IO_URING_F_CQE32 = 8,
|
||||
IO_URING_F_IOPOLL = 16,
|
||||
|
||||
/* the request is executed from poll, it should not be freed */
|
||||
IO_URING_F_MULTISHOT = 32,
|
||||
};
|
||||
|
||||
struct io_uring_cmd {
|
||||
|
|
|
@ -1618,7 +1618,7 @@ int io_poll_issue(struct io_kiocb *req, bool *locked)
|
|||
io_tw_lock(req->ctx, locked);
|
||||
if (unlikely(req->task->flags & PF_EXITING))
|
||||
return -EFAULT;
|
||||
return io_issue_sqe(req, IO_URING_F_NONBLOCK);
|
||||
return io_issue_sqe(req, IO_URING_F_NONBLOCK|IO_URING_F_MULTISHOT);
|
||||
}
|
||||
|
||||
struct io_wq_work *io_wq_free_work(struct io_wq_work *work)
|
||||
|
|
|
@ -17,8 +17,8 @@ enum {
|
|||
IOU_ISSUE_SKIP_COMPLETE = -EIOCBQUEUED,
|
||||
|
||||
/*
|
||||
* Intended only when both REQ_F_POLLED and REQ_F_APOLL_MULTISHOT
|
||||
* are set to indicate to the poll runner that multishot should be
|
||||
* Intended only when both IO_URING_F_MULTISHOT is passed
|
||||
* to indicate to the poll runner that multishot should be
|
||||
* removed and the result is set on req->cqe.res.
|
||||
*/
|
||||
IOU_STOP_MULTISHOT = -ECANCELED,
|
||||
|
|
|
@ -1168,8 +1168,7 @@ retry:
|
|||
* return EAGAIN to arm the poll infra since it
|
||||
* has already been done
|
||||
*/
|
||||
if ((req->flags & IO_APOLL_MULTI_POLLED) ==
|
||||
IO_APOLL_MULTI_POLLED)
|
||||
if (issue_flags & IO_URING_F_MULTISHOT)
|
||||
ret = IOU_ISSUE_SKIP_COMPLETE;
|
||||
return ret;
|
||||
}
|
||||
|
@ -1194,9 +1193,7 @@ retry:
|
|||
goto retry;
|
||||
|
||||
io_req_set_res(req, ret, 0);
|
||||
if (req->flags & REQ_F_POLLED)
|
||||
return IOU_STOP_MULTISHOT;
|
||||
return IOU_OK;
|
||||
return (issue_flags & IO_URING_F_MULTISHOT) ? IOU_STOP_MULTISHOT : IOU_OK;
|
||||
}
|
||||
|
||||
int io_socket_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
|
||||
|
|
Loading…
Reference in New Issue