DF-5796 / verdict.json
{ "finding_id": "DF-5796", "status": "reproduced", "reproduced": true, "impact": "none", "confidence": "likely", "verdict": "Reproduced the primitive on the production guest: _m_copyback2()/m_copyback() (sys/kern/uipc_mbuf.c:2368-2369) bcopy()s caller data into a target mbufs existing window with no M_WRITABLE()/m_sharecount() gate; with two mbufs sharing one cluster via m_copym() (sharecount=2, M_WRITABLE=0), m_copyback() through one mbuf rewrote the other mbufs data (a[0]=0x41 -> 0x5a). Memory-safe (writes stay in cluster bounds) but a cross-packet data-integrity corruption. Production sink (code-cited): bridge_output() if_bridge.c:4464-4471 rewrites ether_shost in place via m_copyback on bridge-forwarded frames whose clusters are shared by m_copypacket() flood copies (if_bridge.c:2317/3056/3208/3274) - remote-triggerable by any broadcast frame on a bridged member; wrong source MAC can poison switch MAC tables / blackhole L2 traffic. Same class: pf in-place header rewrites (pf.c:2120,3857,3997,4018,4085,4285,5060; pf_norm.c:1395,1620,1954).", "exploit_chain": "", "evidence": "run.log decisive lines: DF5796: cluster shared, m_sharecount(a)=2 (M_WRITABLE=0), DF5796: REPRODUCED: m_copyback through shared cluster rewrote the other mbufs data: a[0]=0x5a (expected 0x41). Source: mbuf_probe.c probe_5796(); ungated write at sys/kern/uipc_mbuf.c:2369.", "kernel_refs": [ "sys/kern/uipc_mbuf.c:2368", "sys/kern/uipc_mbuf.c:1647", "sys/net/bridge/if_bridge.c:4464", "sys/net/bridge/if_bridge.c:3274", "sys/net/pf/pf.c:3857" ], "poc_changes": "Added missing #include <sys/malloc.h> for M_WAITOK; used m_getcl + m_copym(M_COPYALL) to build the canonical shared-cluster pair and 0x41/0x5A markers to prove the cross-write read back through the original mbuf.", "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": "cd /tmp/df5796 && make -m /usr/src/share/mk SYSDIR=/usr/src/sys", "run_cmd": "kldload ./mbuf_probe.ko; sleep 1; kldunload mbuf_probe; dmesg | tail -30", "code_hash": "4d8206b6042649863367cdcdc683d06582fbd5d644d9f206a89cdf642a19e499", "notes": "Impact recorded as none because the enum lacks an integrity bucket; the demonstrated and code-cited ceiling is cross-packet data corruption (wrong source MACs on bridged frames -> L2 DoS/MAC-table poisoning), not memory corruption. End-to-end L2 impact not driven on the single-NIC audit guest; the primitive plus the bridge call graph is the evidence. Guest left clean.", "recommended_fix": "Gate the ungated bcopy in _m_copyback2 with an INVARIANTS KASSERT on M_WRITABLE(m) (see fix.diff); durable remediation at callers: unshare (m_unshare/m_dup) before in-place rewrites, and make bridge_outputs shost rewrite operate on a private head mbuf.", "fix_status": "not_testable", "fix_baseline_reproduced": 1, "fix_patched_reproduced": null, "fix_verdict": "Fix-validation kernel rebuild not performed: not a reproduced memory-corruption finding (in-bounds write). fix.diff adds an INVARIANTS-only KASSERT that would panic on the demonstrated rig and on the bridge path when INVARIANTS is enabled.", "fix_evidence": "fix.diff in this directory; sink analysis in VERDICT.md." } |