⬢ DragonFlyBSD Kernel Audit
DF-4363 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4363",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "REPRODUCED (harness; guest has no mps HBA - same method as DF-1556/DF-1557). mps_config_get_man_pg10 is the only getter in mps_config.c that allocates a fixed-size page buffer (MPS_MAN_PAGE10_SIZE=0x5C=92 bytes, mpsvar.h:105, kmalloc at mps_config.c:254) while the DMA length comes from the firmware page header (cm->cm_length = PageLength*4 up to 1020, mps_config.c:249). mps.c:2099-2101 bus_dmamap_loads cm_length bytes over that 92-byte allocation and the IOC DMAs the full Manufacturing Page 10 into it: firmware-controlled kernel heap overflow of up to 928 bytes. Guard-page harness on the guest: PageLength=24 -> SIGSEGV 4 bytes past; 23 -> exact fit clean; 255 -> SIGSEGV 928 bytes past. Fixed model (fix.diff: kmalloc(MAX(cm_length, 0x5C)) + <0x1C floor guard) exits clean on all inputs.",
  "exploit_chain": "malicious/buggy WarpDrive SSS6200 firmware (or device posing as one via hotplug) returns Manufacturing Page 10 header with PageLength>23 -> IOC DMA writes up to 1020 firmware-chosen bytes into a 92-byte M_MPT2 heap allocation during discovery (mps_sas.c:3320 -> mps_wd_config_pages -> mps_config.c:368) -> kernel heap corruption with fully controlled content; device-driven, not unprivileged-user-driven (same threat model/severity class as the known DF-1556/DF-1557 in this file)",
  "evidence": "findings/poc/DF-4363/run.log: RUN24_EXIT=1 (SIGSEGV, +4 bytes), RUN23_EXIT=0 (exact 0x5C boundary), RUN255_EXIT=1 (+928 bytes), fixed runs F24/F255/F4=0; harness.c models mps_config.c:249,254,260 + mps.c:2099-2101 one-to-one; env.txt proves mps in GENERIC with no HBA attached",
  "kernel_refs": [
    "sys/dev/raid/mps/mps_config.c:249",
    "sys/dev/raid/mps/mps_config.c:254",
    "sys/dev/raid/mps/mps_config.c:260",
    "sys/dev/raid/mps/mpsvar.h:105",
    "sys/dev/raid/mps/mps.c:2099",
    "sys/dev/raid/mps/mps_sas.c:3320",
    "sys/dev/raid/mps/mps_pci.c:143"
  ],
  "poc_changes": "wrote harness from scratch (no seed): guard-page kmalloc(0x5C) model + fw-DMA memcpy model, baseline and -DFIXED validation modes in one file",
  "attempts": 1,
  "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": 210,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -Wall -Wextra -o harness harness.c",
  "run_cmd": "./harness 24; ./harness 23; ./harness 255",
  "code_hash": "fa5cbacaa3a79be720f1b4cec56f1b73e64b55b0581d4db0fdf03144d49b27f4",
  "notes": "Guest clean (userland harness only, /tmp artifacts on guest). Distinct from known DF-1556 (raid_volume_pg0 final bcopy, :1117) and DF-1557 (DD_column_map index, :462): this is the DMA sizing at :249/:254. mpr twin diverges correctly (all mpr_config.c getters allocate cm_length).",
  "recommended_fix": "Size the man-pg10 buffer for the DMA: kmalloc(MAX(cm->cm_length, MPS_MAN_PAGE10_SIZE)) and reject cm_length < 0x1C before the ProductSpecificInfo derefs (fix.diff).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Harness-level fix validation: baseline PageLength 24/255 fault on the guard page (heap overflow reproduced); with the fix.diff modeled (-DFIXED: MAX(cm_length,0x5C) allocation + short-page floor) the identical runs exit 0 with no overflow and PageLength=4 takes the new EINVAL path. Kernel-build validation not possible on this guest (no LSI HBA); both hunks are mechanical sizing guards.",
  "fix_evidence": "findings/poc/DF-4363/run.log (FIXED sections: F24=0, F255=0, F4=0 vs baseline RUN24_EXIT=1/RUN255_EXIT=1); fix.diff"
}