# DF-4848 — VERDICT

**status: reproduced** (feeder level, real unmodified code on the audit guest)
**primitive:** OOB read+write of up to align−1 bytes past the destination
window; then `count` underflow to ~4GiB and a wild second-pass source fill
that can write up to bufsoft-ready (tens of KB) of user-controlled bytes past
the window end
**confidence: certain** (harness-proven on pristine code; underflow re-arm
observed directly)

## Root cause

`feeder_volume.c:277`:
```c
j = SND_FXDIV(FEEDER_FEED(f->source, c, dst, count, source), info->align);
```
The dividend is the SOURCE RETURN — not a kernel-chosen aligned value but the
byte count actually delivered, which for the root feeder is
`min(count, sndbuf_getready(src))` (feeder.c:466) — i.e. exactly what the
unprivileged user has `write()`n into the channel. The generated `SND_FXDIV`
misrounds UP (floor+1) for bad-residue dividends within the claimed domain
(first bad x: align 6 → 32768, align 10 → 16384, align 12 → 8195, align 14 →
5473; see DF-4846 for the exhaustive enumeration). Then:

- `:282` `apply(vol, matrix, ch, dst, j)` processes (ret/align + 1) frames —
  reading and writing one frame past the fed data; when ret == count the
  extra frame is past the destination window (canary REAR hit at exactly
  count+1 in the harness).
- `:284-286` `j *= align; count -= j;` with j = ret+delta > count ⇒ count
  wraps to ~4294967295 ⇒ `while (count != 0)` re-arms ⇒
  `FEEDER_FEED(f->source, c, dst+overrun, ~4GiB, ...)` — the source (root)
  then writes `min(4GiB, ready)` bytes at `dst+overrun`, i.e. up to the
  bufsoft-ready amount of user-audio bytes PAST the window end. In-kernel the
  window is the caller's scratch (`to->tmpbuf` or the format feeder's
  in-place tail): a directed heap overflow whose length the attacker paces
  via write() sizes and whose content is the attacker's audio samples.

## Reproduction (guest, pristine file)

`ffvol` (`vol.log`): `checks=21604 failures=2810`, decisive:

```
FAIL[T1 write] ch=3 align=6 count=32771 ret=32772 REAR guard (write past window) maxoff=32772
```

T2 (underflow re-arm) is detected via the source-ask audit (`wild` pointer /
`maxask > window`); the T1 lines above are the direct window overruns.

## Kernel reachability

- feeder_volume is inserted for every vchan child by default:
  `feeder_chain.c:713-716` (`SD_F_VPC` + `snd_maxautovchans = 16` default,
  sound.c:62), and for soft-pcm-volume devices.
- Channel counts 3/5/6/7 (align 6/10/12/14) are unprivileged
  SNDCTL_DSP_CHANNELS choices (dsp.c clamps ≤ 8 — 3,5,6,7 all legal).
- The dividend is user-paced: write sizes choose `ready` at feed time.
- The underflow second pass writes past the window into adjacent kernel
  heap; the harness bounds it to the guarded arena to log instead of
  corrupting the guest process.

In-kernel churn (bad-residue pacing on 6ch/7ch vchans, ES1370): no
differential anomaly vs aligned control on this no-INVARIANTS kernel (logs
in the DF-4849 pack) — consistent with DF-4710's experience; the primitive's
observability requires a detector (INVARIANTS/KASAN) the production guest
lacks.

## Fix validation

`fix.diff` (generator): baseline 2810 failures → fixed **0 (ALL PASS)**
(`vol.log` vs `vol_fixed.log`). fix_status: fixed.

## 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.
