# DF-3263 VERDICT — reproduced (panic, unprivileged trigger)

## Result
`status: reproduced`, `impact: panic` (remote-triggerable DoS once the
rule exists; root-loaded rule + unauthenticated/unprivileged trigger
packet).

## How it was run
1. Guest booted (vm.sh up), `kldload pf`, stock kernel
   `DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026` (6 CPUs).
2. Root loads the rule set (`rdr_div0.conf`): pfctl accepts the reversed
   range — `pfctl -sn` shows
   `rdr pass on lo0 inet proto tcp from any to 127.0.0.1 port = 9998 -> 127.0.0.1 port 5001:5000`.
3. Unprivileged user (uid 1001 maxx) runs `trigger_div0` — a plain
   `connect("127.0.0.1", 9998)`; the SYN traverses pf_check_in on lo0,
   matches the rdr rule, enters pf_get_translation() PF_RDR branch.
4. Kernel panics before connect() returns (ssh session died;
   `vm.sh status` → down; serial log captured):

```
Fatal trap 18: integer divide fault while in kernel mode
cpuid = 0; lapic id = 0
instruction pointer = 0x8:0xffffffff8261389a
kernel: type 18 trap, code=0
Stopped at      pf_get_translation+0x31a:       idivl   %ecx,%eax
```

Trap 18 is the x86 #DE; the faulting instruction is the `idivl` of the
modulus at sys/net/pf/pf.c:3306-3310 inside pf_get_translation — the
exact predicted sink. 100% deterministic (one packet, one panic).

## Root cause chain
- usr.sbin/pfctl/parse.y `parseport()`: `5001:5000` parses to
  a=5001, b=5000 (a>b not rejected; only a==b collapses).
- pf_ioctl.c DIOCADDRULE (1262-1273): pool-list checks only; no
  proxy_port ordering validation.
- pf.c:3303 `if (r->rpool.proxy_port[1])` → true (5000) →
  pf.c:3308 divisor `5000 - 5001 + 1 = 0` → idiv trap.

## Exploit chain
Not applicable (panic/DoS class). In production this is a
remote-triggered kernel panic gated on a pfctl-loadable typo'd rule;
pfctl will happily load it from any rules file.

## Fix
Validated fix.diff (load-time validation in pf_ioctl.c + defensive
degenerate-range check in pf.c). Baseline panic captured; patched
kernel re-runs the identical trigger with no panic (see run.log /
fix validation notes in manifest).

## Impact ceiling
Denial of service (panic). No memory-safety implication (integer #DE).
Severity Medium: requires a root-loaded misconfigured rule (or root via
raw ioctl), triggered by a single unauthenticated packet.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
