Re: pf state key link inp

2017-12-23 Thread Alexandr Nedvedicky
Hello,

> ok?

sure, no objections/comments

OK sashan@



pf state key link inp

2017-12-22 Thread Alexander Bluhm
Hi,

There is a corner case where linking the inp to the state key does
not work in pf.  The function pf_inp_link() takes the state key
from the mbuf and not the one we have just found.  Introduce a new
function pf_state_key_link_inpcb() that does exactly that together
with some sanity checks.

I have regress tests that can trigger cases where this is relevant.

ok?

bluhm

Index: net/pf.c
===
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pf.c,v
retrieving revision 1.1050
diff -u -p -r1.1050 pf.c
--- net/pf.c4 Dec 2017 15:13:12 -   1.1050
+++ net/pf.c22 Dec 2017 14:21:09 -
@@ -249,6 +249,8 @@ void pf_state_key_link(struct 
pf_stat
struct pf_state_key *);
 voidpf_inpcb_unlink_state_key(struct inpcb *);
 voidpf_state_key_unlink_reverse(struct pf_state_key *);
+voidpf_state_key_link_inpcb(struct pf_state_key *,
+   struct inpcb *);
 
 #if NPFLOG > 0
 voidpf_log_matches(struct pf_pdesc *, struct pf_rule *,
@@ -1085,8 +1087,9 @@ pf_find_state(struct pfi_kif *kif, struc
if (dir == PF_OUT && pkt_sk &&
pf_compare_state_keys(pkt_sk, sk, kif, dir) == 0)
pf_state_key_link(sk, pkt_sk);
-   else if (dir == PF_OUT)
-   pf_inp_link(m, m->m_pkthdr.pf.inp);
+   else if (dir == PF_OUT && m->m_pkthdr.pf.inp &&
+   !m->m_pkthdr.pf.inp->inp_pf_sk && !sk->inp)
+   pf_state_key_link_inpcb(sk, m->m_pkthdr.pf.inp);
}
 
/* remove firewall data from outbound packet */
@@ -7259,6 +7262,15 @@ void
 pf_pkt_state_key_ref(struct mbuf *m)
 {
pf_state_key_ref(m->m_pkthdr.pf.statekey);
+}
+
+void
+pf_state_key_link_inpcb(struct pf_state_key *sk, struct inpcb *inp)
+{
+   KASSERT(sk->inp == NULL);
+   sk->inp = inp;
+   KASSERT(inp->inp_pf_sk == NULL);
+   inp->inp_pf_sk = pf_state_key_ref(sk);
 }
 
 void