# DF-3027 verdict — REPRODUCED (kernel-stack info leak, unprivileged)

## Root cause (path:line)

* `sys/vfs/fuse/fuse_vnops.c:312-316` — `fuse_vop_getattr` returns 0 with
  `*a_vap` untouched for dead mounts and ENOSYS-latched FUSE_GETATTR.
* `sys/vfs/fuse/fuse_vnops.c:329-338` — `-ENOSYS` reply converted to success
  (`error = 0`) without filling `*a_vap`.
* `sys/kern/vfs_vnops.c:833-845` — `vn_stat` stack-allocates `struct vattr
  vattr;` uninitialized, and on success copies `vap` fields into the user's
  `struct stat` (`st_ino/st_uid/st_gid/st_size/st_nlink/st_{a,m,c}timespec`).

## How it was reproduced (guest DragonFly 6.5-DEVELOPMENT #0, X86_64_GENERIC)

1. root mounts a synthetic FUSE fs via `fuse_daemon normal /mnt/fuse`.
2. unprivileged user `maxx` opens `/mnt/fuse/target` (attrs served normally).
3. daemon is SIGKILLed -> cdevpriv dtor -> `fuse_mount_kill` -> `dead=1`.
4. maxx grooms his kernel stack: `fstat(marker_fd)` puts a valid `va_type`
   (VREG) into the exact `vn_stat` vattr slot; the `su`/shell machinery (and
   `readlink` in ptrs-mode) leaves kernel pointers in adjacent slot bytes.
5. maxx `fstat(fuse_fd)` -> `fuse_vop_getattr` returns 0 instantly (dead path)
   -> `vn_stat` copies the stale stack slot to userspace -> **success with
   kernel pointer fields**.

Observed (3/3 runs, values differ per run — live kernel data):

    mt=fffff80118c0b7d8.fffff8011712d300 ct=fffff80117172780.fffff80118c0b8f8
    mt=fffff801166db7d8.fffff8011712ff00 ct=fffff80117172c00.fffff801166db8f8
    mt=fffff801183df7d8.fffff80117132780 ct=fffff80117173080.fffff801183df8f8

`0xfffff801....` / `0xfffff800....` are kernel virtual addresses (KVA) —
heap/vm-object pointers left by earlier syscall frames.  An earlier variant
also demonstrated a deterministic **marker echo**: the fuse file reported the
*previous* fstat's attributes verbatim (probe4, evidence in transcript), the
cleanest possible proof of the uninitialized read.

Additional observation: the same uninitialized vattr feeds permission
evaluation — `ls: /mnt/fuse: Bad file descriptor` (vn_stat default EBADF on
garbage va_type) and `stat: Permission denied` (garbage va_mode) were both
observed, i.e. the garbage also drives access decisions.

## Impact

Unprivileged kernel-stack disclosure, ~100 bytes/call, repeatable at will,
content groomable (kernel pointers demonstrated).  KASLR-defeating primitive
on kernels with KASLR; heap-address oracle for other exploits.

## Fix validation

`fix.diff` (zero + type-fill `*a_vap` on every success-without-attrs path)
applied in the guest, module rebuilt, same PoC re-run: `LEAK` returns zeroed
attributes (`ino=0 sz=0 ptrlike=0`), no marker echo, guest healthy.
fix_status=fixed.
