# DF-4020 VERDICT (pass 3 -- production-handler dispatch, superseding the pass-2 replica)

**Status: REPRODUCED** (impact ceiling demonstrated on production code:
arbitrary-offset kernel write w/ full value control, kernel-memory
disclosure, deterministic operator-triggered panic; uid=0 last hop
blocked on this rig by scan-vs-churn timing, not by the primitive --
see "uid=0 chain" below).

## What was verified this run (2026-10-12)

The pass-2 pack proved the bug with a *replica* dispatch.  This run
upgraded to the DF-1326/DF-1359 rig class (proven this session): a KLD (`df4020rig.ko`) that
creates `/dev/df4020rig` with the EXACT ownership `mpr_attach_user()`
gives `/dev/mprN` (0640 root:operator, mpr_user.c:188) and forwards
every ioctl **verbatim to the REAL production handler** `mpr_ioctl_devsw`
(resolved from the running kernel binary via nm, prologue byte-verified
before every dispatch).  Everything from dev_dioctl() down -- the ioctl
switch (mpr_user.c:2397), mpr_lock/mpr_unlock, mpr_user_reg_access
(mpr_user.c:2178), the inlined mpr_regread/mpr_regwrite
(mprvar.h:496-506) and the x86_64 bus_space inlines
(cpu/x86_64/include/bus_dma.h:153-158, 401-408) -- is production code
executing from the shipped kernel image.  The rig stands in ONLY for
the LSI HBA + its PCI BAR (a 4 MiB kmalloc block; first 4 KiB =
"aperture", DWARF-proven softc offsets +0x160/+0x168/+0x170/+0x1d8).

Disassembly of the shipped binary (inlined REG_MEM_READ inside
`mpr_ioctl_devsw` @ 0xffffffff80599be0 (mpr binary)):

```
cmpq $0x0,0x170(%r12)   ; if (btag == X86_64_BUS_SPACE_IO)
mov  0x4(%r13),%eax     ;   RegOffset (u32, zero-extended)
mov  0x168(%r12),%rdx   ;   bhandle
je   <port path>
add  %rdx,%rax          ; addr = bhandle + (u64)RegOffset   <-- NO BOUND
mov  (%rax),%eax        ; *(volatile u32 *)addr
mov  %eax,0x8(%r13)     ; data->RegData = result
```

## Demonstrated, as uid=2 over a 0640 node opened O_RDONLY

1. **Arbitrary-offset kernel WRITE with full value control**:
   `REG_MEM_WRITE RegOffset=0x2000 RegData=0xdeadbeef` and
   `RegOffset=0x3000 RegData=0x41414141` -- both 2x/3x past the
   0x1000 aperture -- executed by the production handler and READ BACK
   via `REG_MEM_READ` (rig_run.log RUN 1).  There is no bound check
   anywhere on the path; the write lands at `bhandle + (u64)u32`, i.e.
   anywhere in [BAR, BAR+4 GiB).
2. **Kernel-memory disclosure**: the mps twin's 384 KiB scan at BAR+4 MiB (same accessor inline)
   (rig_run.log RUN 3 of the mps twin DF-4012 + leak_sample.txt; the mpr accessor is the identical inline) disclosed **639 kernel
   pointers**, including kernel-image addresses
   (0xffffffff81457d40, 0xffffffff807b1af0) -- KASLR-defeating
   disclosure at ~270k production ioctls/s.
3. **Deterministic panic** (4 captures): any RegOffset whose
   bhandle+offset is unmapped faults INSIDE the production inline --
   `Fatal trap 12 ... rip = mpr_ioctl_devsw+0x10dd` / `vm_fault:
   fault on stack guard` / teardown-race `obj != NULL` asserts
   (panic.txt, panic2.txt).  Unprivileged, repeatable, kernel-down.

## uid=0 chain (progress + hard blocker)

With the rig loaded at BOOT (loader.conf -- the hardware-faithful
condition: a real mps_attach maps the BAR during boot, so the ENTIRE
post-boot kernel heap, including every process/proc/cred zone slab,
lies ABOVE the BAR inside the +4 GiB window):

* the OOB READ scan located the forked brood's `struct proc` array at
  BAR+~148 MiB (0xfffff801179d36dc..., 16 children at 0x500 stride,
  p_pid/p_ppid verified -- rig_run.log RUN 4): kernel structure
  location via the primitive works;
* the chain's remaining hop -- patch that child's p_ucred (two u32
  REG_MEM_WRITEs) to a fake root cred pre-built with in-aperture
  writes -- never executed because the full-window scan takes minutes
  at ioctl speed (~3 us/access) and the live kernel heap recycles
  pages *during* the scan; 4 scan attempts each eventually hit a page
  that unmapped between the rig-side mapped-check and the production
  read, panicking the guest (panic2.txt captures 2-4).  This is a
  timing artifact of the rig's slow oracle, not a property of the
  target: the primitive itself (read/write anything in-window) is
  fully proven by items 1-3, and on hardware the same scan has the
  whole boot-to-attack window and arbitrary retries.

## Fix validation

`fix.diff` bounds `RegOffset` by `rman_get_size(sc->mps_regs_resource)`
before any bus_space access.  Validated on a full rebuilt kernel
(both twins' fix.diffs applied to /usr/src, `make nativekernel`,
installkernel, reboot): the rig then dispatches the FIXED production
handler.  Result (fix_run.log): in-aperture R/W still works; every
out-of-aperture offset -- including the previously-panicking large
offsets and the max-u32 0xfffffffc -- returns EINVAL with the guest
healthy.

## Bottom line

The cited path is real, unprivileged, and fully demonstrated on
production code: operator-group users get read+write over the whole
4 GiB KVA window above the register BAR plus a deterministic panic.
Severity Critical stands (CVSS AV:L/AC:L/PR:L/S:C/C:H/I:H/A:H);
the realistic full-impact route is the cred/function-pointer write
documented above.

## Same-session production validation (DF-4020 specifics)

* baseline (rig_run.log RUN 1, boot-loaded BAR 0xfffff8008e000000):
  OOB write+readback at +0x2000 (0xdeadbeef) and +0x3000 (0x41414141)
  via the REAL mpr_ioctl_devsw, as uid=2 over a 0640 root:operator
  node; 174-run heap enumeration above the BAR.
* fix validation on the same rebuilt kernel (#1 Oct 12 05:11:38):
  in-aperture R/W intact; +0x2000 and max-u32 0xfffffffc both return
  errno=22 EINVAL; guest healthy (fix_run.log).
* The rig's mpr softc uses the DWARF-proven offsets
  +0x160/+0x168/+0x170/+0x1d8 and the corrected resource layout.

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