DF-4232 / verdict.json
{ "finding_id": "DF-4232", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "Source-level certain: every ring cursor txp(4) walks is a 32-bit word in the DMA-shared hostvar block (if_txpreg.h:542-554) or the DMA-shared descriptor rings, consumed with zero validation. (1) txp_rx_reclaim (if_txp.c:658-737): roff/woff device-fed, rxd = r_desc + roff/16 unbounded; roff outside [0,2048) or misaligned walks descriptors OOB past the contigmallocd ldata block while roff!=woff may never terminate (serializer-held livelock); rx_sd is a kernel pointer stored in DMA memory (if_txpreg.h:268-271) read at :671 and dereferenced at :673 -- wild mbuf then lengthened (:676), copied from (:704), freed. (2) txp_response (if_txp.c:1418-1453): ridx from device-writable hv_resp_read_idx gives rsp = base + ridx OOB read; hv_resp_write_idx not in {0,16..496} makes the walk cycle the 32-entry ring forever; rsp_numdesc from OOB memory sizes a kmalloc (:1422) and bcopy walk. Sibling drivers (fxp/bge/em/re) mask their device-fed indices; txp does not. Runtime inconclusive: driver in kernel, NO_3COM_PCI_DEVICE on the guest (run.log).", "exploit_chain": "Malicious/faulty firmware (or passthrough device): one DMA word aimed at hv_resp_write_idx = hard livelock DoS; crafted roff/rx_sd aims a wild deref and a wild-mbuf free/copy -- arbitrary-deref primitive leading to kernel R/W for the device owner.", "evidence": "run.log (driver in kernel + absence proof), VERDICT.md (both walks traced path:line), trigger.c, fix.diff", "kernel_refs": [ "sys/dev/netif/txp/if_txp.c:658", "sys/dev/netif/txp/if_txp.c:660", "sys/dev/netif/txp/if_txp.c:671", "sys/dev/netif/txp/if_txp.c:673", "sys/dev/netif/txp/if_txp.c:733", "sys/dev/netif/txp/if_txp.c:1393", "sys/dev/netif/txp/if_txp.c:1418", "sys/dev/netif/txp/if_txp.c:1419", "sys/dev/netif/txp/if_txp.c:1422", "sys/dev/netif/txp/if_txpreg.h:522", "sys/dev/netif/txp/if_txpreg.h:525", "sys/dev/netif/txp/if_txpreg.h:542" ], "poc_changes": "No seed (pass-2 new); annotated precondition trigger per DF-3604/DF-3761 convention.", "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": 95, "guest_dirty": 0, "build_cmd": "cc -o trig_4232 t4232.c (guest)", "run_cmd": "./trig_4232 && kldstat -v | grep if_txp && (pciconf -l | grep -i 10b7 || echo NO_3COM_PCI_DEVICE)", "code_hash": "583c77707128e8f66d151b60e68393a9fbd18c1798a02530f56b81e679342ae7", "notes": "DF-3761 unbounded-walk family, txp member. txp_intrs TX-ring walks are cnt-bounded (host-tracked r_cnt) and were verified NOT affected.", "recommended_fix": "Validate ring cursors (16-byte alignment + ring byte-size bound) at both walk entry points before computing any descriptor pointer; see fix.diff.", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff clamps-and-checks both cursor pairs and resets to 0 on violation (recovery equivalent to the drivers existing chip-reset paths). Not runtime-validable without the device.", "fix_evidence": "fix.diff; run.log absence proof" } |