DF-5744 / verdict.json
{ "finding_id": "DF-5744", "status": "reproduced", "reproduced": true, "impact": "dos", "confidence": "certain", "verdict": "REPRODUCED on-guest with production code: apple_gmux attach (apple-gmux.c:737-744) accepts any ACPI _CRS size \u2014 GMUX_MIN_IO_LEN (apple-gmux.c:77) is dead code, the check present in upstream Linux v4.8 was dropped in the DragonFly port. With a planted 4-port APP000B device, the shipped /boot/kernel/apple_gmux.ko performed out-of-bounds port I/O past its 4-port rman allocation: 3 OOB reads at offsets 4-6 and indexed-probe writes 0xaa/0x55/0x00 at offsets 0xcc-0xce; the 0xaa write landed exactly on the COM1 SCR canary at 0x3ff (observed 0 -> 0xaa), i.e. a write into an unrelated devices register 204 bytes outside the allocation. Impact ceiling is hardware-state corruption (hang/panic class) from crafted/malicious ACPI or a firmware bug; trigger is privileged input, hence Low severity. fix.diff (size validation incl. indexed-probe minimum) validated on the same rig: undersized region rejected, canary untouched.", "exploit_chain": "crafted ACPI DSDT/SSDT with APP000B device + undersized _CRS -> kldload apple_gmux -> attach performs unbounded bus_read_1/bus_write_1 at offsets up to 0xd4 on the short resource -> out-of-bounds x86 port I/O to unrelated hardware registers (demonstrated: 0xaa written to UART SCR at base+0xcc); on real hardware adjacent ELCR/PM/EC/SMBus registers are corruptible -> system instability/hang (dos). No kernel-memory impact; not reachable unprivileged.", "evidence": "run.log (baseline hw.gmuxobs_scr:0 -> after kldload apple_gmux: 170=0xaa; port 0x333-0x336 on acpi0 proves 4-port resource), dmesg.txt, make_ssdt.py + ssdt_a.aml (planted table), gmuxobs.c (canary), fix_validation.log (patched: gmux I/O region too small (4 bytes, need >= 120), canary stays 0)", "kernel_refs": [ "sys/gnu/dev/misc/apple_gmux/apple-gmux.c:77", "sys/gnu/dev/misc/apple_gmux/apple-gmux.c:737", "sys/gnu/dev/misc/apple_gmux/apple-gmux.c:351", "sys/gnu/dev/misc/apple_gmux/apple-gmux.c:758" ], "poc_changes": "Seed had no runnable rig. Built: hand-encoded AML SSDT generator (small IO descriptor 0x47 requires byte-sized align/len and EndTag 79 00 \u2014 verified against QEMUs own DSDT after two dead ends), a canary KLD watching COM1 SCR (port 0x3ff = base 0x333 + offset 0xcc), and module-only fix rebuild for validation. No Apple hardware needed: driver is a KLD probing any APP000B ACPI device.", "attempts": 4, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026\troot@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 2400, "guest_dirty": 1, "build_cmd": "cd /root/gmuxobs_a && make (guest, /usr/src); module: cd /usr/src/sys/gnu/dev/misc/apple_gmux && make", "run_cmd": "kldload gmuxobs.ko; kldload apple_gmux; sysctl hw.gmuxobs_scr", "code_hash": "90af6168d7b8ba9b87719e55d9aae57ccee3edbcaab55c2f6d97cc8a09535904", "notes": "Guest left dirty (patched /usr/src copy + built modules); vm.sh reset with-src run afterwards. Divergence vs upstream Linux v4.8 apple-gmux.c: the iolen<GMUX_MIN_IO_LEN check was dropped; indexed probe additionally overreaches to 0xd4 even upstream. dfly port owns the fix.", "recommended_fix": "Validate rman_get_size(io_res) >= GMUX_MIN_IO_LEN at attach and >= GMUX_PORT_WRITE+4 before the indexed probe (see fix.diff).", "fix_status": "fixed", "fix_baseline_reproduced": true, "fix_patched_reproduced": false, "fix_verdict": "Patched module on the identical rig prints gmux I/O region too small (4 bytes, need >= 120), attach fails -ENODEV before any register access, and the canary port is untouched (0x00). Baseline (shipped module) wrote 0xaa to it. Behavior change confirmed.", "fix_evidence": "findings/poc/DF-5744/fix_validation.log; fix.diff" } |