DF-4690 / verdict.json
{ "finding_id": "DF-4690", "status": "reproduced", "reproduced": 1, "impact": "none", "confidence": "certain", "verdict": "REPRODUCED at decoder level on the DragonFly guest (verbatim-extracted decode_tuple_bar, cardbus_cis.c:293-385, driven with crafted CIS bytes + emulated PCI probe; the accepted DF-1811 used the same source-only standard since the guest has no CardBus bridge). Beyond DF-1811 (which covers only masked-probe-zero ffs(0)): (mode 1) when the BAR probe reads back 0xffffffff -- exactly the case :362 excludes -- the attacker-controlled 32-bit CIS size field survives, is assigned to the INT `len` (:308) and passed UNCHECKED as the resource count to resource_list_add (:377): 0xFFFFFFF0 -> count = -16; (mode 2) a BAR probing 0x80000000 gives `1 << (ffs(pci_bar)-1)` = 1 << 31 (:368), signed-overflow UB manifesting as INT_MIN -> count = -2147483648. A negative count in a child resource-list entry is nonsense for every later rman allocation of that entry. Hardware-gated (physical CardBus card); realistic ceiling is the cards driver failing to attach / resource misbehavior, not privilege escalation.", "exploit_chain": "malicious CardBus card (physical insertion) -> cardbus_do_cis -> decode_tuple_bar/decode_tuple_funce -> negative resource count / stale-byte MAC ivar; no uid0 path", "evidence": "run.log: m1: ... probe=0xffffffff -> resource_list_add count = -16 ... NEGATIVE COUNT and m2: ... probe=0x80000000 -> count = -2147483648 ... NEGATIVE; fix_run.log: PATCHED modes 1/2/3 ... count = 1111638594 (0x42424242) (sentinel intact = resource_list_add never reached).", "kernel_refs": [ "sys/dev/pccard/cardbus/cardbus_cis.c:308", "sys/dev/pccard/cardbus/cardbus_cis.c:360", "sys/dev/pccard/cardbus/cardbus_cis.c:362", "sys/dev/pccard/cardbus/cardbus_cis.c:368", "sys/dev/pccard/cardbus/cardbus_cis.c:377" ], "poc_changes": "verbatim extraction of the two decoder bodies (anchors, cardbus_cis.c:258-290/293-385) against minimal newbus/pci stubs (pci_read/write_config probe emulation, resource_list_add capture); added errno.h include after first build failed on EINVAL", "attempts": 3, "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": 30, "guest_dirty": 0, "build_cmd": "cd /root/cb4690 && sh build.sh", "run_cmd": "cd /root/cb4690 && sh run.sh", "code_hash": "b662d9d7a366c595e7eb6d018c7f15ec865f1c17fea6bdac58ce1715e454be3e", "notes": "hardware-gated (no CardBus bridge on guest); decoder-level verification per the accepted DF-1811 source-only reproduced standard", "recommended_fix": "After the probe block, reject non-positive sizes (len <= 0 -> EINVAL) and the masked pci_bar == 0 case (the DF-1811 half) before resource_list_add.", "fix_status": "fixed", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "Harness-level: baseline m1/m2/m3 deliver negative counts into resource_list_add; with fix4690.diff all three return EINVAL and the captured count keeps its sentinel 0x42424242 (never called).", "fix_evidence": "run.log: m1: ... probe=0xffffffff -> resource_list_add count = -16 ... NEGATIVE COUNT and m2: ... probe=0x80000000 -> count = -2147483648 ... NEGATIVE; fix_run.log: PATCHED modes 1/2/3 ... count = 1111638594 (0x42424242) (sentinel intact = resource_list_add never reached)." } |