Page MenuHomeFreeBSD

ipfw: pull up only the headers ipfw_chk() inspects
AbandonedPublic

Authored by netchild on Sep 4 2026, 1:46 PM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, Oct 16, 12:37 AM
Unknown Object (File)
Tue, Oct 13, 4:52 AM
Unknown Object (File)
Tue, Oct 13, 3:32 AM
Unknown Object (File)
Tue, Oct 13, 12:02 AM
Unknown Object (File)
Wed, Oct 7, 1:48 PM
Unknown Object (File)
Wed, Oct 7, 1:47 PM
Unknown Object (File)
Tue, Oct 6, 6:39 PM
Unknown Object (File)
Mon, Oct 5, 10:30 PM

Details

Summary

The layer-2 hook (net.link.ether.ipfw) runs ipfw_chk() on the raw
Ethernet frame, which pulled up min(m_pkthdr.len, max_protohdr) bytes to
make the L2 and L3 base headers contiguous. A sender advertising
IFCAP_MEXTPG hands it an unmapped (M_EXTPG) sendfile(2) or KTLS chain
whose mapped head is 54 bytes; max_protohdr is 60, so m_pullup() walked
six bytes into the unmapped mbuf and dereferenced a NULL mtod(),
panicking the kernel.

Pull up only the Ethernet plus the largest L3 base header ipfw reads
inline; deeper headers are already pulled up on demand. This is the same
fix as bridge_pfil().

Assisted-by: Claude Code (Fable 5)

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 76495
Build 73378: arc lint + arc unit

Event Timeline

netchild held this revision as a draft.

This is the the same issue as in D59332 (bridge).

netchild published this revision for review.Sep 4 2026, 1:48 PM

Ok, this mess mostly comes from me. While reviewing this patch I came to alternative that I will post soon.

Ok, this mess mostly comes from me. While reviewing this patch I came to alternative that I will post soon.

Do you agree that I can abandon this revision?

Ok, this mess mostly comes from me. While reviewing this patch I came to alternative that I will post soon.

Do you agree that I can abandon this revision?

Please don't rush yet, before I post mine. Will check if it passes your test case at least :)

Alternative https://reviews.freebsd.org/D59426 I will also see if the new PULLUP() can be used everywhere down below the function to easily get typed pointers with guaranteed memory length provided.