DF-4086 / verdict.json
{ "finding_id": "DF-4086", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "Source-certain off-by-one -> heap OOB read + conditional 32-byte heap OOB write, pass 2, fresh finding (not DF-1374/1375; not in the mpr twin set). _mapping_get_ir_maprange (mps_mapping.c:221-235) computes end_idx = start_idx + max_volumes - 1 unclamped; with firmware facts MaxTargets==0 plus pg8 RESERVED_TARGETID_0 and low volume mapping, end_idx == max_devices while max_devices = MaxTargets+MaxVolumes (:1734). Every IR walk uses inclusive <= (:366,:409,:457,:1647,:2126) and reads mapping_table[max_devices], one 32-byte entry past the kmalloc; _mapping_get_free_ir_mt_idx :457 can RETURN the OOB index, and mps_mapping_ir_config_change_event :2222-2232 then writes a full firmware-controlled dev_mapping_table entry there (physical_id = volume WWID, dev_handle, device_info). Harness proves range end==max_devices, the OOB read, the returned OOB index and the 32-byte OOB write with the fw WWID (run.log). Not reproduced at kernel level: no SAS HBA on the guest (env.txt). mps_mapping_check_devices :1647 sink is dead code (no callers) - noted.", "exploit_chain": "Hardware-gated: malicious/buggy IOC facts (MaxTargets=0 + IR + reserved-targetid-0 + low volume mapping) -> IR config change event on volume add -> _mapping_get_free_ir_mt_idx returns max_devices (OOB) when in-range slots are busy -> 32-byte struct write one entry past mapping_table with fw WWID/handle -> adjacent slab-object corruption -> potential kernel code execution. Stopped at primitive proof: no HBA in guest.", "evidence": "run.log/run.2.log (guest harness: end==max_devices off-by-one, OOB read at :366, free-idx walk returns 255, guard entry overwritten with fw WWID), harness_df4086.c (verbatim range fn + walks + :2222-2232 write), env.txt, VERDICT.md, fix.diff + fix_build.log (-Werror module build)", "kernel_refs": [ "sys/dev/raid/mps/mps_mapping.c:221", "sys/dev/raid/mps/mps_mapping.c:233", "sys/dev/raid/mps/mps_mapping.c:234", "sys/dev/raid/mps/mps_mapping.c:366", "sys/dev/raid/mps/mps_mapping.c:409", "sys/dev/raid/mps/mps_mapping.c:457", "sys/dev/raid/mps/mps_mapping.c:462", "sys/dev/raid/mps/mps_mapping.c:1647", "sys/dev/raid/mps/mps_mapping.c:2126", "sys/dev/raid/mps/mps_mapping.c:2222", "sys/dev/raid/mps/mps_mapping.c:2232", "sys/dev/raid/mps/mps_mapping.c:1734" ], "poc_changes": "No seed PoC (pass-2 finding). Harness replicates the range function, both <= walks and the event write verbatim; built/run on guest as 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": 60, "guest_dirty": 0, "build_cmd": "cc -O2 -Wall -o harness_df4086 harness_df4086.c", "run_cmd": "./harness_df4086", "code_hash": "b61f1a58efc0bd84b49e9c69e2af62068d9530e949f69d686b0fc835c49ff38d", "notes": "Same defect exists in mpr sibling _mapping_get_ir_maprange (mpr_mapping.c:241-256) - not covered by any existing mpr finding. Guest /usr/src restored pristine; guest reset with-src.", "recommended_fix": "Clamp end_idx to sc->max_devices - 1 in _mapping_get_ir_maprange so the inclusive IR walks cannot index past mapping_table.", "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-4086/fix.diff, findings/poc/DF-4086/fix_build.log" } |