{
  "finding_id": "DF-3420",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "Code-certain lifetime defect: pfi_update_status() bcopys the pf group ifg_members TAILQ head without the ifgroup lock (pf_if.c:722-724) and then walks that snapshot under LK_SHARED (pf_if.c:736-758); a concurrently removed+kfreed ifg_member (if.c:1224, under LK_EXCLUSIVE) that was head-of-list at snapshot time is dereferenced after free. Three adversarial stress rounds on the 6-cpu INVARIANTS guest (30k pfctl -si + 3k tap churn; 2M tight DIOCGETSTATUS + 8k churn; 3M tight DIOCGETSTATUS + 6k oldest-member churn targeting the head-entry pattern) totalled >5.3M status calls and never hit the few-instruction window; no panic, no corruption observed. Root-vs-root only (/dev/pf 0600, group ops are admin). Filed Low: hardening-scope lifetime bug, realistic impact negligible.",
  "exploit_chain": "",
  "evidence": [
    "findings/poc/DF-3420/README.md \u2014 defect description, stress matrix (3 rounds, >5.3M iterations), proposed lock-scope fix",
    "findings/poc/DF-3420/setstatif.c \u2014 sets pf status-if to the group name so DIOCGETSTATUS exercises the group branch",
    "findings/poc/DF-3420/statloop.c \u2014 tight DIOCGETSTATUS loop used for rounds 2-3",
    "sys/net/pf/pf_if.c:722-724 \u2014 unlocked bcopy of ifg_members head",
    "sys/net/pf/pf_if.c:736-738 \u2014 walk of the snapshot under LK_SHARED",
    "sys/net/if.c:1186,1224 \u2014 membership insert/remove under LK_EXCLUSIVE, kfree of ifg_member"
  ],
  "kernel_refs": [
    "sys/net/pf/pf_if.c:722-724",
    "sys/net/pf/pf_if.c:736-738",
    "sys/net/if.c:1224"
  ],
  "poc_changes": "Authored from scratch: setstatif.c (DIOCSETSTATUSIF to a group name), statloop.c (tight ioctl loop; first version used a guessed struct size and failed with Operation not supported - fixed by compiling against the guests /usr/src pfvar.h), churn scripts cycling tap create/destroy including the oldest-member/head-of-list pattern.",
  "attempts": 3,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026\troot@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC\tx86_64",
  "runtime_sec": 540,
  "guest_dirty": 0,
  "build_cmd": "cc -O -I/usr/src/sys -I/usr/src/sys/net -o /tmp/statloop /tmp/statloop.c",
  "run_cmd": "/tmp/setstatif tap && (/tmp/churn*.sh & /tmp/statloop 3000000 & wait)",
  "code_hash": "",
  "notes": "Stress logs: round outputs statloop done N / CHURN-DONE captured in /tmp/s3420{,b,c,d}.log on the guest during the run; guest was reset clean afterwards. Downgraded Medium->Low: window is the span between bcopy and lockmgr (nanoseconds), and both racing operations require root.",
  "recommended_fix": "Acquire ifgroup_lockmgr(LK_SHARED) before the bcopy of ifg_members and hold it through the walk; see fix sketch in README.md",
  "fix_status": "not_testable",
  "fix_kernel_uname": "",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Baseline never reproduced, so fix validation is not meaningful; the lock-scope fix in README.md removes the unlocked snapshot by construction.",
  "fix_evidence": ""
}