DF-2310 / verdict.json
{ "finding_id": "DF-2310", "status": "reproduced", "reproduced": 1, "impact": "leak", "confidence": "certain", "verdict": "REPRODUCED on the production iic.ko/iicbus.ko/iicbb.ko stack riding the fakebb3 harness (DF-5539 rig family, disclosed setup patches DF-5559/5560; the I2CRDWR logic under test is stock): a write-direction I2CRDWR message with an invalid user buffer pointer (0xffffffff00000000, kernel range) is accepted with ioctl SUCCESS -- the unchecked copyin at iic.c:362 fails silently -- and the wire capture shows the freshly kmalloc(M_WAITOK, no M_ZERO) buffer transmitted stale kernel heap to the emulated slave: bytes 8..15 of the groom marker DF5558STALEHEAP! (414c454845415021), a kernel-realm pointer-qword remnant (ffffffffffffffff) at the head, and marker sequence/size/fill tails. At least 12 bytes of provably-stale kernel heap per message reach the I2C peripheral (and are readable back by the same operator), with the error never reported to userspace. The sibling unchecked copyout at :369 is addressed by the same fix.", "exploit_chain": "groom M_TEMP chunk (marker + kernel-realm qwords) -> kfree -> I2CRDWR write msg with kernel-range buf -> silent copyin EFAULT -> kmalloc recycles the chunk -> stale heap clocked out on SDA -> emulated slave capture (sysctl dump) = kernel heap disclosure over the I2C wire", "evidence": "run.log: CONTROL captures exactly the submitted pattern 0x40..0x5f; ATTACK capture ffffffff...414c454845415021... after groom; ioctl returned SUCCESS", "kernel_refs": [ "sys/bus/iicbus/iic.c:360", "sys/bus/iicbus/iic.c:361", "sys/bus/iicbus/iic.c:362", "sys/bus/iicbus/iic.c:364", "sys/bus/iicbus/iic.c:369" ], "poc_changes": "Extended the DF-5539 harness with hw.fakebb3.dumprx/clearrx sysctls (slave wire-capture dump) and a busowner probe; PoC self-contains the iic ioctl ABI (no /usr/include/bus/iicbus).", "attempts": 2, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Wed Oct 21 11:04:42 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/BUSAUDIT x86_64 (stock GENERIC + device targ; INVARIANTS)", "runtime_sec": 60, "guest_dirty": 0, "build_cmd": "sh rigup.sh (applies disclosed setup patches, builds+loads production stack on harness, builds groom KLD and PoCs)", "run_cmd": "./poc2310", "code_hash": "6e24279ed27d937922560b2b97a62b47898ddb975f7c349a56991974f7547208", "notes": "", "recommended_fix": "Check the copyin return (propagate EFAULT, skip the transfer) and the copyout return; M_ZERO the per-message buffers (fix.diff).", "fix_status": "fixed", "fix_validation": "fix kernel + rebuilt iic.ko: attack ioctl returns EFAULT, transfer skipped, slave capture empty; control path still delivers the pattern" } |