Hello, On Sat, Nov 25, 2023 at 10:49:44AM +0100, j...@navratil.cz wrote: > >Synopsis: ddb{1}> on serial console > >Category: kernel > >Environment: > System : OpenBSD 7.4 > Details : OpenBSD 7.4 (GENERIC.MP) #0: Sun Oct 22 12:13:42 MDT 2023 > > r...@syspatch-74-amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP > > Architecture: OpenBSD.amd64 > Machine : amd64 > >Description: > over night the machine got to ddb{1}> > > ddb{1}> show panic > *cpu1: kernel diagnostic assertion "st->timeout == PFTM_UNLINKED" failed: > file " > /usr/src/sys/net/pf.c", line 1844 > ddb{1}> trace > db_enter() at db_enter+0x14 > panic(ffffffff820a5be3) at panic+0xc3 > __assert(ffffffff82121e5d,ffffffff8207ffa2,734,ffffffff8207ffd3) at > __assert+0x 29 > pf_free_state(fffffd80d1480838) at pf_free_state+0x1ef > pf_purge_expired_states(40,40) at pf_purge_expired_states+0x288 > pf_purge_states(0) at pf_purge_states+0x20 > taskq_thread(ffffffff824ba7d0) at taskq_thread+0x100 > end trace frame: 0x0, count: -7 > > ddb{1}> boot dump > syncing disks... > > I tried to get core dump, but the machines freezed. I had to ask technical > support to physicaly power off / power up the machine. >
The same issue got reported already by other users [1]. few users seem to happily run diff which fixes the issue [2]. The same diff is attached. thanks and regards sashan [1] https://marc.info/?t=169896604700001&r=1&w=2 [2] https://marc.info/?l=openbsd-bugs&m=169903486617859&w=2 --------8<---------------8<---------------8<------------------8<-------- Index: net/pf.c =================================================================== RCS file: /cvs/src/sys/net/pf.c,v retrieving revision 1.1186 diff -u -p -r1.1186 pf.c --- net/pf.c 8 Sep 2023 13:40:52 -0000 1.1186 +++ net/pf.c 26 Nov 2023 09:59:12 -0000 @@ -469,6 +469,15 @@ pf_state_list_remove(struct pf_state_lis pf_state_unref(st); /* list no longer references the state */ } +void +pf_update_state_timeout(struct pf_state *st, int to) +{ + mtx_enter(&st->mtx); + if (st->timeout != PFTM_UNLINKED) + st->timeout = to; + mtx_leave(&st->mtx); +} + int pf_src_connlimit(struct pf_state **stp) { @@ -549,7 +558,7 @@ pf_src_connlimit(struct pf_state **stp) ((*stp)->rule.ptr->flush & PF_FLUSH_GLOBAL || (*stp)->rule.ptr == st->rule.ptr)) { - st->timeout = PFTM_PURGE; + pf_update_state_timeout(st, PFTM_PURGE); pf_set_protostate(st, PF_PEER_BOTH, TCPS_CLOSED); killed++; @@ -563,7 +572,7 @@ pf_src_connlimit(struct pf_state **stp) } /* kill this state */ - (*stp)->timeout = PFTM_PURGE; + pf_update_state_timeout(*stp, PFTM_PURGE); pf_set_protostate(*stp, PF_PEER_BOTH, TCPS_CLOSED); return (1); } @@ -1761,7 +1770,9 @@ pf_remove_state(struct pf_state *st) if (st->timeout == PFTM_UNLINKED) return; + mtx_enter(&st->mtx); st->timeout = PFTM_UNLINKED; + mtx_leave(&st->mtx); /* handle load balancing related tasks */ pf_postprocess_addr(st); @@ -1816,7 +1827,8 @@ pf_remove_divert_state(struct pf_state_k sist->dst.state < TCPS_FIN_WAIT_2) { pf_set_protostate(sist, PF_PEER_BOTH, TCPS_TIME_WAIT); - sist->timeout = PFTM_TCP_CLOSED; + pf_update_state_timeout(sist, + PFTM_TCP_CLOSED); sist->expire = getuptime(); } sist->state_flags |= PFSTATE_INP_UNLINKED; @@ -5036,18 +5048,18 @@ pf_tcp_track_full(struct pf_pdesc *pd, s (*stp)->expire = getuptime(); if (src->state >= TCPS_FIN_WAIT_2 && dst->state >= TCPS_FIN_WAIT_2) - (*stp)->timeout = PFTM_TCP_CLOSED; + pf_update_state_timeout(*stp, PFTM_TCP_CLOSED); else if (src->state >= TCPS_CLOSING && dst->state >= TCPS_CLOSING) - (*stp)->timeout = PFTM_TCP_FIN_WAIT; + pf_update_state_timeout(*stp, PFTM_TCP_FIN_WAIT); else if (src->state < TCPS_ESTABLISHED || dst->state < TCPS_ESTABLISHED) - (*stp)->timeout = PFTM_TCP_OPENING; + pf_update_state_timeout(*stp, PFTM_TCP_OPENING); else if (src->state >= TCPS_CLOSING || dst->state >= TCPS_CLOSING) - (*stp)->timeout = PFTM_TCP_CLOSING; + pf_update_state_timeout(*stp, PFTM_TCP_CLOSING); else - (*stp)->timeout = PFTM_TCP_ESTABLISHED; + pf_update_state_timeout(*stp, PFTM_TCP_ESTABLISHED); /* Fall through to PASS packet */ } else if ((dst->state < TCPS_SYN_SENT || @@ -5229,18 +5241,18 @@ pf_tcp_track_sloppy(struct pf_pdesc *pd, (*stp)->expire = getuptime(); if (src->state >= TCPS_FIN_WAIT_2 && dst->state >= TCPS_FIN_WAIT_2) - (*stp)->timeout = PFTM_TCP_CLOSED; + pf_update_state_timeout(*stp, PFTM_TCP_CLOSED); else if (src->state >= TCPS_CLOSING && dst->state >= TCPS_CLOSING) - (*stp)->timeout = PFTM_TCP_FIN_WAIT; + pf_update_state_timeout(*stp, PFTM_TCP_FIN_WAIT); else if (src->state < TCPS_ESTABLISHED || dst->state < TCPS_ESTABLISHED) - (*stp)->timeout = PFTM_TCP_OPENING; + pf_update_state_timeout(*stp, PFTM_TCP_OPENING); else if (src->state >= TCPS_CLOSING || dst->state >= TCPS_CLOSING) - (*stp)->timeout = PFTM_TCP_CLOSING; + pf_update_state_timeout(*stp, PFTM_TCP_CLOSING); else - (*stp)->timeout = PFTM_TCP_ESTABLISHED; + pf_update_state_timeout(*stp, PFTM_TCP_ESTABLISHED); return (PF_PASS); } @@ -5377,7 +5389,7 @@ pf_test_state(struct pf_pdesc *pd, struc addlog("\n"); } /* XXX make sure it's the same direction ?? */ - (*stp)->timeout = PFTM_PURGE; + pf_update_state_timeout(*stp, PFTM_PURGE); pf_state_unref(*stp); *stp = NULL; pf_mbuf_link_inpcb(pd->m, inp); @@ -5417,9 +5429,9 @@ pf_test_state(struct pf_pdesc *pd, struc (*stp)->expire = getuptime(); if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE) - (*stp)->timeout = PFTM_UDP_MULTIPLE; + pf_update_state_timeout(*stp, PFTM_UDP_MULTIPLE); else - (*stp)->timeout = PFTM_UDP_SINGLE; + pf_update_state_timeout(*stp, PFTM_UDP_SINGLE); break; default: /* update states */ @@ -5432,9 +5444,9 @@ pf_test_state(struct pf_pdesc *pd, struc (*stp)->expire = getuptime(); if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE) - (*stp)->timeout = PFTM_OTHER_MULTIPLE; + pf_update_state_timeout(*stp, PFTM_OTHER_MULTIPLE); else - (*stp)->timeout = PFTM_OTHER_SINGLE; + pf_update_state_timeout(*stp, PFTM_OTHER_SINGLE); break; } @@ -5585,7 +5597,7 @@ pf_test_state_icmp(struct pf_pdesc *pd, return (ret); (*stp)->expire = getuptime(); - (*stp)->timeout = PFTM_ICMP_ERROR_REPLY; + pf_update_state_timeout(*stp, PFTM_ICMP_ERROR_REPLY); /* translate source/destination address, if necessary */ if ((*stp)->key[PF_SK_WIRE] != (*stp)->key[PF_SK_STACK]) {