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.

Reply via email to