[linux-next] fuse: avoid double pqueue allocation in fuse_dev_alloc_install

Morduan Zang posted 1 patch 2 months ago
fs/fuse/dev.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
[linux-next] fuse: avoid double pqueue allocation in fuse_dev_alloc_install
Posted by Morduan Zang 2 months ago
From: Morduan <zhangdandan@uniontech.com>

fuse_dev_chan_new() preallocates fch->pq_prealloc. After dca5bba8d17f,
fuse_dev_install() transfers that queue to fuse_dev_install_with_pq(),
which expects fud->pq.processing to still be NULL.

The CUSE open path still goes through fuse_dev_alloc_install(), which
unconditionally uses fuse_dev_alloc() and allocates fud->pq.processing a
second time.  Opening /dev/cuse then triggers
WARN_ON(fud->pq.processing) in fuse_dev_install_with_pq() and panics when
panic_on_warn=1.

If the channel already carries pq_prealloc, allocate the fuse_dev
without a processing queue and let fuse_dev_install() transfer ownership
of the preallocated queue.

Fixes: dca5bba8d17f ("fuse: alloc pqueue before installing fch in fuse_dev")
Reported-by: syzbot+a761f017e231803b82cd@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=a761f017e231803b82cd
Signed-off-by: Zhan Jun <zhanjun@uniontech.com>
---
 fs/fuse/dev.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index 87c0a6e60440..6001163db34e 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -501,7 +501,10 @@ struct fuse_dev *fuse_dev_alloc_install(struct fuse_chan *fch)
 {
 	struct fuse_dev *fud;
 
-	fud = fuse_dev_alloc();
+	if (fch->pq_prealloc)
+		fud = fuse_dev_alloc_no_pq();
+	else
+		fud = fuse_dev_alloc();
 	if (!fud)
 		return NULL;
 
-- 
2.50.1
Re: [linux-next] fuse: avoid double pqueue allocation in fuse_dev_alloc_install
Posted by Miklos Szeredi 2 months ago
On Thu, 16 Apr 2026 at 08:21, Morduan Zang <zhangdandan@uniontech.com> wrote:
>
> From: Morduan <zhangdandan@uniontech.com>
>
> fuse_dev_chan_new() preallocates fch->pq_prealloc. After dca5bba8d17f,
> fuse_dev_install() transfers that queue to fuse_dev_install_with_pq(),
> which expects fud->pq.processing to still be NULL.
>
> The CUSE open path still goes through fuse_dev_alloc_install(), which
> unconditionally uses fuse_dev_alloc() and allocates fud->pq.processing a
> second time.  Opening /dev/cuse then triggers
> WARN_ON(fud->pq.processing) in fuse_dev_install_with_pq() and panics when
> panic_on_warn=1.
>
> If the channel already carries pq_prealloc, allocate the fuse_dev
> without a processing queue and let fuse_dev_install() transfer ownership
> of the preallocated queue.
>
> Fixes: dca5bba8d17f ("fuse: alloc pqueue before installing fch in fuse_dev")
> Reported-by: syzbot+a761f017e231803b82cd@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=a761f017e231803b82cd
> Signed-off-by: Zhan Jun <zhanjun@uniontech.com>

Thanks, this should be fixed since yesterday in for-next.

Checking fch->pq_prealloc is not necessary, since
fuse_dev_alloc_install() has a single callsite: cuse_channel_open().
Since cuse also uses fuse_dev_chan_new(), pq_prealloc is always going
to be set.

Thanks,
Miklos