From: "Darrick J. Wong" <djwong@kernel.org>
To: Zhihao Cheng <chengzhihao1@huawei.com>
Cc: miklos@szeredi.hu, linux-fsdevel@vger.kernel.org,
linux-kernel@vger.kernel.org, yangerkun@huawei.com,
yi.zhang@huawei.com, fuse-devel <fuse-devel@lists.linux.dev>
Subject: Re: [PATCH] fuse: virtiofs: fix illegal inode address access in fuse_release_end
Date: Fri, 15 May 2026 14:07:19 -0700 [thread overview]
Message-ID: <20260515210719.GD9568@frogsfrogsfrogs> (raw)
In-Reply-To: <20260514124102.2703313-1-chengzhihao1@huawei.com>
[add fuse-devel]
On Thu, May 14, 2026 at 08:41:02PM +0800, Zhihao Cheng wrote:
> When a submount (e.g. virtiofs with fc->auto_submounts=true) is umounted
> while an async RELEASE request is still pending, an illegal inode address
> accessing occurs in fuse_release_end()->iput().
>
> Trigger process:
> 1. virtiofs has a submount; user opens and closes a file under it
> 2. Close calls fuse_file_put() with sync=false, sending RELEASE
> asynchronously
> 3. fuse_release_end() is scheduled to run later via igrab() holding
> inode ref
> 4. File is freed, mount/dentry refcounts are released
> 5. User umounts the submount; fuse connection detects remaining
> superblock and does NOT flush the connection's requests
> 6. generic_shutdown_super() destroys the superblock and poisons busy
> inodes' inode->i_sb = VFS_PTR_POISON
> 7. Later, fuse_request_end() calls fuse_release_end() which does
> iput(inode)
> 8. iput() accesses inode->i_sb->s_op at the poisoned address, crash!
>
> There are two solutions to fix it:
> Solution A: Hold path reference in fuse_file_put, and put path
> synchronously, which could reintroduce the issue fixed by commit
> 5a18ec176c934 ("fuse: fix hang of single threaded fuseblk filesystem").
>
> Solution B (chosen): Use synchronous RELEASE for auto_submounts (which
> is only supported by virtiofs). The virtiofsd(fuse daemon) and virtiofs
> won't work together under one same kernel instance, so the problem fixed
> by commit 26e5c67deb2e ("fuse: fix livelock in synchronous file put from
> fuseblk workers") won't be brought back in virtiofs.
Does the weird AIO "kernel breaks if you close the fd before all the IOs
complete" behavior happen on virtiofsd?
--D
>
> Fetch a reproducer in https://bugzilla.kernel.org/show_bug.cgi?id=221519.
>
> Fixes: 26e5c67deb2e ("fuse: fix livelock in synchronous file put from fuseblk workers")
> Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
> ---
> fs/fuse/file.c | 19 +++++++++++++------
> 1 file changed, 13 insertions(+), 6 deletions(-)
>
> diff --git a/fs/fuse/file.c b/fs/fuse/file.c
> index c59452d60b8d..a6192b96d861 100644
> --- a/fs/fuse/file.c
> +++ b/fs/fuse/file.c
> @@ -375,13 +375,20 @@ void fuse_file_release(struct inode *inode, struct fuse_file *ff,
> * synchronous RELEASE is allowed (and desirable) in this case
> * because the server can be trusted not to screw up.
> *
> - * Always use the asynchronous file put because the current thread
> - * might be the fuse server. This can happen if a process starts some
> - * aio and closes the fd before the aio completes. Since aio takes its
> - * own ref to the file, the IO completion has to drop the ref, which is
> - * how the fuse server can end up closing its clients' files.
> + * For auto_submounts (e.g. virtiofs), always use synchronous
> + * release to avoid illegal inode address access when umount
> + * happens before async release completes. The async release
> + * holds inode reference via igrab(), but umount can shutdown
> + * superblock and poison inode->i_sb before release ends,
> + * causing crash in fuse_release_end()->iput(). Otherwise,
> + * always use the asynchronous file put because the current
> + * thread might be the fuse server. This can happen if a
> + * process starts some aio and closes the fd before the aio
> + * completes. Since aio takes its own ref to the file, the IO
> + * completion has to drop the ref, which is how the fuse server
> + * can end up closing its clients' files.
> */
> - fuse_file_put(ff, false);
> + fuse_file_put(ff, ff->fm->fc->auto_submounts);
> }
>
> void fuse_release_common(struct file *file, bool isdir)
> --
> 2.52.0
>
prev parent reply other threads:[~2026-05-15 21:07 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-14 12:41 [PATCH] fuse: virtiofs: fix illegal inode address access in fuse_release_end Zhihao Cheng
2026-05-15 21:07 ` Darrick J. Wong [this message]
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=20260515210719.GD9568@frogsfrogsfrogs \
--to=djwong@kernel.org \
--cc=chengzhihao1@huawei.com \
--cc=fuse-devel@lists.linux.dev \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=yangerkun@huawei.com \
--cc=yi.zhang@huawei.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox