We should first look at the return value of __io_arm_poll_handler() and only if zero checking for ipt.error, not the other way around. Currently we may enqueue a tw for such request and then release it inline causing UAF. Fixes: 9c1d09f56425e ("io_uring: handle completions in the core") Signed-off-by: Pavel Begunkov <asml.silence@xxxxxxxxx> --- io_uring/poll.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/io_uring/poll.c b/io_uring/poll.c index 8f4fff76d3b4..528418aaf3f6 100644 --- a/io_uring/poll.c +++ b/io_uring/poll.c @@ -782,16 +782,11 @@ int io_poll_add(struct io_kiocb *req, unsigned int issue_flags) req->flags &= ~REQ_F_HASH_LOCKED; ret = __io_arm_poll_handler(req, poll, &ipt, poll->events); - if (ipt.error) { - return ipt.error; - } else if (ret > 0) { + if (ret) { io_req_set_res(req, ret, 0); return IOU_OK; - } else if (!ret) { - return IOU_ISSUE_SKIP_COMPLETE; } - - return ret; + return ipt.error ?: IOU_ISSUE_SKIP_COMPLETE; } int io_poll_remove(struct io_kiocb *req, unsigned int issue_flags) -- 2.36.1