https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=288274
Bug ID: 288274 Summary: pf_test() can use an mbuf freed by pf_route() Product: Base System Version: CURRENT Hardware: Any OS: Any Status: New Severity: Affects Some People Priority: --- Component: kern Assignee: b...@freebsd.org Reporter: r...@lcs.mit.edu Attachment #262227 text/plain mime type: Created attachment 262227 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=262227&action=edit cause pf_route() to free an mbuf subsequently used by pf_test() In this code around line 10922 in pf.c: #ifdef INET if (pd.naf == AF_INET) pf_route(r, kif->pfik_ifp, s, &pd, inp); #endif /* INET */ ... *m0 = pd.m; action = PF_PASS; goto out; ... out: ... pf_sctp_multihome_delayed(&pd, kif, s, action); If something goes wrong in pf_route(), it may mfree pd.m. But then pf_test() can continue using pd.m, leading to use-after-free. I've attached a demo that sets up pf with: block in from urpf-failed to any pass in inet6 from any to 64:ff9b::/96 af-to inet from 7.0.0.2 keep state The demo sends an ip6/sctp packet into tun0 with ttl=0; the ttl=0 causes pf_route() on the ip6->ip4 translated packet to fail and free the mbuf. With INVARIANTS, I get this KASSERT because pf_match_rule() calls M_GETFIB(pd->m) while pd->m is filled with 0xdeadc0de: panic: rt_m_getfib: Attempt to get FIB from non header mbuf 0xfffff8006562c000 #0 panic ( fmt=0xffffffc0009943fa "%s: Attempt to get FIB from non header mbuf %p") at /usr/rtm/symbsd/src/sys/kern/kern_shutdown.c:886 #1 0xffffffc000761d54 in rt_m_getfib (m=0xffffffd01435b500) at /usr/rtm/symbsd/src/sys/sys/mbuf.h:1537 #2 pf_match_rule (ctx=0xffffffc082ce32a8, ruleset=0xffffffc03e0f1938) at /usr/rtm/symbsd/src/sys/netpfil/pf/pf.c:5567 #3 0xffffffc000768688 in pf_test_rule (rm=0xffffffc082ce3670, sm=0xffffffc082ce3680, pd=0xffffffd001bb5210, am=0xffffffc082ce3678, rsm=<optimized out>, reason=0xffffffc082ce3666, inp=<optimized out>) at /usr/rtm/symbsd/src/sys/netpfil/pf/pf.c:5858 #4 0xffffffc000767816 in pf_sctp_multihome_delayed (pd=0xffffffc082ce3488, kif=0xffffffd001146b00, s=0xffffffd0144e9480, action=<optimized out>) at /usr/rtm/symbsd/src/sys/netpfil/pf/pf.c:7457 #5 pf_test (af=<optimized out>, dir=<optimized out>, pflags=65280, ifp=<optimized out>, m0=<optimized out>, inp=<optimized out>, default_actions=<optimized out>) at /usr/rtm/symbsd/src/sys/netpfil/pf/pf.c:10980 #6 0xffffffc00077bd04 in pf_check6_in (m=0xffffffc082ce3778, ifp=<optimized out>, flags=339064064, ruleset=<optimized out>, inp=<optimized out>) at /usr/rtm/symbsd/src/sys/netpfil/pf/pf_ioctl.c:6616 #7 0xffffffc000580a86 in pfil_mbuf_common (pch=<optimized out>, m=0xffffffc082ce3778, ifp=0xffffffd001b5a800, flags=65536, inp=0x0) at /usr/rtm/symbsd/src/sys/net/pfil.c:213 #8 pfil_mbuf_in (head=<optimized out>, m=0xffffffc082ce3778, ifp=0xffffffd001b5a800, inp=0x0) at /usr/rtm/symbsd/src/sys/net/pfil.c:231 #9 0xffffffc0006db8f4 in ip6_input (m=0x0) at /usr/rtm/symbsd/src/sys/netinet6/ip6_input.c:743 With that KASSERT commented out, the resulting fibnum=0xc0de can eventually lead to a kernel page fault; in my kernel, the crash is here: #0 fib6_check_urpf (fibnum=49374, dst6=0xffffffd001bb5244, scopeid=0, flags=0, src_if=0xffffffd001b5a800) at /usr/rtm/symbsd/src/sys/netinet6/in6_fib.c:281 #1 0xffffffc0007627b4 in pf_routable (addr=<optimized out>, af=<optimized out>, kif=<optimized out>, rtableid=<optimized out>) at /usr/rtm/symbsd/src/sys/netpfil/pf/pf.c:8908 #2 0xffffffc00076148e in pf_match_rule (ctx=0xffffffc082ce32a8, ruleset=0xffffffc03e0f1938) at /usr/rtm/symbsd/src/sys/netpfil/pf/pf.c:5567 #3 0xffffffc000768626 in pf_test_rule (rm=0xffffffc082ce3670, sm=0xffffffc082ce3680, pd=0xffffffd001bb5210, am=0xffffffc082ce3678, rsm=<optimized out>, reason=0xffffffc082ce3666, inp=<optimized out>) at /usr/rtm/symbsd/src/sys/netpfil/pf/pf.c:5858 #4 0xffffffc0007677b4 in pf_sctp_multihome_delayed (pd=0xffffffc082ce3488, kif=0xffffffd001146b00, s=0xffffffd014caa480, action=<optimized out>) at /usr/rtm/symbsd/src/sys/netpfil/pf/pf.c:7457 #5 pf_test (af=<optimized out>, dir=<optimized out>, pflags=65280, ifp=<optimized out>, m0=<optimized out>, inp=<optimized out>, default_actions=<optimized out>) at /usr/rtm/symbsd/src/sys/netpfil/pf/pf.c:10980 #6 0xffffffc00077bc88 in pf_check6_in (m=0xffffffc082ce3778, ifp=<optimized out>, flags=0, ruleset=<optimized out>, inp=<optimized out>) at /usr/rtm/symbsd/src/sys/netpfil/pf/pf_ioctl.c:6616 #7 0xffffffc000580a86 in pfil_mbuf_common (pch=<optimized out>, m=0xffffffc082ce3778, ifp=0xffffffd001b5a800, flags=65536, inp=0x0) at /usr/rtm/symbsd/src/sys/net/pfil.c:213 #8 pfil_mbuf_in (head=<optimized out>, m=0xffffffc082ce3778, ifp=0xffffffd001b5a800, inp=0x0) at /usr/rtm/symbsd/src/sys/net/pfil.c:231 #9 0xffffffc0006db8b4 in ip6_input (m=0x0) at /usr/rtm/symbsd/src/sys/netinet6/ip6_input.c:743 -- You are receiving this mail because: You are the assignee for the bug.