# DF-3998 — Unclamped phase offset in the envy24ht DMA emulators (DF-3996 twin)

**File:** `sys/dev/sound/pci/envy24ht.c` (pass 2)
**Class:** kernel memory disclosure (record direction, unprivileged) + latent
kernel heap OOB write (play direction) + 1-element OOB write past `ch->data`.

## Reproduce

```
scp -F dfbsd-qemu/config emldmaht_harness.c dfbsd-maxx:/tmp/
vm.sh run_user 'cc -O2 -Wall -o /tmp/emldmaht_harness /tmp/emldmaht_harness.c && /tmp/emldmaht_harness'
vm.sh run_user '/tmp/emldmaht_harness hard'     # guard-page proof
# fixed variant:
vm.sh run_user 'cc -O2 -Wall -o /tmp/emldmaht_fixed /tmp/emldmaht_harness_fixed.c && /tmp/emldmaht_fixed && /tmp/emldmaht_fixed hard'
```

## Expected (baseline)

```
[C] 2nd rec ch (num=2, slot=-6) START: ptr=4087 blk=8 -> offset=4088 (ssize=2048)
  [C] user stream received 12 samples from BEFORE rbuf, 1 from PAST rbuf end
         first leaked: data[17] = 0xbe06 (low half of kernel-heap ...)
         data-side OOB write: data16[8192] = 0xfee9 (one element past ch->data)
[D] play twin p16sl (LATENT, 2nd play ch): offset=4064 -> 2 sample32 entries
    written past pbuf end, first at +130024 bytes (value 0xb9b90000)
HARD: SIGSEGV at first OOB read past rbuf end (offset=4088) - arithmetic proven
```

Fixed variant: all counts 0, no fault (`fix_run.log`).

## Files

- `emldmaht_harness.c` — verbatim driver code + trigger-offset formula
- `emldmaht_harness_fixed.c` — same code with fix.diff applied (+DF-3999 slot clamp)
- `build.log` / `run.log` / `run.2.log` / `run.hard.log` / `fix_run.log` / `env.txt`
- `fix.diff` — git-apply-able fix against `sys/dev/sound/pci/envy24ht.c`

Live `/dev/dsp` trigger is hardware-gated: the QEMU guest has no ICE1724
(1412:1724) device (`env.txt`: envy24-pci-devs=0). The harness runs the exact
kernel constants and verbatim code paths; the arithmetic is deterministic.
