# DF-3932 verdict narrative

## Reproduced?
The *sink* is reproduced on the audit guest kernel: executing the exact
`kmalloc(0xffffffff80000000, M_DEVBUF, M_INTWAIT)` that `mly_user_command`
performs for `DataTransferLength == INT_MIN` panics the kernel with
"kmem_slab_alloc(): kernel_map ran out of space!" (panic.txt; trace
fire_sysctl → _kmalloc → kmem_slab_alloc).  The *trigger* (MLYIO_COMMAND
ioctl on /dev/mly0) is hardware-gated — no mly controller in the guest — so
the finding as a whole is filed inconclusive (mechanism proven, instance
hardware-gated), following the DF-3715 family convention.

## Root cause chain (path:line)

1. mlyio.h:42 — `DataTransferLength` is a plain signed `int`, fully
   user-controlled through the 0600 root:operator control device.
2. mly.c:2889
   ```c
   mc->mc_length = (uc->DataTransferLength >= 0) ?
       uc->DataTransferLength : -uc->DataTransferLength;
   ```
   For INT_MIN the negation wraps (int overflow) and the sign-extension into
   `size_t mc_length` yields 0xFFFFFFFF80000000 — which satisfies
   `mc->mc_length > 0` at mly.c:2890.
3. mly.c:2891 `mc->mc_data = kmalloc(mc->mc_length, M_DEVBUF, M_INTWAIT);`
   → kern_slaballoc.c:942 `size >= ZoneLimit` → kmem_slab_alloc →
   vm_map_findspace fails → kern_slaballoc.c:1724 panic (M_INTWAIT has no
   M_NULLOK).  **Proven on-guest** (panic.txt).
4. Secondary defects in the same size handling (source-certain, folded here):
   - No upper bound at all: any root user can request up to 2GB-1 of WIRED
     kernel memory per ioctl (M_INTWAIT → kmem_slab_alloc wires it),
     repeatable — trivial kernel-memory exhaustion by the management daemon.
   - mly.c:1850 ignores bus_dmamap_load()'s error; on this DFly bus_dma the
     callback is always invoked (busdma_machdep.c:767-805) with the error
     passed in, and mly_map_command_sg (mly.c:1781) ignores its `error`
     argument too — a failed/partial load (EFBIG for >MAXBSIZE buffers,
     which the missing cap makes reachable) still dispatches the command
     with whatever stale s/g entries the slot's table holds.

## Threat model
Root-only device node — the panic/DoS primitive is already-privileged
(severity Low accordingly); the defect matters for robustness of the
management stack (linux-mly-compatible tools pass user lengths straight
through) and because the panic is reachable from a single ioctl with no
hardware preconditions beyond the card being present.

## Impact
Kernel panic (DoS), proven at the sink on this guest kernel; wired-memory
exhaustion variant; stale-s/g dispatch variant.

## Fix
Reject INT_MIN and cap |DataTransferLength| at MAXBSIZE (the buffer DMA tag's
maxsize) — fix.diff.

## Fix validation
Not run (fix touches mly path; hardware-gated).  The kmallocsink replica
already demonstrates that the size never reaching kmalloc removes the panic;
the cap also makes bus_dmamap_load's EFBIG path unreachable.

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