DF-3379 / verdict.json
{ "finding_id": "DF-3379", "status": "reproduced", "reproduced": 1, "impact": "none", "confidence": "certain", "verdict": "The pfsync state-synchronization engine is dead code in this tree, three independent ways, verified statically (exhaustive tree grep) and behaviorally on the guest. (1) The global pfsyncif is never assigned anywhere - its only occurrence as an lvalue is the NULL initializer at if_pfsync.c:90; pfsync_clone_create() (131-192) omits the upstream pfsyncif = sc, so pfsync_input (:489), pfsync_pack_state (:1286), pfsync_request_update (:1449) and pfsync_clear_states (:1492) all take their sc==NULL early-out forever. (2) The RX dispatch in in_proto.c:281-296 is guarded by #ifdef NPFSYNC, which nothing defines (no use_pfsync.h include exists; conf/files:1574 builds if_pfsync.c only as part of pf), so pfsync_input is never registered in any build - the comment at :482 is accurate. (3) The bulk updater pfsync_bulk_update is never scheduled and the only sc_bulk_tmo arming (:1604) passes pfsync_timeout instead of pfsync_bulk_update; plus the SIOCSETPFSYNC default-peer reset assigns host-byte-order INADDR_PFSYNC_GROUP (:1076-1077 vs htonl at :150-151). Behavioral proof on the guest: pfsync0 configured with syncdev=lo0 AND unicast peer 10.0.2.2 (confirmed readback), pf enabled with keep-state, states creating/updating - tcpdump proto 240 on vtnet0 and lo0 captured ZERO packets over the window, where a live engine must transmit within its 1s tick. Security impact: silent total loss of the HA state-sync control on any deployment that configures it (failover drops all state, no error/warning/counter); triage correction: known findings DF-0428..0432 (unauthenticated protocol family) are unreachable as shipped and would re-arm the moment the engine is wired without authentication.", "exploit_chain": "", "evidence": [ "run.log: SIOCGETPFSYNC readback (syncdev=lo0, maxupd=128) + live pf states + 0 packets captured for proto 240 on both vtnet0 and lo0 + in-guest static grep (pfsyncif only at :90/:466/:1278/:1445/:1488; NPFSYNC only as #ifdef/#endif; use_pfsync.h absent)", "trigger_df3379.c: SIOCSETPFSYNC with syncdev+unicast peer - the unicast peer defeats the legitimate nobody listening early-out at if_pfsync.c:1294, making the zero-TX observation decisive", "VERDICT.md: full three-defect analysis and the DF-0428..0432 reachability correction", "sbin/ifconfig contains no SIOCSETPFSYNC caller at all (grep in repo) - userspace story equally vestigial" ], "kernel_refs": [ "sys/net/pf/if_pfsync.c:90", "sys/net/pf/if_pfsync.c:131-192", "sys/net/pf/if_pfsync.c:489", "sys/net/pf/if_pfsync.c:1277-1287", "sys/net/pf/if_pfsync.c:1604", "sys/net/pf/if_pfsync.c:1076-1077", "sys/netinet/in_proto.c:281-296", "sys/conf/files:1574" ], "poc_changes": "No PoC seed existed (new finding). Wrote a purpose-built SIOCSETPFSYNC trigger (syncdev + unicast peer) because DFs base ifconfig has no pfsync subcommands; the unicast peer is essential to make zero-TX a positive proof rather than an early-out artifact.", "attempts": 2, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Fri Sep 11 21:24:50 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64 (decisive run; corroborating zero-TX observation also on stock #0 at 21:09Z)", "runtime_sec": 420, "guest_dirty": 0, "build_cmd": "cc -o /root/trigger_df3379 /root/trigger_df3379.c", "run_cmd": "./run.sh (configure pfsync via trigger, enable pf keep-state, generate states, tcpdump proto 240 on vtnet0+lo0 -> 0 packets)", "code_hash": "d63987caca5f7e20b116852650ad705758a9c06ca5d6b15ed9dc356897a6b7a5", "notes": "impact=none at kernel-compromise level: the demonstrated defect is silent loss of a security-redundancy control (HA state sync), not a memory-safety or privilege issue. Guests reset clean after runs. Attempts: (1) stock kernel, peer-only config (weaker proof due to default multicast peer); (2) patched kernel, syncdev+unicast peer (decisive).", "recommended_fix": "Near term: make the dead engine loud - fail SIOCSETPFSYNC / clone creation with EOPNOTSUPP until the engine is actually wired. Full fix (assign pfsyncif in clone create/destroy, register RX, fix :1604 handler and :1076 htonl) MUST land together with peer authentication for the DF-0428..0432 family, or those five findings go live unchanged." } |