⬢ DragonFlyBSD Kernel Audit
DF-4622 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4622",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "REPRODUCED on the DragonFly guest (verbatim-extraction harness, mode 3): with an EEPROM-shaped dataset of flat pd-gain curves (all deltas 0 \u2014 legal 4-bit EEPROM values), sizeCurrVpdTable==0 makes ar5413.c:508-509 index VpdTable_I[ii][(uint32)0-1] -> element 0xFFFFFFFF -> read at row+0x1FFFFFFFE bytes (+8.59 GB). SIGSEGV handler asserts si_addr == &vpdTable_I[0][0] + 0x1FFFFFFFE exactly (0x200402892) \u2014 the fault is pinned to this line. In-kernel: direct-map garbage read or KVA-hole panic on every channel set with such a curve (crafted EEPROM, or a flat-calibrated legit card). Fix validated: clamping sizeCurrVpdTable>=2 removes the fault; patched mode 3 runs to completion.",
  "exploit_chain": "flat EEPROM power curve (deltas 0) -> sizeCurrVpdTable=0 at ar5413.c:501 -> :508-509 uint32 index wrap -> kernel read at vpdTable_I row + 0x1FFFFFFFE (past the ar5413State allocation, ~8.6GB away) -> panic (unmapped KVA) or garbage Vpd_step -> wrong pdadc extrapolation programmed to PHY. No exfil; no uid0 route (hardware-gated).",
  "evidence": "run.log mode 3 lines: REPRODUCED: SIGSEGV si_addr=0x200402892, expected wild address 0x200402892 and MATCH: wild OOB read proven (ar5413.c uint32 counter underflow); fix_run.log --- mode 3 shows patched build completing with no fault.",
  "kernel_refs": [
    "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:501",
    "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:503",
    "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:508",
    "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:509",
    "sys/dev/netif/ath/ath_hal/ar5413.c:55",
    "sys/dev/netif/ath/ath_hal/ar5413.c:423",
    "sys/dev/netif/ath/ath_hal/ah_eeprom_v3.c:449"
  ],
  "poc_changes": "no seed PoC; discovered while isolating DF-4619 (the first harness run segfaulted here before the kk overflow could manifest); mode 3 = flat-curve dataset + SIGSEGV handler asserting the exact expected wrapped address",
  "attempts": 2,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "runtime_sec": 60,
  "guest_dirty": 0,
  "build_cmd": "sh build.sh   (verbatim extraction of ar5413.c:288-540 + cc -O2)",
  "run_cmd": "./ar5413_harness 3",
  "code_hash": "fc8693ed15ae1678c4d1a170d2a138dd392f5a59d49cadbaab442826f4a371c1",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0 x86_64 (harness-level validation of patched function bodies; kernel-build validation hardware-gated)",
  "fix_verdict": "fix.diff clamps sizeCurrVpdTable to >=2 before the [size-1]/[size-2] reads; baseline faults at the exact wrapped address, patched mode 3 completes with no SIGSEGV (residual stale in-row reads are memory-safe, correctness-only).",
  "fix_evidence": "fix_run.log --- mode 3 section (patched): full mode-3 output with no REPRODUCED: SIGSEGV line and normal termination.",
  "notes": "Same uint32-underflow class as DF-4620 but different trigger (flat curve vs zero-gain) and different guard; both independent of known DF-1766.",
  "recommended_fix": "Clamp sizeCurrVpdTable to >= 2 before the VpdTable_I[ii][sizeCurrVpdTable-1/-2] reads (see fix.diff)."
}