# DF-2582 - Verification Verdict

**Status:** reproduced
**Impact:** corruption
**Confidence:** certain

## Mechanism
table_append_dispatch computes mask = htonl(~((1 << (32 - mlen)) - 1)) from the user masklen with no validation. mlen==0 makes the shift count 32, mlen>32 makes it negative (both UB); on x86 the count masks to 5 bits so the stored mask is silently WRONG (33 -> /1, 64 -> /32, 0 -> /32).

## Verdict
REPRODUCED as root on the stock guest (kldload ipfw3 + ipfw3_basic, firewall disabled during the test): APPEND accepts masklen 0, 33 and 64 (setsockopt rc=0 each). Behavioral proof in one table: empty table -> 1.2.3.4 not found; honest 10.1.2.0/24 -> 10.1.2.9 found / 10.9.9.9 not found; after appending 11.0.0.5/33 the entry is stored as 0.0.0.0/1, so 99.0.0.1 (top bit 0) now MATCHES the table while 200.1.1.1 does not - the bogus catch-all from the unbounded shift is live in the radix lookup tree the firewall datapath uses. Root-gated (raw socket).

## Threat / reachability
Root-configured firewall tables silently match the wrong prefixes (a /33 rule behaves like a /1 catch-all); combined with rule logic this is rule-bypass/enabler territory, but only reachable by the firewall administrator.

## Privilege escalation assessment
n/a (root-gated configuration path)

## Fix
Validate mlen (reject >32, special-case 0 -> zero mask) before the shift.

## Kernel references
- `sys/net/ipfw3_basic/ip_fw3_table.c:161`
- `sys/net/ipfw3_basic/ip_fw3_table.c:164`

## 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.
