# DF-0782 — PoC & Reproduction

**Integer overflow in `fuse_vop_write` at offset near INT64_MAX → KKASSERT panic via negative newsize**
(`sys/vfs/fuse/fuse_vnops.c:1469` / `:1529` / `fuse_reg_resize` `:1970`)

Medium severity.  CWE-190 Integer Overflow.  CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H

## What the bug is

`fuse_vop_write()` computes `newsize = uio->uio_offset + uio->uio_resid`
(`:1469`) where `uio_offset` is `off_t` (signed int64) and `uio_resid` is
`size_t` (unsigned).  For an offset near `INT64_MAX` the sum wraps to
`0x8000000000000000` (INT64_MIN).  A subsequent clamp
(`if (newsize < oldsize) newsize = oldsize`, `:1470`) masks it, so the
`FUSE_MAXFILESIZE`/`RLIMIT` checks pass.  Inside the write loop the size is
recomputed without the clamp (`:1529`) and `fuse_reg_resize(vp, INT64_MIN, 0)`
is called, hitting `KKASSERT(newsize >= 0)` (`:1972`) — which is **always
compiled in** because `fuse.h:31-33` force-`#define`s `INVARIANTS` for the
whole FUSE module.  Result: deterministic kernel panic (DoS).

`fuse_vop_read()` has `if (uio->uio_offset < 0) return EINVAL;` at `:1338`;
`fuse_vop_write()` does **not** — the asymmetry this finding reports.

## Impact

Local DoS (kernel panic), reachable from an **unprivileged** user who can
write a file on a root-mounted FUSE filesystem (`lseek` near `INT64_MAX` +
`write`).  No surviving memory corruption (the KKASSERT halts before any
write with the overflowed value).  No escalation chain.

## How to reproduce

```
./build.sh          # cc -O0 -g -o fuse_daemon fuse_daemon.c ; cc -O0 -g -o write_trigger write_trigger.c
./run.sh            # as root: kldload fuse, start daemon, mount; then as maxx: write at 0x7FFFFFFFFFFFFFF0
```

`run.sh` is root-driven: it loads `fuse.ko`, starts `fuse_daemon` (which
opens `/dev/fuse` and mounts `/mnt/fuse`), then `su -m maxx` runs
`write_trigger /mnt/fuse/target`.  Expected on the **unpatched** kernel:
the `write()` never returns; the guest panics:

```
panic: assertion "newsize >= 0" failed in fuse_reg_resize at fuse_vnops.c:1970
fuse_reg_resize() at fuse_reg_resize+0xd9
fuse_vop_write() at fuse_vop_write+0x322
```

On the **patched** kernel (apply `fix.diff`, rebuild `fuse.ko`): `write`
returns `EFBIG` (errno 27, "File too large"), no panic.

## Preconditions

- FUSE is module-only (`optional fuse`, not in `X86_64_GENERIC`); `kldload
  fuse` requires root.
- `/dev/fuse` is `root:operator 0660` (`fuse_device.c:313`); `mount` needs
  `SYSCAP_NOMOUNT_FUSE` (root).  So the daemon/mount setup is root-only
  (matches the finding's stated gates, same as DF-0780/0781).
- The **trigger** (the actual overflow) is an unprivileged `lseek`+`write` —
  realistic model: admin has mounted a FUSE filesystem; any user with write
  access to a file on it can DoS the kernel.

## Files

- `fuse_daemon.c`   — benign raw `/dev/fuse` daemon (serves one writable file)
- `write_trigger.c` — unprivileged trigger (lseek near INT64_MAX + write 16)
- `build.sh` / `run.sh`
- `fix.diff`        — the validated fix (add offset/overflow guards to fuse_vop_write)
- `VERDICT.md`      — full analysis
- `panic.txt`       — kernel panic signature (proof)
- `run.log`/`run.3.log` — baseline (unpatched) runs (panic)
- `fix_run.log`     — patched runs (EFBIG, no panic)
- `fix_build.log`   — single-fix fuse.ko build log
- `env.txt` / `manifest.json`
