From: Jun Yang <littleddfu@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>, fuse-devel@lists.linux.dev
Cc: Zhao Chen <winters.zc@antgroup.com>,
linux-kernel@vger.kernel.org, Jun Yang <junvyyang@tencent.com>,
stable@kernel.org, TencentOS Corvus AI <corvus@tencent.com>
Subject: [PATCH 2/2] fuse: don't queue an interrupt for a request that is back on fiq->pending
Date: Tue, 4 Aug 2026 17:17:09 +0800 [thread overview]
Message-ID: <20260804091757.503476-3-junvyyang@tencent.com> (raw)
In-Reply-To: <20260804091757.503476-1-junvyyang@tencent.com>
fuse_dev_queue_interrupt() links a request onto fiq->interrupts based on
an FR_SENT observation its callers make without fiq->lock: in
request_wait_answer(), in fuse_dev_do_read() after setting FR_SENT, and in
fuse_dev_do_write() on an interrupt reply with -EAGAIN.
fuse_chan_resend() invalidates that observation: under fiq->lock it clears
FR_SENT, sets FR_PENDING and splices the request back onto fiq->pending. A
caller that sampled FR_SENT just before that happens links the request onto
fiq->interrupts just after, so the request ends up queued on fiq->pending
*and* on fiq->interrupts.
That combination is a problem, because a request on fiq->pending can be
released without ever going through fuse_request_end(). A waiter whose wait
is interrupted calls fuse_remove_pending_req(), which sees FR_PENDING,
unlinks the request from fiq->pending and drops the queue's reference;
fuse_chan_send() then drops the last one. Unlike fuse_request_end(), that
path has no FR_INTERRUPTED cleanup, so the request can be released while
still linked on fiq->interrupts, and the next fuse_dev_do_read() walks it
in fuse_read_interrupt().
Re-check FR_SENT in fuse_dev_queue_interrupt() under fiq->lock, which is
the lock fuse_chan_resend() holds when it clears it. This restores the
invariant "FR_PENDING set => intr_entry not linked", both sides of it now
being taken under fiq->lock. No interrupt is lost: the request is going
back to the daemon, and fuse_dev_do_read() re-queues the interrupt once it
has set FR_SENT again.
Confirmed on v7.2-rc6 (075b74841bd0).
Fixes: 760eac73f9f6 ("fuse: Introduce a new notification type for resend pending requests")
Cc: stable@kernel.org
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Assisted-by: tencentos-corvus-ai:kimi-k3
Signed-off-by: Jun Yang <junvyyang@tencent.com>
---
A KASAN reproducer for this issue is available if requested.
fs/fuse/dev.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index e62c7ed8bcf4..c4df1d4abd33 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -240,6 +240,11 @@ void fuse_dev_queue_forget(struct fuse_iqueue *fiq,
void fuse_dev_queue_interrupt(struct fuse_iqueue *fiq, struct fuse_req *req)
{
spin_lock(&fiq->lock);
+ /* fuse_chan_resend() may have put the request back on fiq->pending */
+ if (!test_bit(FR_SENT, &req->flags)) {
+ spin_unlock(&fiq->lock);
+ return;
+ }
if (list_empty(&req->intr_entry)) {
list_add_tail(&req->intr_entry, &fiq->interrupts);
/*
--
2.43.7
next prev parent reply other threads:[~2026-08-04 9:18 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-04 9:17 [PATCH 0/2] fuse: fix request lifetime races in the resend path Jun Yang
2026-08-04 9:17 ` [PATCH 1/2] fuse: set FR_PENDING under fiq->lock in fuse_chan_resend() Jun Yang
2026-08-14 7:23 ` Tang Yizhou
2026-08-17 10:25 ` Jun Yang
2026-08-17 13:30 ` Tang Yizhou
2026-08-18 8:39 ` Miklos Szeredi
2026-08-18 9:55 ` Yizhou Tang
2026-08-04 9:17 ` Jun Yang [this message]
2026-08-14 8:49 ` [PATCH 2/2] fuse: don't queue an interrupt for a request that is back on fiq->pending Tang Yizhou
2026-08-14 6:19 ` [PATCH 0/2] fuse: fix request lifetime races in the resend path Tang Yizhou
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260804091757.503476-3-junvyyang@tencent.com \
--to=littleddfu@gmail.com \
--cc=corvus@tencent.com \
--cc=fuse-devel@lists.linux.dev \
--cc=junvyyang@tencent.com \
--cc=linux-kernel@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=stable@kernel.org \
--cc=winters.zc@antgroup.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.