Markus Lude wrote:
> Description:
>       updated to latest snapshot from 22/23 december
>       kernel panic on system startup
> 
> panic: kernel diagnostic assertion "!pf_state_key_isvalid(sk)" failed: file 
> "../../../../net/pf.c", line 6830
> Stopped at    Debugger+0x8:   nop
>    TID    PID    UID     PRFLAGS     PFLAGS  CPU  COMMAND                     
>    
> *17325  17325     92    0x100010          0    0  rtadvd                      
>    
> __assert(1620858, 1689630, 1aae, 1689688, 0, a82ec0d4e0) at __assert+0x20
> pf_state_key_unref(400090aab60, 0, 0, 0, 0, 0) at pf_state_key_unref+0xac
> pf_pkt_unlink_state_key(40008df4300, a82f00f000, fffffffffffffff8, 
> 40010b18000, 1012d74, 0) at pf_pkt_unlink_state_key+0x4
> m_free(40008df4300, 0, 40010b1bb18, 0, 0, 0) at m_free+0xb4
> soreceive(4000908f900, 0, 40010b1bb18, 0, 40008df4200, 4000908f980) at 
> soreceive+0xc84
> recvit(0, 3, 40010b1bcb8, 0, 40010b1bdf0, 3b9aca00) at recvit+0x10c
> sys_recvmsg(400090a0000, 40010b1bdb0, a82f00f868, 40010b1bcd8, 400090a0048, 
> 14b) at sys_recvmsg+0x88
> syscall(40010b1bed0, 41b, aac219dfa8, aac219dfac, 0, 0) at syscall+0x34c
> softtrap(3, a82f00f898, 0, aac21648cc, 0, a82ec0d4e0) at softtrap+0x19c
> http://www.openbsd.org/ddb.html describes the minimum info required in bug
> reports.  Insufficient info makes it difficult to find and fix bugs.
> ddb> No such command
> ddb> machine     print       examine     x           search      set         

Same panic here, but with a different trace (see below).
It looks like the pf_state_key reference count is not always
updated. When the packet header of an mbuf is duplicated, the
reference count is not being increased. But freeing the old and
the duplicated mbuf would result in two pf_state_key_unref()s.

This diff made the panic go away for me:

Index: net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.961
diff -u -p -r1.961 pf.c
--- net/pf.c    22 Dec 2015 13:33:26 -0000      1.961
+++ net/pf.c    23 Dec 2015 16:21:53 -0000
@@ -6850,6 +6850,11 @@ pf_pkt_unlink_state_key(struct mbuf *m)
        m->m_pkthdr.pf.statekey = NULL;
 }
 
+void pf_pkt_state_key_ref(struct mbuf *m)
+{
+       pf_state_key_ref(m->m_pkthdr.pf.statekey);
+}
+
 void
 pf_inpcb_unlink_state_key(struct inpcb *inp)
 {
Index: net/pfvar.h
===================================================================
RCS file: /cvs/src/sys/net/pfvar.h,v
retrieving revision 1.427
diff -u -p -r1.427 pfvar.h
--- net/pfvar.h 22 Dec 2015 13:33:26 -0000      1.427
+++ net/pfvar.h 23 Dec 2015 16:21:54 -0000
@@ -1923,6 +1923,7 @@ struct pf_state_key       *pf_state_key_ref(st
 void                    pf_state_key_unref(struct pf_state_key *);
 int                     pf_state_key_isvalid(struct pf_state_key *);
 void                    pf_pkt_unlink_state_key(struct mbuf *);
+void                    pf_pkt_state_key_ref(struct mbuf *);
 
 #endif /* _KERNEL */
 
Index: kern/uipc_mbuf.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_mbuf.c,v
retrieving revision 1.215
diff -u -p -r1.215 uipc_mbuf.c
--- kern/uipc_mbuf.c    22 Dec 2015 13:33:26 -0000      1.215
+++ kern/uipc_mbuf.c    23 Dec 2015 16:22:15 -0000
@@ -1215,6 +1215,10 @@ m_dup_pkthdr(struct mbuf *to, struct mbu
        to->m_flags |= (from->m_flags & M_COPYFLAGS);
        to->m_pkthdr = from->m_pkthdr;
 
+#if NPF > 0
+       pf_pkt_state_key_ref(to);
+#endif /* NPF > 0 */
+
        SLIST_INIT(&to->m_pkthdr.ph_tags);
 
        if ((error = m_tag_copy_chain(to, from, wait)) != 0)

ddb output:
panic: kernel diagnostic assertion "!pf_state_key_isvalid(sk)" failed:
file "../../../../net/pf.c", line 6830
Stopped at      Debugger+0x9:   leave
   TID    PID    UID     PRFLAGS     PFLAGS    CPU    COMMAND
  3870   3870     83    0x100010          0      1    ntpd
*  327    327      0     0x14000      0x210      2    softnet
Debugger() at Debugger+0x9
panic() at panic+0xfe
__assert() at __assert+0x25
pf_state_key_unref() at pf_state_key_unref+0x88
pf_pkt_unlink_state_key() at pf_pkt_unlink_state_key+0x15
m_free() at m_free+0xa0
m_freem() at m_freem+0x15
icmp6_rip6_input() at icmp6_rip6_input+0x339
icmp6_input() at icmp6_input+0x1ca
ip6_input() at ip6_input+0x495
ip6intr() at ip6intr+0x18
netintr() at netintr+0x87
softintr_dispatch() at softintr_dispatch+0x8b
Xsoftnet() at Xsoftnet+0x1f
--- interrupt ---
end trace frame: 0x0, count: 1
taskq_thread:0x6c:

Reply via email to