⬢ DragonFlyBSD Kernel Audit
DF-4660 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4660",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "dos",
  "confidence": "certain",
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 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": 3,
  "guest_dirty": 0,
  "build_cmd": "cd /root/df2413 && sh build.sh",
  "code_hash": "649368a4f0ba8c2b3e06ce44e4570d0ca199c48de7f40bd49afefb09bcc22a81",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Validated on the guest: fixA+B+C applied to a copy of the pristine ar2413.c, function bodies re-extracted verbatim from the patched copy, harness rebuilt and re-run. Baseline reproduces the defect; patched build shows the defect GONE (mode 1: no overflow / mode 2: early return, sentinel minPower, no wild-read propagation / mode 3: completes without the wild-address SIGSEGV). fix.diff is git-apply-able against the pristine tree (git apply --check clean) and was never applied to sys/.",
  "fix_evidence": "fix_run.log (full patched 3-mode run) vs run.log (baseline); fix.diff in pack; PATCHES_APPLIED + FIXED_BUILD_OK in fix_run.log.",
  "verdict": "REPRODUCED on the DragonFly guest by compiling the verbatim kernel function bodies (anchor-extracted ar2413.c:245-496 from /usr/src, md5-verified == audit tree) against a faithful ar2413State layout (bank rows 1/1/1/27/3 from the shipped ar5212.ini; verified offsets pcdac@72 Bank1@328 vpdI@1484 sizeof 2000): with an EEPROM-shaped crafted dataset (xpd_mask=0xF, Pmin pattern {0,58,58,58}, TPCRG5 overlap 15 -- register-realistic, the field is 4 bits) the unbounded kk walk at ar2413.c:453/:462/:476 wrote 40 uint16 cells (80 bytes) past pcdacTable[PWR_TABLE_SIZE_2413=128] into the Bank1Data..Bank7Data members of the heap-allocated ar2413State object (intra-object overflow; RF bank scratch corrupted, reprogrammed to the radio at ar2413.c:206-210). kk ran to 168; with 63-clamped boundaries and overlap 15 the minimum-guaranteed walk is 3+63+6*15=156 > 128. Exploitation is gated on attacker-supplied AR2413 hardware with crafted EEPROM (physical/supply-chain); realistic ceiling is radio misprogramming/DoS, not privilege escalation. Twin of DF-4619 (ar5413) / DF-4648 (ar2316). Fix validated: with kk<PWR_TABLE_SIZE_2413 guards the overflow is gone (bank canary intact, fix_run.log).",
  "exploit_chain": "crafted v3 EEPROM on AR2413 card -> ath attach reads ee_rawDataset2413 -> ar5212SetTransmitPower -> ar2413SetPowerTable -> ar2413getGainBoundariesAndPdadcsForPowers unbounded kk walk -> 80-byte intra-object heap OOB write past pcdacTable[128] into RF bank scratch -> banks programmed to radio (ar2413.c:206-210): radio misprogramming / crash. No uid0 route (values clamped 0..127, intra-object only).",
  "evidence": "run.log mode 1: DF-4660 REPRODUCED ... kk ran to 168; build.log struct offsets (pcdac@72 Bank1@328 vpdI@1484 sizeof 2000); fix_run.log patched mode 1: NO overflow detected; fix.diff (git-apply verified).",
  "kernel_refs": [
    "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:451",
    "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:453",
    "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:462",
    "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:476",
    "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:37",
    "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:510",
    "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:747",
    "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:206",
    "sys/dev/netif/ath/ath_hal/ah_eeprom_v3.h:282"
  ],
  "poc_changes": "Harness ported from the DF-4648 (ar2316) twin: bank row counts 1/1/1/27/3 (ar5212.ini ar5212Bank*_2413), ar2413 names/anchors, 66-cell bank canary window; extraction anchored (not line-based). No kernel-code changes -- function bodies compiled verbatim.",
  "notes": "Intra-object overflow only (stays inside the 2000-byte ath_hal_malloc allocation); values constrained (pdadc clamps 0/127). Known DF-1796 (numChannels==0 OOB read, pass 1) NOT re-reported. Sibling wraps in the same function filed as DF-4661/DF-4662. First fix.diff draft had a malformed hunk header (patched-source re-run still overflowed); regenerated byte-exact and re-validated -- baseline unaffected (baseline ran on pristine source).",
  "recommended_fix": "Add kk < PWR_TABLE_SIZE_2413 guards to all three pPDADCValues[kk++] loops in ar2413getGainBoundariesAndPdadcsForPowers (fix.diff).",
  "run_cmd": "./ar2413_harness 1",
  "attempts": 1
}