mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Zhihao Cheng <chengzhihao1@huawei.com>
To: "Darrick J. Wong" <djwong@kernel.org>
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: Mon, 15 Jun 2026 19:08:35 +0800	[thread overview]
Message-ID: <da9772f5-d20c-0efe-2fb8-74f14e8d490b@huawei.com> (raw)
In-Reply-To: <953d1dc7-f1a4-88a8-1db4-0902b902055f@huawei.com>

在 2026/5/16 11:20, Zhihao Cheng 写道:
> 在 2026/5/16 5:07, Darrick J. Wong 写道:
>> [add fuse-devel]
>>

friendly ping
>> 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?
>>
> 
> Hi Darrick,
> IMHO, the problem fixed by commit 26e5c67deb2e1f42a9("fuse: fix livelock 
> in synchronous file put from fuseblk workers") happens as following 
> process:
>     fuse user              fuse daemon
> fd = open(file)
> io_submit_one
>   req->ki_filp = fget(iocb->aio_fildes)
> close(fd) // file->f_ref = 1, file won't be released
>                          process FUSE_WRITE req
>                          write(/dev/fuse, reply)
>                           fuse_request_end
>                            fuse_aio_complete_req
>                             aio_complete_rw
>                              fput(iocb->ki_filp)
>                               task_work_add
>                           task_work_run
>                            __fput
>                             fuse_release
>                              __fuse_simple_request
>                               request_wait_answer
> 
> For viriofs, the user(virtiofs) runs in kernel A(guest), the 
> daemon(virtiofsd) runs kernel B(host), and the fuse_request_end is 
> called by virtio_fs_requests_done_work -> virtio_fs_complete_req_work -> 
> virtio_fs_request_complete, which is under the kworker context(kernel A, 
> guest), so it won't block the daemon thread(kernel B, host).
> 
>> --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
>>>
>>
>> .
>>
> 
> 
> 
> .


  reply	other threads:[~2026-06-15 11:08 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-14 12:41 Zhihao Cheng
2026-05-15 21:07 ` Darrick J. Wong
2026-05-16  3:20   ` Zhihao Cheng
2026-06-15 11:08     ` Zhihao Cheng [this message]
2026-06-15 12:06       ` Miklos Szeredi
2026-06-15 12:16         ` Zhihao Cheng

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=da9772f5-d20c-0efe-2fb8-74f14e8d490b@huawei.com \
    --to=chengzhihao1@huawei.com \
    --cc=djwong@kernel.org \
    --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

all inboxes | Powered by JetHome®