pf: fix a race against kif destruction in pf_test{,6}
ifp kif was dereferenced prior to taking the lock and could have been nullified later. Reviewed by: kp Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision:
This commit is contained in:
parent
3cb9f1976c
commit
6c92016aa6
|
@ -6978,18 +6978,25 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *
|
|||
if (!V_pf_status.running)
|
||||
return (PF_PASS);
|
||||
|
||||
PF_RULES_RLOCK();
|
||||
|
||||
kif = (struct pfi_kkif *)ifp->if_pf_kif;
|
||||
|
||||
if (kif == NULL) {
|
||||
if (__predict_false(kif == NULL)) {
|
||||
DPFPRINTF(PF_DEBUG_URGENT,
|
||||
("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname));
|
||||
PF_RULES_RUNLOCK();
|
||||
return (PF_DROP);
|
||||
}
|
||||
if (kif->pfik_flags & PFI_IFLAG_SKIP)
|
||||
if (kif->pfik_flags & PFI_IFLAG_SKIP) {
|
||||
PF_RULES_RUNLOCK();
|
||||
return (PF_PASS);
|
||||
}
|
||||
|
||||
if (m->m_flags & M_SKIP_FIREWALL)
|
||||
if (m->m_flags & M_SKIP_FIREWALL) {
|
||||
PF_RULES_RUNLOCK();
|
||||
return (PF_PASS);
|
||||
}
|
||||
|
||||
memset(&pd, 0, sizeof(pd));
|
||||
pd.pf_mtag = pf_find_mtag(m);
|
||||
|
@ -7000,10 +7007,12 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *
|
|||
ifp = ifnet_byindexgen(pd.pf_mtag->if_index,
|
||||
pd.pf_mtag->if_idxgen);
|
||||
if (ifp == NULL || ifp->if_flags & IFF_DYING) {
|
||||
PF_RULES_RUNLOCK();
|
||||
m_freem(*m0);
|
||||
*m0 = NULL;
|
||||
return (PF_PASS);
|
||||
}
|
||||
PF_RULES_RUNLOCK();
|
||||
(ifp->if_output)(ifp, m, sintosa(&pd.pf_mtag->dst), NULL);
|
||||
*m0 = NULL;
|
||||
return (PF_PASS);
|
||||
|
@ -7023,12 +7032,11 @@ pf_test(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb *
|
|||
/* But only once. We may see the packet multiple times (e.g.
|
||||
* PFIL_IN/PFIL_OUT). */
|
||||
pd.pf_mtag->flags &= ~PF_TAG_DUMMYNET;
|
||||
PF_RULES_RUNLOCK();
|
||||
|
||||
return (PF_PASS);
|
||||
}
|
||||
|
||||
PF_RULES_RLOCK();
|
||||
|
||||
if (__predict_false(ip_divert_ptr != NULL) &&
|
||||
((ipfwtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL)) != NULL)) {
|
||||
struct ipfw_rule_ref *rr = (struct ipfw_rule_ref *)(ipfwtag+1);
|
||||
|
@ -7468,17 +7476,24 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
|
|||
if (!V_pf_status.running)
|
||||
return (PF_PASS);
|
||||
|
||||
PF_RULES_RLOCK();
|
||||
|
||||
kif = (struct pfi_kkif *)ifp->if_pf_kif;
|
||||
if (kif == NULL) {
|
||||
if (__predict_false(kif == NULL)) {
|
||||
DPFPRINTF(PF_DEBUG_URGENT,
|
||||
("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname));
|
||||
PF_RULES_RUNLOCK();
|
||||
return (PF_DROP);
|
||||
}
|
||||
if (kif->pfik_flags & PFI_IFLAG_SKIP)
|
||||
if (kif->pfik_flags & PFI_IFLAG_SKIP) {
|
||||
PF_RULES_RUNLOCK();
|
||||
return (PF_PASS);
|
||||
}
|
||||
|
||||
if (m->m_flags & M_SKIP_FIREWALL)
|
||||
if (m->m_flags & M_SKIP_FIREWALL) {
|
||||
PF_RULES_RUNLOCK();
|
||||
return (PF_PASS);
|
||||
}
|
||||
|
||||
memset(&pd, 0, sizeof(pd));
|
||||
pd.pf_mtag = pf_find_mtag(m);
|
||||
|
@ -7489,10 +7504,12 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
|
|||
ifp = ifnet_byindexgen(pd.pf_mtag->if_index,
|
||||
pd.pf_mtag->if_idxgen);
|
||||
if (ifp == NULL || ifp->if_flags & IFF_DYING) {
|
||||
PF_RULES_RUNLOCK();
|
||||
m_freem(*m0);
|
||||
*m0 = NULL;
|
||||
return (PF_PASS);
|
||||
}
|
||||
PF_RULES_RUNLOCK();
|
||||
nd6_output_ifp(ifp, ifp, m,
|
||||
(struct sockaddr_in6 *)&pd.pf_mtag->dst, NULL);
|
||||
*m0 = NULL;
|
||||
|
@ -7510,11 +7527,10 @@ pf_test6(int dir, int pflags, struct ifnet *ifp, struct mbuf **m0, struct inpcb
|
|||
/* Dummynet re-injects packets after they've
|
||||
* completed their delay. We've already
|
||||
* processed them, so pass unconditionally. */
|
||||
PF_RULES_RUNLOCK();
|
||||
return (PF_PASS);
|
||||
}
|
||||
|
||||
PF_RULES_RLOCK();
|
||||
|
||||
/* We do IP header normalization and packet reassembly here */
|
||||
if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) {
|
||||
action = PF_DROP;
|
||||
|
|
Loading…
Reference in New Issue