The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=cb43e97aea11a788972f977ea68c518bfb7fc0c1
commit cb43e97aea11a788972f977ea68c518bfb7fc0c1 Author: Kristof Provost <k...@freebsd.org> AuthorDate: 2025-07-15 08:40:25 +0000 Commit: Kristof Provost <k...@freebsd.org> CommitDate: 2025-07-16 11:33:51 +0000 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 <r...@lcs.mit.edu> Tested by: Robert Morris <r...@lcs.mit.edu> Reviewed by: emaste Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D51324 --- sys/netpfil/pf/pf.c | 6 ++++++ tests/sys/netpfil/pf/nat64.py | 15 +++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index ad42f1cccd33..9acfb19645b7 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -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; diff --git a/tests/sys/netpfil/pf/nat64.py b/tests/sys/netpfil/pf/nat64.py index adae2489ce5e..5cc4713a16cc 100644 --- a/tests/sys/netpfil/pf/nat64.py +++ b/tests/sys/netpfil/pf/nat64.py @@ -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