Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Jul 2025 21:08:15 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 288224] pf_translate_af() can cause NULL deref if ip6_plen is too big
Message-ID:  <bug-288224-227@https.bugs.freebsd.org/bugzilla/>

index | next in thread | raw e-mail

https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=288224

            Bug ID: 288224
           Summary: pf_translate_af() can cause NULL deref if ip6_plen is
                    too big
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Some People
          Priority: ---
         Component: kern
          Assignee: bugs@FreeBSD.org
          Reporter: rtm@lcs.mit.edu
 Attachment #262155 text/plain
         mime type:

Created attachment 262155
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=262155&action=edit
demo a pf_translate_af() bug

If pf is translating ip6 to ip4, and it receives an IPPROTO_ICMPV6
packet, and ip6_plen is too big, pf_translate_af() can call
in4_cksum() with a len argument that's larger than the mbuf data,
causing a KASSERT or a NULL dereference.

ip6_input() calls packet filters before checking ip6_plen:

        if (pfil_mbuf_in(V_inet6_pfil_head, &m, m->m_pkthdr.rcvif,
            NULL) != PFIL_PASS)
                return;
        ...
        if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) {

Then ip6_plen makes its way to the in4_cksum() call:

pf_setup_pdesc():
                pd->tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr);

pf_translate_af():
                ip4->ip_len = htons(hlen + (pd->tot_len - pd->off));
                ...
                    in4_cksum(pd->m, 0, hlen, ntohs(ip4->ip_len) - hlen) :

I've attached a demo program that configures tap0 and tap1 and
installs a pf firewall configuration consisting of just:

pass in on tap0 inet6 from any to any af-to inet from 192.168.3.1 keep state

and then sends this ethernet/ip6/icmp6 packet, with a huge ip6_plen,
into tap0:

00 03 03 03 03 03 00 04 04 04 04 04 86 dd 60 ff ff ff 27 0f 3a 64 20
01 0d b8 46 72 65 65 20 26 50 43 2d 42 53 45 00 00 00 00 46 73 65 66
20 26 50 43 2d 42 53 47 80 d2 00 16 00 00 00 01 00 00 00 00 50 02 04
00

The result is an INVARIANTS panic or a NULL dereference:

# uname -a
FreeBSD xxx 15.0-CURRENT FreeBSD 15.0-CURRENT #30 main-n275522-551d428b5bdc:
Fri Jun 27 16:05:41 AST 2025    
root@xxx:/usr/obj/usr/src/amd64.amd64/sys/GENERIC amd64
# cc npf6b.c
# ./a.out
...
panic: m_apply, length > size of mbuf chain (9983 extra)
cpuid = 11
time = 1752520329
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe00d6d98450
vpanic() at vpanic+0x136/frame 0xfffffe00d6d98580
panic() at panic+0x43/frame 0xfffffe00d6d985e0
m_apply() at m_apply+0x2d3/frame 0xfffffe00d6d98630
in_cksum_skip() at in_cksum_skip+0x2f/frame 0xfffffe00d6d98650
in4_cksum() at in4_cksum+0x58/frame 0xfffffe00d6d98670
pf_translate_af() at pf_translate_af+0x2aa/frame 0xfffffe00d6d986c0
pf_test() at pf_test+0x13b9/frame 0xfffffe00d6d98990
pf_check6_in() at pf_check6_in+0x5d/frame 0xfffffe00d6d989c0
pfil_mbuf_in() at pfil_mbuf_in+0x58/frame 0xfffffe00d6d989f0
ip6_input() at ip6_input+0x6be/frame 0xfffffe00d6d98ad0
netisr_dispatch_src() at netisr_dispatch_src+0xb4/frame 0xfffffe00d6d98b30
ether_demux() at ether_demux+0x16a/frame 0xfffffe00d6d98b60
ether_nh_input() at ether_nh_input+0x3ce/frame 0xfffffe00d6d98bb0
netisr_dispatch_src() at netisr_dispatch_src+0xb4/frame 0xfffffe00d6d98c10
ether_input() at ether_input+0xd5/frame 0xfffffe00d6d98c70
tunwrite() at tunwrite+0x57d/frame 0xfffffe00d6d98ce0
devfs_write_f() at devfs_write_f+0xf3/frame 0xfffffe00d6d98d40
dofilewrite() at dofilewrite+0x81/frame 0xfffffe00d6d98d90
sys_write() at sys_write+0xb7/frame 0xfffffe00d6d98e00
amd64_syscall() at amd64_syscall+0x169/frame 0xfffffe00d6d98f30
fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe00d6d98f30
--- syscall (4, FreeBSD ELF64, write), rip = 0x8233b2e9a, rsp = 0x820a204c8,
rbp = 0x820a20580 ---

-- 
You are receiving this mail because:
You are the assignee for the bug.

home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-288224-227>