fs/fuse/inode.c | 3 +++ 1 file changed, 3 insertions(+)
fuse_opt_fd() stored the fuse device in ctx->fud and bumped its refcount
unconditionally:
ctx->fud = fuse_dev_grab(file);
If fd= is given twice (two fsconfig FSCONFIG_SET_FD calls), the second
call overwrites ctx->fud and grabs the new device, while the reference
taken on the first device is never released - a permanent refcount leak
that pins the first fuse_dev until reboot.
Reject a second fd= outright. ctx is zeroed on allocation, so a non-NULL
ctx->fud reliably means the option was already processed.
Fixes: d42eb23b2ef9 ("fuse: don't require /dev/fuse fd to be kept open during mount")
Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
---
fs/fuse/inode.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 455c7feba057..2372e6ed333f 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -791,6 +791,9 @@ static int fuse_opt_fd(struct fs_context *fsc, struct file *file)
{
struct fuse_fs_context *ctx = fsc->fs_private;
+ if (ctx->fud)
+ return invalfc(fsc, "Multiple fd specified");
+
if (file->f_op != &fuse_dev_operations)
return invalfc(fsc, "fd is not a fuse device");
/*
--
2.43.7
On Tue, 11 Aug 2026 at 06:54, Baokun Li <libaokun@linux.alibaba.com> wrote:
>
> fuse_opt_fd() stored the fuse device in ctx->fud and bumped its refcount
> unconditionally:
>
> ctx->fud = fuse_dev_grab(file);
>
> If fd= is given twice (two fsconfig FSCONFIG_SET_FD calls), the second
> call overwrites ctx->fud and grabs the new device, while the reference
> taken on the first device is never released - a permanent refcount leak
> that pins the first fuse_dev until reboot.
>
> Reject a second fd= outright. ctx is zeroed on allocation, so a non-NULL
> ctx->fud reliably means the option was already processed.
>
> Fixes: d42eb23b2ef9 ("fuse: don't require /dev/fuse fd to be kept open during mount")
> Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
Applied, thanks.
Miklos
On 8/11/26 12:53 PM, Baokun Li wrote:
> fuse_opt_fd() stored the fuse device in ctx->fud and bumped its refcount
> unconditionally:
>
> ctx->fud = fuse_dev_grab(file);
>
> If fd= is given twice (two fsconfig FSCONFIG_SET_FD calls), the second
> call overwrites ctx->fud and grabs the new device, while the reference
> taken on the first device is never released - a permanent refcount leak
> that pins the first fuse_dev until reboot.
>
> Reject a second fd= outright. ctx is zeroed on allocation, so a non-NULL
> ctx->fud reliably means the option was already processed.
>
> Fixes: d42eb23b2ef9 ("fuse: don't require /dev/fuse fd to be kept open during mount")
> Signed-off-by: Baokun Li <libaokun@linux.alibaba.com>
LGTM.
Reviewed-by: Jingbo Xu <jefflexu@linux.alibaba.com>
> ---
> fs/fuse/inode.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
> index 455c7feba057..2372e6ed333f 100644
> --- a/fs/fuse/inode.c
> +++ b/fs/fuse/inode.c
> @@ -791,6 +791,9 @@ static int fuse_opt_fd(struct fs_context *fsc, struct file *file)
> {
> struct fuse_fs_context *ctx = fsc->fs_private;
>
> + if (ctx->fud)
> + return invalfc(fsc, "Multiple fd specified");
> +
> if (file->f_op != &fuse_dev_operations)
> return invalfc(fsc, "fd is not a fuse device");
> /*
--
Thanks,
Jingbo
© 2016 - 2026 Red Hat, Inc.