DF-2311 / verdict.json
{ "finding_id": "DF-2311", "status": "reproduced", "reproduced": 1, "impact": "denial_of_service", "confidence": "certain", "verdict": "REPRODUCED with a softc-level probe: after iicread() takes the bus (iicbus_request_bus, iic.c:253) and iicbus_block_read fails (:263), the function returns at :265-268 WITHOUT iicbus_release_bus -- struct iicbus_softc->owner (iicbus.h:39) sticks at the iic0 device pointer permanently: 0 -> 0xfffff8008bb654a0 after the failed read, unchanged +2 s. Compare iicwrite :222-225 which always releases. Any other iicbus child is locked out until reboot (the same-device re-request succeeding masks the lock from the leaking fd itself -- the probe must be read-only, documented in the PoC). Trigger note: the emulated peer cannot NACK read-direction data, so the deterministic block_read failure used is the bus-already-started EINVAL of iicbus_start (iiconf.c:178) -- the identical early-error return at :265-268 that the finding NACK flavor takes on hardware.", "exploit_chain": "", "evidence": "run.log: owner BEFORE 0 -> AFTER FAILED READ 0xfffff8008bb654a0 -> +2s unchanged; read returned EINVAL from the same path", "kernel_refs": [ "sys/bus/iicbus/iic.c:253", "sys/bus/iicbus/iic.c:263", "sys/bus/iicbus/iic.c:265", "sys/bus/iicbus/iic.c:267", "sys/bus/iicbus/iic.c:225", "sys/bus/iicbus/iiconf.c:169", "sys/bus/iicbus/iiconf.c:178" ], "poc_changes": "v1 probed with a second ioctl (self-masking: the ioctl path itself requests+releases and hid the leak) and hit the single-open EBUSY; v2/v3 use one O_NONBLOCK fd, keep sc->started armed, and probe via the read-only hw.fakebb3.busowner sysctl added to the harness.", "attempts": 3, "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": 45, "guest_dirty": 0, "build_cmd": "cc -O -Wall -o poc2311 poc2311.c", "run_cmd": "./poc2311", "code_hash": "2ff0db39e8a71a93a5ac7b19275879cc78af42885441f240c821fa85d63fd867", "notes": "", "recommended_fix": "Call iicbus_release_bus on the block_read error path before returning (fix.diff).", "fix_status": "fixed", "fix_validation": "fix kernel + rebuilt iic.ko: owner stays 0 after the failed read (released on error)" } |