summaryrefslogtreecommitdiff
path: root/io_uring
diff options
context:
space:
mode:
authorDylan Yudaken <dylany@fb.com>2022-06-30 02:12:27 -0700
committerJens Axboe <axboe@kernel.dk>2022-07-24 18:39:17 -0600
commita2da676376feb79224eacb9ac1f554bb3232b5de (patch)
tree82f56a9dcd4cbe0d3c777e73e95d57035107fc02 /io_uring
parent52120f0fadcbdaaa981c19327f1865a714e85268 (diff)
io_uring: fix multishot poll on overflow
On overflow, multishot poll can still complete with the IORING_CQE_F_MORE flag set. If in the meantime the user clears a CQE and a the poll was cancelled then the poll will post a CQE without the IORING_CQE_F_MORE (and likely result -ECANCELED). However when processing the application will encounter the non-overflow CQE which indicates that there will be no more events posted. Typical userspace applications would free memory associated with the poll in this case. It will then subsequently receive the earlier CQE which has overflowed, which breaks the contract given by the IORING_CQE_F_MORE flag. Signed-off-by: Dylan Yudaken <dylany@fb.com> Link: https://lore.kernel.org/r/20220630091231.1456789-9-dylany@fb.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'io_uring')
-rw-r--r--io_uring/poll.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/io_uring/poll.c b/io_uring/poll.c
index e8f922a4f6d7..57747d92bba4 100644
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -243,8 +243,10 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked)
req->apoll_events);
if (!io_post_aux_cqe(ctx, req->cqe.user_data,
- mask, IORING_CQE_F_MORE, true))
- return -ECANCELED;
+ mask, IORING_CQE_F_MORE, false)) {
+ io_req_set_res(req, mask, 0);
+ return IOU_POLL_REMOVE_POLL_USE_RES;
+ }
} else {
ret = io_poll_issue(req, locked);
if (ret == IOU_STOP_MULTISHOT)