Re: [PATCH v2] fuse: avoid 32-bit prune notification count wrap
From: Joanne Koong
Date: Tue Jun 09 2026 - 23:25:56 EST
On Tue, Jun 9, 2026 at 5:38 PM Samuel Moelius
<sam.moelius@xxxxxxxxxxxxxxx> wrote:
>
> FUSE_NOTIFY_PRUNE validates the nodeid payload length with:
>
> size - sizeof(outarg) != outarg.count * sizeof(u64)
>
> On 32-bit kernels, size_t is also 32 bits, so the daemon-controlled
> count multiplication can wrap. A prune notification with count
> 0x20000000 and no nodeid payload passes the check, enters the copy
> loop, and asks the device copy path to read nodeids that are not
> present in the userspace write buffer. In QEMU this reaches the
> fuse_copy_fill() BUG_ON(!err) path.
>
> Validate the payload length with array_size() instead. That accepts
> exactly the same valid messages, but avoids wrapping arithmetic before
> the copy loop consumes the count.
>
> Assisted-by: Codex:gpt-5.5-cyber-preview
> Fixes: 3f29d59e92a9 ("fuse: add prune notification")
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Samuel Moelius <sam.moelius@xxxxxxxxxxxxxxx>
> ---
> Changes in v2:
> - Use array_size macro
>
> fs/fuse/dev.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
> index c105aaf9ff5d..0c6d1855003e 100644
> --- a/fs/fuse/dev.c
> +++ b/fs/fuse/dev.c
> @@ -2081,7 +2081,7 @@ static int fuse_notify_prune(struct fuse_conn *fc, unsigned int size,
> if (err)
> return err;
>
> - if (size - sizeof(outarg) != outarg.count * sizeof(u64))
> + if (size - sizeof(outarg) != array_size(outarg.count, sizeof(u64)))
> return -EINVAL;
>
> for (; outarg.count; outarg.count -= num) {
> --
> 2.43.0
>
LGTM. A heads-up: in Miklos's current fuse tree [1], the notify logic
was moved over to a new fs/fuse/notify.c file, so I think you'll
probably need to rebase this onto for-next and resubmit against
notify.c. But this current patch looks great for backporting to
stable.
Reviewed-by: Joanne Koong <joannelkoong@xxxxxxxxx>
Thanks,
Joanne
[1] https://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git/log/?h=for-next