# DF-5744 VERDICT — REPRODUCED (production code, on-guest)

**Status: reproduced · impact: dos-class hardware-state corruption (OOB port
I/O) · confidence: certain**

## Root cause (static, certain)

* `sys/gnu/dev/misc/apple_gmux/apple-gmux.c:737-744` — `bus_alloc_resource_any`
  for SYS_RES_IOPORT with **no size check**; return value NULL-checked only.
* `apple-gmux.c:77` — `GMUX_MIN_IO_LEN` defined, **dead** (never referenced in
  the file; upstream Linux v4.8 `apple-gmux.c` uses it in exactly the check
  the port dropped).
* Consumers of offsets beyond any validated bound:
  * `gmux_pio_read8` at 0x04–0x06 during attach (apple-gmux.c:758-760)
  * `gmux_is_indexed()` writes 0xcc/0xcd/0xce (apple-gmux.c:351-353)
  * indexed protocol: 0xc2–0xc5 (VALUE, incl. `bus_read_4`), 0xd0 (READ),
    0xd4 (WRITE) (apple-gmux.c:216-303)
* x86 `bus_space` I/O ops are raw `inb`/`outb` — no rman bounds enforcement.

## Reproduction (guest: DragonFly 6.5-DEVELOPMENT, X86_64_GENERIC, QEMU i440fx)

Planted SSDT with `\_SB.ZZZ0 { _HID "APP000B", _CRS = IO 4 ports @ 0x333 }`
(QEMU `-acpitable`), COM1 SCR (port 0x3ff) as a side-effect-free canary —
0x333+0xcc = 0x3ff exactly.

Observed (`run.log`):

1. `apple_gmux0: port 0x333-0x336 on acpi0` — 4-port resource granted.
2. Baseline canary: `hw.gmuxobs_scr: 0`.
3. `kldload apple_gmux` (unmodified shipped `/boot/kernel/apple_gmux.ko`).
4. Canary after: **`hw.gmuxobs_scr: 170` (0xaa)** — the exact byte
   `gmux_is_indexed()` writes to `bus_write_1(sc->io_res, 0xcc, 0xaa)`
   (apple-gmux.c:351), landing 0xcc bytes past the end of the 4-port
   allocation, in another device's register.
5. Attach then failed -ENODEV ("gmux device not present") — the OOB accesses
   are on the failure path *by design* of the port: they happen before the
   driver gives up.

This is production code writing to hardware registers of unrelated devices
outside its allocated I/O window. On the rig the victim is a UART scratch
byte (chosen to be harmless); on real hardware the adjacent window can hold
PIC ELCR, PM logic, embedded controller or SMBus registers — corruption there
is at minimum a hang/panic (dos), potentially worse (e.g. toggling power
rails via EC registers).

## Threat model

Reachability requires an `APP000B` ACPI device with an undersized `_CRS`:
malicious/crafted firmware (supplier compromise, evil DMA... not realistic for
remote), or **root-performed ACPI table override + kldload** (already
privileged), or a benign firmware bug (real: Linux added the length check
because such machines existed). Not reachable by an unprivileged local user.
Hence Low severity despite the clean OOB-write primitive: it is a
robustness/divergence defect whose trigger is privileged input, consistent
with the audit's treatment of crafted-firmware preconditions.

## Fix validation

`fix.diff` (2 hunks): reject regions < GMUX_MIN_IO_LEN at attach, and reject
regions < GMUX_PORT_WRITE+4 before the indexed probe (the probe runs before
classic/indexed is known, and touches up to 0xd4).

Patched module (module-only rebuild of the same source), identical rig:

```
apple_gmux: gmux I/O region too small (4 bytes, need >= 120)
device_probe_and_attach: apple_gmux0 attach returned -19
hw.gmuxobs_scr: 0        <- canary untouched, no OOB access
```

Baseline bug reproduced / patched behavior gone ⇒ fix_status: fixed.

## Notes / divergence

* Upstream Linux v4.8 checks `iolen < GMUX_MIN_IO_LEN` (0x78) only; the
  indexed probe's 0xcc–0xd4 overreach beyond 0x78 exists upstream too — but
  upstream never *drops* the check. DragonFly's port is strictly more
  permissive; the port owner (DragonFly) should restore the check and extend
  it to the indexed ports.
* Rig construction notes in `make_ssdt.py` (hand-encoded AML; small I/O
  descriptor 0x47 carries byte-sized align/len — verified against QEMU's own
  DSDT; EndTag checksum byte must be 0x00).

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