pf crashes in pfr_update_stats()

David Siebörger d.sieborger at ru.ac.za
Thu Jan 26 14:38:33 UTC 2012


Hi,

I have a pair of FreeBSD 9.0-RELEASE firewalls which are crashing 
repeatedly.  I've been able to connect to one of them with remote kgdb 
after it crashed (see kgdb session attached), but I haven't been able to 
get to the bottom of what's wrong.  Is anyone able to shed more light on 
this?

The first problem that I see is that the kt argument to 
pfr_update_stats() is null, so the kernel panics as soon as that's 
dereferenced.

Where pfr_update_stats() is called from pf_test(), kgdb tells me that 
"Variable "tr" is not available."  (Is that because of a gcc 
optimisation?)  But, tr ought to equal r in this instance, and r is 
available, so I looked at r.  r->dst.addr.p.tbl is indeed null.

Does anyone have any theories about why that could be the case, or 
anything else that I could do to debug this?  I can provide more 
configuration information if needed.


-- 
David Siebörger
System Administrator, IT Division, Rhodes University
-------------- next part --------------
# kgdb -r /dev/cuau0 /usr/obj/usr/src/sys/FIREWALL/kernel.debug
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "amd64-marcel-freebsd"...
Switching to remote protocol
pfr_update_stats (kt=0x0, a=0xfffffe000e0a4c90, af=2 '\002', len=48,
    dir_out=0, op_pass=0, notrule=0)
    at /usr/src/sys/contrib/pf/net/pf_table.c:2242
2242            if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL)

(kgdb) where
#0  pfr_update_stats (kt=0x0, a=0xfffffe000e0a4c90, af=2 '\002', len=48,
    dir_out=0, op_pass=0, notrule=0)
    at /usr/src/sys/contrib/pf/net/pf_table.c:2242
#1  0xffffffff8031140c in pf_test (dir=1, ifp=Variable "ifp" is not available.
)
    at /usr/src/sys/contrib/pf/net/pf.c:7064
#2  0xffffffff80316b5b in pf_check_in (arg=Variable "arg" is not available.
)
    at /usr/src/sys/contrib/pf/net/pf_ioctl.c:4139
#3  0xffffffff8093965e in pfil_run_hooks (ph=Variable "ph" is not available.
) at /usr/src/sys/net/pfil.c:82
#4  0xffffffff809a0907 in ip_input (m=0xfffffe000e0a4c00)
    at /usr/src/sys/netinet/ip_input.c:510
#5  0xffffffff8093892b in netisr_dispatch_src (proto=1, source=Variable "source" is not available.
)
    at /usr/src/sys/net/netisr.c:1013
#6  0xffffffff8092dd6d in ether_demux (ifp=0xfffffe0003d91000, m=dwarf2_read_address: Corrupted DWARF expression.
)
    at /usr/src/sys/net/if_ethersubr.c:937
#7  0xffffffff8092e044 in ether_nh_input (m=Variable "m" is not available.
)
    at /usr/src/sys/net/if_ethersubr.c:756
#8  0xffffffff8093892b in netisr_dispatch_src (proto=9, source=Variable "source" is not available.
)
    at /usr/src/sys/net/netisr.c:1013
#9  0xffffffff8092dc8f in ether_demux (ifp=0xfffffe0002acb000, m=dwarf2_read_address: Corrupted DWARF expression.
)
    at /usr/src/sys/net/if_ethersubr.c:846
#10 0xffffffff8092e044 in ether_nh_input (m=Variable "m" is not available.
)
    at /usr/src/sys/net/if_ethersubr.c:756
#11 0xffffffff8093892b in netisr_dispatch_src (proto=9, source=Variable "source" is not available.
)
    at /usr/src/sys/net/netisr.c:1013
#12 0xffffffff8043f88a in bce_intr (xsc=Variable "xsc" is not available.
) at /usr/src/sys/dev/bce/if_bce.c:6600
#13 0xffffffff80849c74 in intr_event_execute_handlers (p=Variable "p" is not available.
)
    at /usr/src/sys/kern/kern_intr.c:1257
#14 0xffffffff8084b434 in ithread_loop (arg=0xfffffe0002b0dc00)
    at /usr/src/sys/kern/kern_intr.c:1270
#15 0xffffffff808468cf in fork_exit (
    callout=0xffffffff8084b390 <ithread_loop>, arg=0xfffffe0002b0dc00,
    frame=0xffffff80f6d19c50) at /usr/src/sys/kern/kern_fork.c:995
#16 0xffffffff80b5fd6e in fork_trampoline ()
    at /usr/src/sys/amd64/amd64/exception.S:602
#17 0x0000000000000000 in ?? ()
#18 0x0000000000000000 in ?? ()
#19 0x0000000000000001 in ?? ()
#20 0x0000000000000000 in ?? ()
#21 0x0000000000000000 in ?? ()
#22 0x0000000000000000 in ?? ()
#23 0x0000000000000000 in ?? ()
#24 0x0000000000000000 in ?? ()
#25 0x0000000000000000 in ?? ()
#26 0x0000000000000000 in ?? ()
#27 0x0000000000000000 in ?? ()
#28 0x0000000000000000 in ?? ()
#29 0x0000000000000000 in ?? ()
#30 0x0000000000000000 in ?? ()
---Type <return> to continue, or q <return> to quit---
#31 0x0000000000000000 in ?? ()
#32 0x0000000000000000 in ?? ()
#33 0x0000000000000000 in ?? ()
#34 0x0000000000000000 in ?? ()
#35 0x0000000000000000 in ?? ()
#36 0x0000000000000000 in ?? ()
#37 0x0000000000000000 in ?? ()
#38 0x0000000000000000 in ?? ()
#39 0x0000000000000000 in ?? ()
#40 0x0000000000000000 in ?? ()
#41 0xffffffff81192900 in affinity ()
#42 0xfffffe0002ac7000 in ?? ()
#43 0x0000000000000000 in ?? ()
#44 0xfffffe0002ac7000 in ?? ()
#45 0xffffff80f6d19b40 in ?? ()
#46 0xffffff80f6d19ae8 in ?? ()
#47 0xfffffe0002907460 in ?? ()
#48 0xffffffff8089c3d2 in sched_switch (td=0xffffffff8084b390,
    newtd=0xfffffe0002b0dc00, flags=dwarf2_read_address: Corrupted DWARF expression.
) at /usr/src/sys/kern/sched_ule.c:1848
Previous frame inner to this frame (corrupt stack?)
(kgdb) info args
kt = (struct pfr_ktable *) 0x0
a = (struct pf_addr *) 0xfffffe000e0a4c90
af = 2 '\002'
len = 48
dir_out = 0
op_pass = 0
notrule = 0
(kgdb) p *a
$1 = {pfa = {v4 = {s_addr = 3414615954}, v6 = {__u6_addr = {
        __u6_addr8 = "\222ç\206˼&\000\031ÉUÿï\000\000\000", __u6_addr16 = {
          59282, 52102, 9916, 6400, 21961, 61439, 0, 0}, __u6_addr32 = {
          3414615954, 419440316, 4026488265, 0}}},
    addr8 = "\222ç\206˼&\000\031ÉUÿï\000\000\000", addr16 = {59282, 52102,
      9916, 6400, 21961, 61439, 0, 0}, addr32 = {3414615954, 419440316,
      4026488265, 0}}}
(kgdb) up
#1  0xffffffff8031140c in pf_test (dir=1, ifp=Variable "ifp" is not available.
)
    at /usr/src/sys/contrib/pf/net/pf.c:7064
7064                            pfr_update_stats(tr->dst.addr.p.tbl,
(kgdb) info args
dir = 1
ifp = Variable "ifp" is not available.
(kgdb) p tr
Variable "tr" is not available.
(kgdb) p nr
Variable "nr" is not available.
(kgdb) p s
$2 = (struct pf_state *) 0x0
(kgdb) p pd.nat_rule
$3 = (struct pf_rule *) 0x0
(kgdb) p r
$4 = (struct pf_rule *) 0xfffffe000f2593a8
(kgdb) p *r
$5 = {src = {addr = {v = {a = {addr = {pfa = {v4 = {s_addr = 0}, v6 = {
                __u6_addr = {__u6_addr8 = '\0' <repeats 15 times>,
                  __u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0}, __u6_addr32 = {0, 0,
                    0, 0}}}, addr8 = '\0' <repeats 15 times>, addr16 = {0, 0,
                0, 0, 0, 0, 0, 0}, addr32 = {0, 0, 0, 0}}}, mask = {pfa = {
              v4 = {s_addr = 0}, v6 = {__u6_addr = {
                  __u6_addr8 = '\0' <repeats 15 times>, __u6_addr16 = {0, 0,
                    0, 0, 0, 0, 0, 0}, __u6_addr32 = {0, 0, 0, 0}}},
              addr8 = '\0' <repeats 15 times>, addr16 = {0, 0, 0, 0, 0, 0, 0,
                0}, addr32 = {0, 0, 0, 0}}}},
        ifname = '\0' <repeats 15 times>, tblname = '\0' <repeats 31 times>,
        rtlabelname = '\0' <repeats 31 times>, rtlabel = 0}, p = {dyn = 0x0,
        tbl = 0x0, dyncnt = 0, tblcnt = 0}, type = 0 '\0', iflags = 0 '\0'},
    port = {0, 0}, neg = 0 '\0', port_op = 0 '\0'}, dst = {addr = {v = {a = {
          addr = {pfa = {v4 = {s_addr = 1970168173}, v6 = {__u6_addr = {
                  __u6_addr8 = "manualblock\000\000\000\000", __u6_addr16 = {
                    24941, 30062, 27745, 27746, 25455, 107, 0, 0},
                  __u6_addr32 = {1970168173, 1818389601, 7037807, 0}}},
              addr8 = "manualblock\000\000\000\000", addr16 = {24941, 30062,
                27745, 27746, 25455, 107, 0, 0}, addr32 = {1970168173,
                1818389601, 7037807, 0}}}, mask = {pfa = {v4 = {s_addr = 0},
              v6 = {__u6_addr = {__u6_addr8 = '\0' <repeats 15 times>,
                  __u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0}, __u6_addr32 = {0, 0,
                    0, 0}}}, addr8 = '\0' <repeats 15 times>, addr16 = {0, 0,
                0, 0, 0, 0, 0, 0}, addr32 = {0, 0, 0, 0}}}},
        ifname = "manualblock\000\000\000\000",
        tblname = "manualblock", '\0' <repeats 20 times>,
        rtlabelname = "manualblock", '\0' <repeats 20 times>,
        rtlabel = 1970168173}, p = {dyn = 0x0, tbl = 0x0, dyncnt = 0,
        tblcnt = 0}, type = 3 '\003', iflags = 0 '\0'}, port = {0, 0},
    neg = 0 '\0', port_op = 0 '\0'}, skip = {{ptr = 0xfffffe000f105000,
      nr = 252727296}, {ptr = 0xfffffe000e9573a8, nr = 244675496}, {
      ptr = 0xfffffe000e988af8, nr = 244878072}, {ptr = 0xfffffe000e988af8,
      nr = 244878072}, {ptr = 0xfffffe000e988af8, nr = 244878072}, {
      ptr = 0xfffffe0098924750, nr = 2559723344}, {ptr = 0xfffffe000e988af8,
      nr = 244878072}, {ptr = 0xfffffe000e988af8, nr = 244878072}},
  label = '\0' <repeats 63 times>,
  ifname = "tenet0\000\000\000\000\000\000\000\000\000",
  qname = '\0' <repeats 63 times>, pqname = '\0' <repeats 63 times>,
  tagname = '\0' <repeats 63 times>, match_tagname = '\0' <repeats 63 times>,
  overload_tblname = '\0' <repeats 31 times>, entries = {
    tqe_next = 0xfffffe000f105000, tqe_prev = 0x0}, rpool = {list = {
      tqh_first = 0x0, tqh_last = 0xfffffe000f2595d8}, cur = 0x0, key = {
      pfk = {key8 = '\0' <repeats 15 times>, key16 = {0, 0, 0, 0, 0, 0, 0, 0},
        key32 = {0, 0, 0, 0}}}, counter = {pfa = {v4 = {s_addr = 0}, v6 = {
          __u6_addr = {__u6_addr8 = '\0' <repeats 15 times>, __u6_addr16 = {0,
              0, 0, 0, 0, 0, 0, 0}, __u6_addr32 = {0, 0, 0, 0}}},
        addr8 = '\0' <repeats 15 times>, addr16 = {0, 0, 0, 0, 0, 0, 0, 0},
---Type <return> to continue, or q <return> to quit---
        addr32 = {0, 0, 0, 0}}}, tblidx = 0, proxy_port = {0, 0},
    port_op = 0 '\0', opts = 0 '\0'}, evaluations = 123840, packets = {363,
    0}, bytes = {29033, 0}, kif = 0xfffffe000e0b3e00, anchor = 0x0,
  overload_tbl = 0x0, os_fingerprint = 0, rtableid = -1, timeout = {
    0 <repeats 20 times>}, states_cur = 0, states_tot = 0, max_states = 0,
  src_nodes = 0, max_src_nodes = 0, max_src_states = 0, spare1 = 0,
  max_src_conn = 0, max_src_conn_rate = {limit = 0, seconds = 0}, qid = 0,
  pqid = 0, rt_listid = 0, nr = 4294967295, prob = 0, cuid = 0, cpid = 38081,
  return_icmp = 771, return_icmp6 = 260, max_mss = 0, tag = 0, match_tag = 0,
  spare2 = 0, uid = {uid = {0, 0}, op = 0 '\0'}, gid = {gid = {0, 0},
    op = 0 '\0'}, rule_flag = 8, action = 1 '\001', direction = 1 '\001',
  log = 1 '\001', logif = 0 '\0', quick = 1 '\001', ifnot = 0 '\0',
  match_tag_not = 0 '\0', natpass = 0 '\0', keep_state = 0 '\0', af = 0 '\0',
  proto = 0 '\0', type = 0 '\0', code = 0 '\0', flags = 0 '\0',
  flagset = 0 '\0', min_ttl = 0 '\0', allow_opts = 0 '\0', rt = 0 '\0',
  return_ttl = 0 '\0', tos = 0 '\0', set_tos = 0 '\0',
  anchor_relative = 0 '\0', anchor_wildcard = 0 '\0', flush = 0 '\0',
  divert = {addr = {pfa = {v4 = {s_addr = 0}, v6 = {__u6_addr = {
            __u6_addr8 = '\0' <repeats 15 times>, __u6_addr16 = {0, 0, 0, 0,
              0, 0, 0, 0}, __u6_addr32 = {0, 0, 0, 0}}},
        addr8 = '\0' <repeats 15 times>, addr16 = {0, 0, 0, 0, 0, 0, 0, 0},
        addr32 = {0, 0, 0, 0}}}, port = 0}}
(kgdb) p r->dst.addr.p.tbl
$6 = (struct pfr_ktable *) 0x0
(kgdb) p r->dst.addr.p
$7 = {dyn = 0x0, tbl = 0x0, dyncnt = 0, tblcnt = 0}
(kgdb) p r->dst.addr
$8 = {v = {a = {addr = {pfa = {v4 = {s_addr = 1970168173}, v6 = {__u6_addr = {
              __u6_addr8 = "manualblock\000\000\000\000", __u6_addr16 = {
                24941, 30062, 27745, 27746, 25455, 107, 0, 0}, __u6_addr32 = {
                1970168173, 1818389601, 7037807, 0}}},
          addr8 = "manualblock\000\000\000\000", addr16 = {24941, 30062,
            27745, 27746, 25455, 107, 0, 0}, addr32 = {1970168173, 1818389601,
            7037807, 0}}}, mask = {pfa = {v4 = {s_addr = 0}, v6 = {
            __u6_addr = {__u6_addr8 = '\0' <repeats 15 times>, __u6_addr16 = {
                0, 0, 0, 0, 0, 0, 0, 0}, __u6_addr32 = {0, 0, 0, 0}}},
          addr8 = '\0' <repeats 15 times>, addr16 = {0, 0, 0, 0, 0, 0, 0, 0},
          addr32 = {0, 0, 0, 0}}}}, ifname = "manualblock\000\000\000\000",
    tblname = "manualblock", '\0' <repeats 20 times>,
    rtlabelname = "manualblock", '\0' <repeats 20 times>,
    rtlabel = 1970168173}, p = {dyn = 0x0, tbl = 0x0, dyncnt = 0, tblcnt = 0},
  type = 3 '\003', iflags = 0 '\0'}


More information about the freebsd-pf mailing list