* [PATCH 0/2] double poll fixes @ 2021-07-20 9:50 Pavel Begunkov 2021-07-20 9:50 ` [PATCH 1/2] io_uring: explicitly count entries for poll reqs Pavel Begunkov ` (2 more replies) 0 siblings, 3 replies; 4+ messages in thread From: Pavel Begunkov @ 2021-07-20 9:50 UTC (permalink / raw) To: Jens Axboe, io-uring; +Cc: asml.silence 2/2 is about recent syzbot report, 1/2 is just a small additional fix Pavel Begunkov (2): io_uring: explicitly count entries for poll reqs io_uring: remove double poll entry on arm failure fs/io_uring.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) -- 2.32.0 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] io_uring: explicitly count entries for poll reqs 2021-07-20 9:50 [PATCH 0/2] double poll fixes Pavel Begunkov @ 2021-07-20 9:50 ` Pavel Begunkov 2021-07-20 9:50 ` [PATCH 2/2] io_uring: remove double poll entry on arm failure Pavel Begunkov 2021-07-20 13:50 ` [PATCH 0/2] double poll fixes Jens Axboe 2 siblings, 0 replies; 4+ messages in thread From: Pavel Begunkov @ 2021-07-20 9:50 UTC (permalink / raw) To: Jens Axboe, io-uring; +Cc: asml.silence If __io_queue_proc() fails to add a second poll entry, e.g. kmalloc() failed, but it goes on with a third waitqueue, it may succeed and overwrite the error status. Count the number of poll entries we added, so we can set pt->error to zero at the beginning and find out when the mentioned scenario happens. Cc: [email protected] Fixes: 18bceab101add ("io_uring: allow POLL_ADD with double poll_wait() users") Signed-off-by: Pavel Begunkov <[email protected]> --- fs/io_uring.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 0cac361bf6b8..6668902cf50c 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -4802,6 +4802,7 @@ IO_NETOP_FN(recv); struct io_poll_table { struct poll_table_struct pt; struct io_kiocb *req; + int nr_entries; int error; }; @@ -4995,11 +4996,11 @@ static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt, struct io_kiocb *req = pt->req; /* - * If poll->head is already set, it's because the file being polled - * uses multiple waitqueues for poll handling (eg one for read, one - * for write). Setup a separate io_poll_iocb if this happens. + * The file being polled uses multiple waitqueues for poll handling + * (e.g. one for read, one for write). Setup a separate io_poll_iocb + * if this happens. */ - if (unlikely(poll->head)) { + if (unlikely(pt->nr_entries)) { struct io_poll_iocb *poll_one = poll; /* already have a 2nd entry, fail a third attempt */ @@ -5027,7 +5028,7 @@ static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt, *poll_ptr = poll; } - pt->error = 0; + pt->nr_entries++; poll->head = head; if (poll->events & EPOLLEXCLUSIVE) @@ -5104,9 +5105,12 @@ static __poll_t __io_arm_poll_handler(struct io_kiocb *req, ipt->pt._key = mask; ipt->req = req; - ipt->error = -EINVAL; + ipt->error = 0; + ipt->nr_entries = 0; mask = vfs_poll(req->file, &ipt->pt) & poll->events; + if (unlikely(!ipt->nr_entries) && !ipt->error) + ipt->error = -EINVAL; spin_lock_irq(&ctx->completion_lock); if (likely(poll->head)) { -- 2.32.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] io_uring: remove double poll entry on arm failure 2021-07-20 9:50 [PATCH 0/2] double poll fixes Pavel Begunkov 2021-07-20 9:50 ` [PATCH 1/2] io_uring: explicitly count entries for poll reqs Pavel Begunkov @ 2021-07-20 9:50 ` Pavel Begunkov 2021-07-20 13:50 ` [PATCH 0/2] double poll fixes Jens Axboe 2 siblings, 0 replies; 4+ messages in thread From: Pavel Begunkov @ 2021-07-20 9:50 UTC (permalink / raw) To: Jens Axboe, io-uring; +Cc: asml.silence __io_queue_proc() can enqueue both poll entries and still fail afterwards, so the callers trying to cancel it should also try to remove the second poll entry (if any). For example, it may leave the request alive referencing a io_uring context but not accessible for cancellation: [ 282.599913][ T1620] task:iou-sqp-23145 state:D stack:28720 pid:23155 ppid: 8844 flags:0x00004004 [ 282.609927][ T1620] Call Trace: [ 282.613711][ T1620] __schedule+0x93a/0x26f0 [ 282.634647][ T1620] schedule+0xd3/0x270 [ 282.638874][ T1620] io_uring_cancel_generic+0x54d/0x890 [ 282.660346][ T1620] io_sq_thread+0xaac/0x1250 [ 282.696394][ T1620] ret_from_fork+0x1f/0x30 Cc: [email protected] Fixes: 18bceab101add ("io_uring: allow POLL_ADD with double poll_wait() users") Reported-and-tested-by: [email protected] Signed-off-by: Pavel Begunkov <[email protected]> --- fs/io_uring.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/io_uring.c b/fs/io_uring.c index 6668902cf50c..6486b54a0f62 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -5113,6 +5113,8 @@ static __poll_t __io_arm_poll_handler(struct io_kiocb *req, ipt->error = -EINVAL; spin_lock_irq(&ctx->completion_lock); + if (ipt->error) + io_poll_remove_double(req); if (likely(poll->head)) { spin_lock(&poll->head->lock); if (unlikely(list_empty(&poll->wait.entry))) { -- 2.32.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2] double poll fixes 2021-07-20 9:50 [PATCH 0/2] double poll fixes Pavel Begunkov 2021-07-20 9:50 ` [PATCH 1/2] io_uring: explicitly count entries for poll reqs Pavel Begunkov 2021-07-20 9:50 ` [PATCH 2/2] io_uring: remove double poll entry on arm failure Pavel Begunkov @ 2021-07-20 13:50 ` Jens Axboe 2 siblings, 0 replies; 4+ messages in thread From: Jens Axboe @ 2021-07-20 13:50 UTC (permalink / raw) To: Pavel Begunkov, io-uring On 7/20/21 3:50 AM, Pavel Begunkov wrote: > 2/2 is about recent syzbot report, 1/2 is just a small additional fix > > Pavel Begunkov (2): > io_uring: explicitly count entries for poll reqs > io_uring: remove double poll entry on arm failure > > fs/io_uring.c | 18 ++++++++++++------ > 1 file changed, 12 insertions(+), 6 deletions(-) Applied, thanks. -- Jens Axboe ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2021-07-20 13:54 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-07-20 9:50 [PATCH 0/2] double poll fixes Pavel Begunkov 2021-07-20 9:50 ` [PATCH 1/2] io_uring: explicitly count entries for poll reqs Pavel Begunkov 2021-07-20 9:50 ` [PATCH 2/2] io_uring: remove double poll entry on arm failure Pavel Begunkov 2021-07-20 13:50 ` [PATCH 0/2] double poll fixes Jens Axboe
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox