diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -1523,15 +1523,28 @@ printf("\n"); } s->timeout = PFTM_UNLINKED; + if (idx == PF_SK_STACK) + /* + * Remove the wire key from + * the hash. Other threads + * can't be referencing it + * because we still hold the + * hash lock. + */ + pf_state_key_detach(s, + PF_SK_WIRE); PF_HASHROW_UNLOCK(ih); KEYS_UNLOCK(); - if (idx == PF_SK_WIRE) { + if (idx == PF_SK_WIRE) + /* + * We've not inserted either key. + * Free both. + */ uma_zfree(V_pf_state_key_z, skw); - if (skw != sks) - uma_zfree(V_pf_state_key_z, sks); - } else { - pf_detach_state(s); - } + if (skw != sks) + uma_zfree( + V_pf_state_key_z, + sks); return (EEXIST); /* collision! */ } }