Hello Olivier,

I've seen your report here

    https://marc.info/?l=openbsd-bugs&m=161968896108810

your crash is slightly different. Sebastien is lucky enough
to trip crash in assert, when state key is dereferenced.

in your case we've missed the assert and are dying on uvm fault.

you both seem to be using rdr-to. your pf seems to use also divert-to rule.
I suspect something is going wrong when we deal with traffic, which matches
rdr-to rule.


would you be so kind and try diff below on your AP box. The diff removes
my change to pf_state_key_link_reverse(). Which is a primary suspect
at the moment.

I'm not able to trigger the panic on my notebook, nor on my
home router.

thank you for your help
regards
sashan

--------8<---------------8<---------------8<------------------8<--------
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 23eebf4a274..12d05976f0b 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -7368,19 +7368,11 @@ pf_inp_unlink(struct inpcb *inp)
 void
 pf_state_key_link_reverse(struct pf_state_key *sk, struct pf_state_key *skrev)
 {
-       struct pf_state_key *old_reverse;
-
-       old_reverse = atomic_cas_ptr(&sk->reverse, NULL, skrev);
-       if (old_reverse != NULL)
-               KASSERT(old_reverse == skrev);
-       else
-               pf_state_key_ref(skrev);
-
-       old_reverse = atomic_cas_ptr(&skrev->reverse, NULL, sk);
-       if (old_reverse != NULL)
-               KASSERT(old_reverse == sk);
-       else
-               pf_state_key_ref(sk);
+       /* Note that sk and skrev may be equal, then we refcount twice. */
+       KASSERT(sk->reverse == NULL);
+       KASSERT(skrev->reverse == NULL);
+       sk->reverse = pf_state_key_ref(skrev);
+       skrev->reverse = pf_state_key_ref(sk);
 }
 
 #if NPFLOG > 0

Reply via email to