DragonFlyBSD Kernel Audit
DF-0428 / live_injection_test.txt
← back to finding ↓ download raw
========== LIVE PFSYNC PACKET INJECTION TEST ==========
Date: $(date)
Guest: DragonFly 6.5-DEVELOPMENT #0 (with-src snapshot, INVARIANTS ON)

Test: Sent IPPROTO_PFSYNC(240) packets with PFSYNC_ACT_CLR payload
      to loopback (127.0.0.1) and multicast (224.0.0.240)

Preconditions:
- pf.ko loaded (kldload pf)
- pfsync0 interface exists (auto-created when pf.ko loads)
- Raw socket for IPPROTO_PFSYNC created successfully

Result:
- Packet sent: [OK] sent 32 bytes to loopback (IPPROTO_PFSYNC CLR)
- Packet sent: [OK] sent 32 bytes to 224.0.0.240 (IPPROTO_PFSYNC CLR)
- pfsyncstats (netstat -s): EMPTY before and after (no pfsync protocol activity)
- dmesg: NO pfsync messages
- Guest stayed UP (no panic, no state changes)

Root cause: in_proto.c:281-296 wraps the IPPROTO_PFSYNC protocol entry in
  #ifdef NPFSYNC. NPFSYNC is never defined anywhere in sys/. Therefore
  ip_protox[IPPROTO_PFSYNC] is not initialized to point to pfsync_input.
  Incoming IPPROTO_PFSYNC packets are handled by rip_input (raw IP handler),
  never reaching pfsync_input. pf.ko does not dynamically register the
  protocol handler (no proto_register/domain_add call for pfsync in the
  module init code).

Conclusion: pfsync_input is DEAD CODE on this kernel. The finding's claim
  that pfsync_input is a "live IPPROTO_PFSYNC(240) handler" is INCORRECT.
  The stale comment "not yet called" in in_proto.c is actually ACCURATE.