DF-3933 / verdict.json
{ "finding_id": "DF-3933", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "Fix not validated on the guest: the trigger path requires mly/age hardware absent from the audit guest. fix.diff is mechanical (bounds/termination-only) and authored post-verification against the cited lines.", "fix_evidence": "findings/poc/DF-3933/fix.diff + VERDICT.md", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "Hardware-gated (no Attansic L1 NIC in the audit guest); source-certain, and explicitly the single-segment complement of known DF-1292 (which covers the multi-segment desc->len path at if_age.c:2037). age_rxeof takes the frame length from the DMAd return descriptor without any clamp: sc->age_cdata.age_rxlen = AGE_RX_BYTES(rxrd->len) (if_age.c:2000), a full 16-bit NIC-controlled value. Receive buffers are MCLBYTES clusters with ETHER_ALIGN headroom (age_newbuf, if_age.c:2742-2747; rx tag capped at MCLBYTES, if_age.c:1066-1076 - 2046 usable bytes). In the single-segment completion path (count==nsegs-1==0) the driver assigns m->m_pkthdr.len = m->m_len = age_rxlen - 0 (if_age.c:2077-2079) and hands the mbuf to if_input (:2121): a hostile/buggy NIC reporting up to 65535 makes ether_input/BPF walk up to ~63KB past the cluster - kernel heap over-read surfaced as packet payload (info leak) or stack panic. The nsegs-vs-length cross-check in age_rxintr (:2161-2164) constrains nsegs only, not the length. Filed not_reproduced (family convention DF-1292), certain at source.", "exploit_chain": "malicious/buggy L1 writes RRD len with nsegs=1 -> m_len/m_pkthdr.len up to 65535 on a 2046-byte cluster -> heap OOB read delivered to the network stack/BPF", "evidence": "findings/poc/DF-3933/VERDICT.md; fix.diff (MCLBYTES-ETHER_ALIGN clamp)", "kernel_refs": [ "sys/dev/netif/age/if_age.c:2000", "sys/dev/netif/age/if_age.c:2074", "sys/dev/netif/age/if_age.c:2077", "sys/dev/netif/age/if_age.c:2079", "sys/dev/netif/age/if_age.c:2121", "sys/dev/netif/age/if_age.c:2746", "sys/dev/netif/age/if_agereg.h:601" ], "poc_changes": "No seed PoC; hardware-gated RX path - lab reproduction documented (QEMU L1 model writing len=0xFFFF<<16 with nsegs=1).", "attempts": 1, "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": 180, "guest_dirty": 0, "notes": "pass-2 GLM5.3. Negative checks on the same function: CRC-strip tail arithmetic guards nsegs==1 vs multi (:2053-2072); newbuf-failure path resets the chain safely (:2025-2033).", "recommended_fix": "Clamp single-segment m_len/m_pkthdr.len to MCLBYTES - ETHER_ALIGN.", "build_cmd": null, "run_cmd": null, "code_hash": null } |