DF-3843 / verdict.json
{ "finding_id": "DF-3843", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "Source-certain unbounded firmware-driven OOB write: mrsas_sync_map_info (mrsas.c:3207,3220-3224) copies num_lds = raidMap.ldCount (full u32) 4-byte entries into a fixed 172,200-byte bus_dmamem buffer; the computed bound size_sync_info (mrsas.c:3210) is never used and MR_ValidateMapInfo (mrsas_fp.c:257-265) only checks totalSize/ldCount mutual consistency, both firmware-supplied. On-guest struct-math proof (run.log) shows ldCount=65536 with totalSize=0x9e028a8 passes validation and overwrites 89,944 bytes past the allocation with 3-of-4 firmware-chosen bytes per entry. Kernel-path execution requires a MegaRAID HBA (Thunderbolt/Invader/Fury) or crafted device DMA; the audit guest has the driver compiled in (kldstat: 80 pci/mrsas) but no LSI PCI device and no /dev/mrsas* node, so the trigger surface does not exist in the VM. Hardware-gated; malicious-firmware threat model (same gating as DF-1528/DF-1242..1244, but a write primitive of firmware-chosen length).", "exploit_chain": "firmware DMA-authors RAID map with ldCount K>43050 plus consistent totalSize -> attach / AEN-driven map-sync completion (mrsas.c:2965) or OCR (mrsas.c:2477) calls mrsas_sync_map_info -> linear overwrite of kernel memory adjacent to raidmap_mem[] with {u8 targetId, 0x00, u16 seqNum} x K -> heap corruption under firmware control -> kernel code execution. No local unprivileged trigger without the device.", "evidence": "run.log lines capacity in sync entries = 43050 and => 89944 bytes written PAST the end of the DMA allocation; VERDICT.md full trace; map_sync_overflow_proof.c struct definitions copied verbatim from mrsas.h; env.txt shows guest has no LSI PCI device / no /dev/mrsas*.", "kernel_refs": [ "sys/dev/raid/mrsas/mrsas.c:3207", "sys/dev/raid/mrsas/mrsas.c:3210", "sys/dev/raid/mrsas/mrsas.c:3213", "sys/dev/raid/mrsas/mrsas.c:3220", "sys/dev/raid/mrsas/mrsas.c:3222", "sys/dev/raid/mrsas/mrsas.c:3223", "sys/dev/raid/mrsas/mrsas.c:1645", "sys/dev/raid/mrsas/mrsas_fp.c:257", "sys/dev/raid/mrsas/mrsas_fp.c:174", "sys/dev/raid/mrsas/mrsas.h:698" ], "poc_changes": "No seed PoC existed; authored map_sync_overflow_proof.c standalone userland harness (verbatim mrsas.h structs) because the kernel path needs an HBA the guest does not have.", "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": 42, "guest_dirty": 0, "build_cmd": "cc -O2 -Wall -o /tmp/df3843_proof /tmp/df3843_proof.c", "run_cmd": "/tmp/df3843_proof; kldstat -v | grep -i mrsas; pciconf -lv | grep -i megaraid; ls /dev/mrsas*", "code_hash": "f7c6391d30a3486b0c0096990c974f92b93112aac2841d3d88a8608a954f6fa6", "notes": "Hardware-gated (malicious/broken firmware or device DMA). Driver present in guest kernel config sys/config/X86_64_GENERIC:123 and kldstat, but never attaches without the HBA. 22,486 fully-OOB entries at ldCount=65536; loop also OOB-reads the source map via MR_LdRaidGet/MR_GetLDTgtId (ldSpanMap[i], i unbounded). Same threat gating as accepted findings DF-1242/1243/1244/1528 but strictly stronger primitive (arbitrary-length linear write vs single-slot or read-only).", "recommended_fix": "Reject ldCount > MAX_LOGICAL_DRIVES in mrsas_sync_map_info before the copy loop (release the mfi cmd and return error) and add the same bound to MR_ValidateMapInfo so bogus maps never enable fast path.", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff bounds ldCount at both the sync path (mrsas.c) and validation (mrsas_fp.c); cannot be boot-tested on this guest (no HBA), so fix validation is not_testable rather than fixed. The bound provably removes the only writer of the overflow: the loop cannot execute past MAX_LOGICAL_DRIVES iterations after the guard.", "fix_evidence": "fix.diff hunks; map_sync_overflow_proof.c capacity math (43050 entries capacity vs MAX_LOGICAL_DRIVES=64 bound)." } |