[BUG] fuse: KASAN slab-use-after-free in fuse_uring_copy_to_ring()

From: 김민서

Date: Mon Jun 01 2026 - 04:29:07 EST


Hello,

I am reporting a FUSE-over-io_uring bug reproduced on upstream v7.1-rc6
with KASAN enabled. The bug was found with a local syzkaller setup.

Target file: fs/fuse/dev_uring.c
Subsystem: FUSE
Git tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Git head: e43ffb69e0438cddd72aaa30898b4dc446f664f8
Kernel release: v7.1-rc6

Observed crash:

BUG: KASAN: slab-use-after-free in fuse_uring_copy_to_ring+0x20b/0x230

The same issue was also observed on v7.1-rc5:

Git head: e7ae89a0c97ce2b68b0983cd01eda67cf373517d

Root cause analysis:

The crash appears to be caused by a lifetime/state mismatch between
struct fuse_req and the FUSE io_uring ring entry state machine.

The KASAN report shows that the affected object is a struct fuse_req from
the fuse_request cache. It is allocated in the FUSE open path via
fuse_request_alloc() and freed later in the same open path via
fuse_put_request(), but it is subsequently accessed from
fuse_uring_copy_to_ring() while FUSE io_uring is sending a request to the
userspace ring.

The preceding warning in fuse_ring_ent_set_commit() also shows an unexpected
ring entry state:

WARNING: fs/fuse/dev_uring.c:865
fuse: qid=0 commit_id 4 state 3

My current guess is that an error/teardown/commit-and-fetch sequence may
leave a stale fuse_req reachable from the FUSE io_uring ring/request queues.

Reproducer:

C reproducer:
https://raw.githubusercontent.com/neck392/linux-kernel-bug-reports/main/fuse-uring-uaf-v7.1-rc6/repro_fuse_uring_uaf_userns.c

Full symbolized console log:
https://raw.githubusercontent.com/neck392/linux-kernel-bug-reports/main/fuse-uring-uaf-v7.1-rc6/clean_userns_report_rc6.txt

Kernel config:
https://raw.githubusercontent.com/neck392/linux-kernel-bug-reports/main/fuse-uring-uaf-v7.1-rc6/kernel-config-v7.1-rc6.config

Key config options:

CONFIG_FUSE_FS=y
CONFIG_FUSE_IO_URING=y
CONFIG_FUSE_PASSTHROUGH=y
CONFIG_IO_URING=y
CONFIG_KASAN=y
CONFIG_KASAN_VMALLOC=y
CONFIG_KASAN_EXTRA_INFO=y
CONFIG_USER_NS=y

Runtime conditions:

fuse.enable_uring=1
unprivileged user namespaces enabled
/dev/fuse accessible to the reproducer

I verified the C reproducer by running it as uid 1000; it then creates a
user namespace. In my minimal QEMU rootfs, /dev/fuse was chmod 0666 before
running the reproducer because the device node is root:root 0600 by default.

Without a user namespace, uid 1000 can open /dev/fuse in this setup but
mount(fuse) fails with EPERM, so the provided reproducer uses CLONE_NEWUSER.

Brief KASAN excerpt:

BUG: KASAN: slab-use-after-free in fuse_uring_copy_to_ring+0x20b/0x230
Read of size 8 at addr ffff888009ecc698 by task repro_minimal_u/153

Allocated by task 153:
fuse_request_alloc
fuse_get_req
__fuse_simple_request
fuse_send_open
fuse_file_open
fuse_do_open
fuse_dir_open
do_dentry_open
vfs_open
path_openat
do_file_open
do_sys_openat2
__x64_sys_openat

Freed by task 153:
fuse_put_request
__fuse_simple_request
fuse_send_open
fuse_file_open
fuse_do_open
fuse_dir_open
do_dentry_open
vfs_open
path_openat
do_file_open
do_sys_openat2
__x64_sys_openat

If you fix this issue, please add the following tag to the commit:

Reported-by: Minseo Kim <neck3922@xxxxxxxxx>

If you need anything else, please let me know.

Best regards,
Minseo Kim