# DF-3362 fix validation (single-fix kernel, in-guest)

## Build
- fix.diff applied to the guest's /usr/src (patch -p1, hunks 1+2 succeeded).
- cd /usr/src && make nativekernel && make installkernel
  (full log /root/poc/build.log on the guest; pf_norm.c compiled with
  the module's -Werror flag set and linked into pf.ko — see
  fixbuild_excerpt.txt; install completed 10:37:04 UTC 2026).
- Rebooted; `uname -v`:
  DragonFly 6.5-DEVELOPMENT #1: Fri Sep 11 10:20:27 UTC 2026
  root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC

## Baseline (pre-fix, stock kernel #0)
Same setup (kldload pf; tap0 up; scrub in on tap0 all fragment crop;
pfctl -e) and same trigger:
  panic: (*m0)->m_next != NULL: pf_fragcache
  pf_fragcache() at pf_fragcache+0xcef
  pf_normalize_ip() at pf_normalize_ip+0x49d
  pf_test() ... pfil_run_hooks() ...
Guest died in DDB (panic.txt).

## Patched (kernel #1 with fix.diff)
Same setup, same trigger:
  wrote frag off=0 len=8000 mf=1 (8034 bytes)
  wrote frag off=496 len=8000 mf=1 (8034 bytes)
  done
  EXIT=0
  uptime: up 42 secs, load averages: 0.25 ...   (guest alive, no panic)

Regression controls on the patched kernel:
- scrub max-mss TCP path: 5000 malformed-MSS packets, EXIT=0, no panic.
- scrub fragment reassemble path (untouched by this fix, negative
  control): 6000-fragment burst in 0.1s → 5.86K concurrent pffrag/
  pffrent entries (DF-3361 still present, as expected for a single-fix
  build), guest healthy.

## Conclusion
fix_status: fixed — the previously-observed panic is gone, the chop
path completes, and neighboring pf normalization paths still function.
(The fix also reorders the m_dup NULL check ahead of the m_adj
argument evaluation, closing DF-0391's NULL deref in the same hunk.)
