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>
