pf: add missing IPv6 length check

We failed to verify that the packet was long enough for the provided IPv6 packet
length. This could result in us walking off the end of the mbuf and panicing.

PR:		288224
Reported by:	Robert Morris <rtm@lcs.mit.edu>
Tested by:	Robert Morris <rtm@lcs.mit.edu>
Reviewed by:	emaste
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D51324
This commit is contained in:
Kristof Provost 2025-07-15 10:40:25 +02:00
parent d00f66feaa
commit cb43e97aea
2 changed files with 21 additions and 0 deletions

View file

@ -10141,6 +10141,12 @@ pf_setup_pdesc(sa_family_t af, int dir, struct pf_pdesc *pd, struct mbuf **m0,
}
h = mtod(pd->m, struct ip6_hdr *);
if (pd->m->m_pkthdr.len <
sizeof(struct ip6_hdr) + ntohs(h->ip6_plen)) {
*action = PF_DROP;
REASON_SET(reason, PFRES_SHORT);
return (-1);
}
if (pf_walk_header6(pd, h, reason) != PF_PASS) {
*action = PF_DROP;

View file

@ -272,3 +272,18 @@ class TestNAT64(VnetTestTemplate):
reply = self.common_test_source_addr(packet)
icmp = reply.getlayer(sp.ICMPv6EchoRequest)
assert icmp
@pytest.mark.require_user("root")
@pytest.mark.require_progs(["scapy"])
def test_bad_len(self):
"""
PR 288224: we can panic if the IPv6 plen is longer than the packet length.
"""
ToolsHelper.print_output("/sbin/route -6 add default 2001:db8::1")
import scapy.all as sp
packet = sp.IPv6(dst="64:ff9b::198.51.100.2", hlim=2, plen=512) \
/ sp.ICMPv6EchoRequest() / sp.Raw("foo")
reply = sp.sr1(packet, timeout=3)
# We don't expect a reply to a corrupted packet
assert not reply