# DF-3228 — VERDICT

**Status: REPRODUCED (deterministic) — impact: dos (slow unbounded kernel
heap exhaustion, semi-privileged) — fix VALIDATED in-guest (v2).**

## Root cause

`fuse_device_open()` (fuse_device.c:48-61) kmallocs `struct fuse_mount`
(M_TEMP, refcnt=1) per open and installs it as cdevpriv; the return of
`devfs_set_cdevpriv()` is ignored (fuse_device.c:57). The dtor
`fuse_cdevpriv_dtor()` (fuse_device.c:38-45) frees only
`if (!fuse_cdevpriv_close(fmp))` — but `fuse_cdevpriv_close()` returns
**ENODEV when the fd was never mounted** (`!fmp->devvp`,
fuse_device.c:84-88). Never-mounted open/close therefore drops nothing:
**the fmp allocated at open leaks on every cycle**. Nothing else holds
or frees it (locks are only `mtx_init`'d at mount time,
fuse_vfsops.c:178-180; `cred` only assigned at mount, fuse_vfsops.c:185).

## Guest run (stock `#0` INVARIANTS kernel)

- baseline `vmstat -m | grep temp`: **472 allocs / 335K**
- after `./df3228 100000` (loop still running when sampled):
  **46.1K allocs / 20.3MB** — ~256 B leaked per cycle (≈
  sizeof(struct fuse_mount)), linear and unbounded (run.log).
- Reachability: `/dev/fuse` is `crw-rw---- root operator 0660`
  (fuse_device.c:313-314) — operator group or root; slow
  memory-exhaustion DoS (CWE-401). Low severity.

## Fix iteration (documented honestly)

- **v1** ("always fuse_mount_free()"): WRONG — validated to panic:
  `fuse_mount_free()` → `crfree(fmp->cred)` with `cred == NULL`
  (never-mounted) → `Fatal trap 12 ... crfree+0xc` (fix_run.log +
  serial log, guest reset). This is itself evidence that the pre-fix
  code could never have taken this path.
- **v2** (fix.diff): dtor distinguishes `fmp->devvp` (mounted: kill +
  shared `fuse_mount_free()`) from never-mounted (refcnt==1, no locks,
  no cred → plain `kfree(fmp, M_TEMP)`); `fuse_device_open` checks
  `devfs_set_cdevpriv()` and frees on failure.
- v2 validated: **20000 cycles → temp identical (472 allocs/335K)
  before/after, no panic** (fix_run2.log); fuse module otherwise
  regression-checked by the DF-3227 patched runs (mount/INIT/statfs/
  read/reply/unmount all healthy on the same module build).

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
