* [PATCH] io_uring/waitid: prevent cancel reference wrap
@ 2026-10-19 15:21 Junyeong Lee
2026-10-19 19:13 ` Jens Axboe
0 siblings, 1 reply; 2+ messages in thread
From: Junyeong Lee @ 2026-10-19 15:21 UTC (permalink / raw)
To: io-uring; +Cc: axboe, greg, linux-kernel, stable
io_waitid packs the cancellation state into bit 31 of ->refs and
uses bits 30:0 as a 31-bit reference counter:
#define IO_WAITID_CANCEL_FLAG BIT(31)
#define IO_WAITID_REF_MASK GENMASK(30, 0)
__io_waitid_cancel() marks a request canceled, then increments the low
bits of ->refs to claim completion ownership. When another path owns the
request, the increment remains even though cancellation returns false.
The request remains discoverable by cancellation, so repeated failed
attempts can wrap the 31-bit reference field to zero. A later cancellation
can claim ownership and complete the request a second time.
Use atomic_fetch_or() when setting the cancel flag and inspect the old flag
value. The first cancel attempt continues to the existing ownership
increment, preserving its wake and issuer handoff semantics. Later attempts
see the cancel flag and return without incrementing the reference field.
This makes repeated failed cancellation attempts idempotent while leaving
the first-cancel state transitions unchanged.
Fixes: f31ecf671ddc ("io_uring: add IORING_OP_WAITID support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Junyeong Lee <jylee5498@gmail.com>
---
io_uring/waitid.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/io_uring/waitid.c b/io_uring/waitid.c
index 2b756017423f..9ad8eadc5b8f 100644
--- a/io_uring/waitid.c
+++ b/io_uring/waitid.c
@@ -154,9 +154,12 @@ static bool __io_waitid_cancel(struct io_kiocb *req, bool copy_si)
/*
* Mark us canceled regardless of ownership. This will prevent a
- * potential retry from a spurious wakeup.
+ * potential retry from a spurious wakeup. Only the first cancel
+ * attempt should take a reference for the ownership handoff.
*/
- atomic_or(IO_WAITID_CANCEL_FLAG, &iw->refs);
+ if (atomic_fetch_or(IO_WAITID_CANCEL_FLAG, &iw->refs) &
+ IO_WAITID_CANCEL_FLAG)
+ return false;
/* claim ownership */
if (atomic_fetch_inc(&iw->refs) & IO_WAITID_REF_MASK)
--
2.54.0 (Apple Git-157)
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] io_uring/waitid: prevent cancel reference wrap
2026-10-19 15:21 [PATCH] io_uring/waitid: prevent cancel reference wrap Junyeong Lee
@ 2026-10-19 19:13 ` Jens Axboe
0 siblings, 0 replies; 2+ messages in thread
From: Jens Axboe @ 2026-10-19 19:13 UTC (permalink / raw)
To: io-uring, Junyeong Lee; +Cc: greg, linux-kernel, stable
On Tue, 20 Oct 2026 00:21:00 +0900, Junyeong Lee wrote:
> io_waitid packs the cancellation state into bit 31 of ->refs and
> uses bits 30:0 as a 31-bit reference counter:
>
> #define IO_WAITID_CANCEL_FLAG BIT(31)
> #define IO_WAITID_REF_MASK GENMASK(30, 0)
>
> __io_waitid_cancel() marks a request canceled, then increments the low
> bits of ->refs to claim completion ownership. When another path owns the
> request, the increment remains even though cancellation returns false.
> The request remains discoverable by cancellation, so repeated failed
> attempts can wrap the 31-bit reference field to zero. A later cancellation
> can claim ownership and complete the request a second time.
>
> [...]
Applied, thanks!
[1/1] io_uring/waitid: prevent cancel reference wrap
commit: 98787d3fa4e99564d2b2bc21255b21f670c450d0
Best regards,
--
Jens Axboe
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-19 19:13 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-19 15:21 [PATCH] io_uring/waitid: prevent cancel reference wrap Junyeong Lee
2026-10-19 19:13 ` Jens Axboe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®