⬢ DragonFlyBSD Kernel Audit
DF-4085 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4085",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-certain heap OOB write (CWE-787), pass 2. In _mapping_process_dpm_pg0 (sys/dev/raid/mps/mps_mapping.c:1512-1518), DPM entries whose DeviceIndex falls in the direct-attached range take num_slots = max_num_phy_ids, the firmware u16 ioc_pg8.MaxNumPhysicalMappedIDs, never validated against the mapping-table size; the reservation loop :1544-1563 then writes num_slots consecutive 32-byte struct dev_mapping_table entries with no check that dev_idx+num_slots <= max_devices (kmalloc(max_devices*32) at :1393-1394). With an IN-BOUNDS dev_idx (distinct from DF-1374s unvalidated index; distinct from DF-1375s event-NumSlots path) a malicious/buggy IOC or emulated HBA gets a linear boot-time heap overflow: harness shows 65,281 entries (2,088,992 bytes) past a 16,320-byte allocation, firmware-controlled qword at stride 32. Not reproduced at kernel level: no SAS HBA on the QEMU guest (env.txt), mps never attaches - same hardware gate as DF-1374/1375/3914. Primitive proven at object level on the guest (harness replicates verbatim struct+loop; run.log, stable across reruns).",
  "exploit_chain": "Hardware-gated chain (not executable on this guest): malicious/compromised IOC firmware or PCI-passthrough emulated HBA -> IOC pg8 MaxNumPhysicalMappedIDs=0xFFFF + DPM pg0 entry with in-bounds DeviceIndex -> mps_mapping_initialize -> _mapping_process_dpm_pg0 reservation loop -> ~2MB linear heap overwrite with fw-controlled qwords at 32-byte stride past mapping_table into adjacent kmalloc zones -> slab metadata / neighboring object corruption -> kernel code execution. Stopped at primitive proof: no HBA in guest.",
  "evidence": "run.log/run.2.log (guest harness: 2,088,992-byte canary smash at stride 32, in-bounds dev_idx), harness_df4085.c (verbatim struct mpsvar.h:135 + loop :1544-1563), env.txt (hardware gate), VERDICT.md (line-by-line chain), fix.diff + fix_build.log (-Werror module build with the fix, mps.ko linked)",
  "kernel_refs": [
    "sys/dev/raid/mps/mps_mapping.c:1512",
    "sys/dev/raid/mps/mps_mapping.c:1518",
    "sys/dev/raid/mps/mps_mapping.c:1544",
    "sys/dev/raid/mps/mps_mapping.c:1545",
    "sys/dev/raid/mps/mps_mapping.c:1393",
    "sys/dev/raid/mps/mps_mapping.c:1469",
    "sys/dev/raid/mps/mps_mapping.c:1734",
    "sys/dev/raid/mps/mpsvar.h:135"
  ],
  "poc_changes": "No seed PoC (pass-2 finding). Harness authored against the exact struct layout with the verbatim :1544-1563 loop; built and run on the audit guest with cc 8.3 as an unprivileged user.",
  "attempts": 2,
  "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": 90,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -Wall -o harness_df4085 harness_df4085.c",
  "run_cmd": "./harness_df4085",
  "code_hash": "02c15d9244e2f82563ad7777157083d9183c15b1ab39762f9b9b4e5e8e831e54",
  "notes": "Checklist cross-apply (a)/(d) from the mpr twins. Guest /usr/src restored pristine after fix build (reverse-patch verified); guest reset with clean-source snapshot.",
  "recommended_fix": "In _mapping_process_dpm_pg0, skip any DPM entry with dev_idx >= max_devices or num_slots > max_devices - dev_idx before storing into enclosure_table or running the reservation loop.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Applied to the guest /usr/src together with this batchs other mps fixes (DF-4085..DF-4090); make in sys/dev/raid/mps compiled all sources with -Werror and linked mps.ko (BUILD_EXIT=0). Runtime fix validation not testable: the path requires an mps(4) HBA delivering firmware data, absent on this guest.",
  "fix_evidence": "findings/poc/DF-4085/fix.diff, findings/poc/DF-4085/fix_build.log"
}