mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-25 10:01:02 +01:00
pf: Access r->rpool.cur->kif under mutex protection
pf_route() sends traffic to a specified next hop over a specific interface. The next hop is obtained in pf_map_addr() but the interface is obtained directly via r->rpool.cur->kif` outside of the lock held in pf_map_addr() in multiple places around pf. The chosen interface is not stored in source node. Move the interface selection into pf_map_addr(), have the function return it together with the chosen IP address and ensure its stored in struct pf_ksrc_node, store it in the source node and use the stored value when needed. Sponsored by: InnoGames GmbH MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D41570
This commit is contained in:
parent
d9fee1d021
commit
d10de21f2f
@ -873,7 +873,7 @@ struct pf_ksrc_node {
|
||||
struct pf_addr raddr;
|
||||
struct pf_krule_slist match_rules;
|
||||
union pf_krule_ptr rule;
|
||||
struct pfi_kkif *kif;
|
||||
struct pfi_kkif *rkif;
|
||||
counter_u64_t bytes[2];
|
||||
counter_u64_t packets[2];
|
||||
u_int32_t states;
|
||||
@ -2474,7 +2474,8 @@ int pf_step_out_of_keth_anchor(struct pf_keth_anchor_stackframe *,
|
||||
|
||||
u_short pf_map_addr(u_int8_t, struct pf_krule *,
|
||||
struct pf_addr *, struct pf_addr *,
|
||||
struct pf_addr *, struct pf_ksrc_node **);
|
||||
struct pfi_kkif **nkif, struct pf_addr *,
|
||||
struct pf_ksrc_node **);
|
||||
struct pf_krule *pf_get_translation(struct pf_pdesc *, struct mbuf *,
|
||||
int, struct pfi_kkif *, struct pf_ksrc_node **,
|
||||
struct pf_state_key **, struct pf_state_key **,
|
||||
|
@ -4880,15 +4880,14 @@ pf_create_state(struct pf_krule *r, struct pf_krule *nr, struct pf_krule *a,
|
||||
|
||||
if (r->rt) {
|
||||
/* pf_map_addr increases the reason counters */
|
||||
if ((reason = pf_map_addr(pd->af, r, pd->src, &s->rt_addr, NULL,
|
||||
&sn)) != 0) {
|
||||
if ((reason = pf_map_addr(pd->af, r, pd->src, &s->rt_addr,
|
||||
&s->rt_kif, NULL, &sn)) != 0) {
|
||||
pf_src_tree_remove_state(s);
|
||||
s->timeout = PFTM_UNLINKED;
|
||||
STATE_DEC_COUNTERS(s);
|
||||
pf_free_state(s);
|
||||
goto csfailed;
|
||||
}
|
||||
s->rt_kif = r->rpool.cur->kif;
|
||||
s->rt = r->rt;
|
||||
}
|
||||
|
||||
@ -6700,6 +6699,7 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp,
|
||||
struct mbuf *m0, *m1, *md;
|
||||
struct sockaddr_in dst;
|
||||
struct ip *ip;
|
||||
struct pfi_kkif *nkif = NULL;
|
||||
struct ifnet *ifp = NULL;
|
||||
struct pf_addr naddr;
|
||||
struct pf_ksrc_node *sn = NULL;
|
||||
@ -6784,21 +6784,22 @@ pf_route(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp,
|
||||
goto bad_locked;
|
||||
}
|
||||
pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src,
|
||||
&naddr, NULL, &sn);
|
||||
&naddr, &nkif, NULL, &sn);
|
||||
if (!PF_AZERO(&naddr, AF_INET))
|
||||
dst.sin_addr.s_addr = naddr.v4.s_addr;
|
||||
ifp = r->rpool.cur->kif ?
|
||||
r->rpool.cur->kif->pfik_ifp : NULL;
|
||||
ifp = nkif ? nkif->pfik_ifp : NULL;
|
||||
} else {
|
||||
if (!PF_AZERO(&s->rt_addr, AF_INET))
|
||||
dst.sin_addr.s_addr =
|
||||
s->rt_addr.v4.s_addr;
|
||||
ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
|
||||
/* If pfsync'd */
|
||||
if (ifp == NULL)
|
||||
ifp = r->rpool.cur->kif ?
|
||||
r->rpool.cur->kif->pfik_ifp : NULL;
|
||||
PF_STATE_UNLOCK(s);
|
||||
}
|
||||
/* If pfsync'd */
|
||||
if (ifp == NULL)
|
||||
ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
|
||||
|
||||
if (ifp == NULL)
|
||||
goto bad;
|
||||
|
||||
@ -6913,6 +6914,7 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp,
|
||||
struct mbuf *m0, *md;
|
||||
struct sockaddr_in6 dst;
|
||||
struct ip6_hdr *ip6;
|
||||
struct pfi_kkif *nkif = NULL;
|
||||
struct ifnet *ifp = NULL;
|
||||
struct pf_addr naddr;
|
||||
struct pf_ksrc_node *sn = NULL;
|
||||
@ -6995,24 +6997,25 @@ pf_route6(struct mbuf **m, struct pf_krule *r, struct ifnet *oifp,
|
||||
goto bad_locked;
|
||||
}
|
||||
pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src,
|
||||
&naddr, NULL, &sn);
|
||||
&naddr, &nkif, NULL, &sn);
|
||||
if (!PF_AZERO(&naddr, AF_INET6))
|
||||
PF_ACPY((struct pf_addr *)&dst.sin6_addr,
|
||||
&naddr, AF_INET6);
|
||||
ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
|
||||
ifp = nkif ? nkif->pfik_ifp : NULL;
|
||||
} else {
|
||||
if (!PF_AZERO(&s->rt_addr, AF_INET6))
|
||||
PF_ACPY((struct pf_addr *)&dst.sin6_addr,
|
||||
&s->rt_addr, AF_INET6);
|
||||
ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL;
|
||||
/* If pfsync'd */
|
||||
if (ifp == NULL)
|
||||
ifp = r->rpool.cur->kif ?
|
||||
r->rpool.cur->kif->pfik_ifp : NULL;
|
||||
}
|
||||
|
||||
if (s)
|
||||
PF_STATE_UNLOCK(s);
|
||||
|
||||
/* If pfsync'd */
|
||||
if (ifp == NULL)
|
||||
ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL;
|
||||
if (ifp == NULL)
|
||||
goto bad;
|
||||
|
||||
|
@ -222,7 +222,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r,
|
||||
struct pf_addr init_addr;
|
||||
|
||||
bzero(&init_addr, sizeof(init_addr));
|
||||
if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
|
||||
if (pf_map_addr(af, r, saddr, naddr, NULL, &init_addr, sn))
|
||||
return (1);
|
||||
|
||||
bzero(&key, sizeof(key));
|
||||
@ -299,7 +299,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r,
|
||||
* pick a different source address since we're out
|
||||
* of free port choices for the current one.
|
||||
*/
|
||||
if (pf_map_addr(af, r, saddr, naddr, &init_addr, sn))
|
||||
if (pf_map_addr(af, r, saddr, naddr, NULL, &init_addr, sn))
|
||||
return (1);
|
||||
break;
|
||||
case PF_POOL_NONE:
|
||||
@ -350,7 +350,8 @@ pf_get_mape_sport(sa_family_t af, u_int8_t proto, struct pf_krule *r,
|
||||
|
||||
u_short
|
||||
pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
|
||||
struct pf_addr *naddr, struct pf_addr *init_addr, struct pf_ksrc_node **sn)
|
||||
struct pf_addr *naddr, struct pfi_kkif **nkif, struct pf_addr *init_addr,
|
||||
struct pf_ksrc_node **sn)
|
||||
{
|
||||
u_short reason = 0;
|
||||
struct pf_kpool *rpool = &r->rpool;
|
||||
@ -377,11 +378,15 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
|
||||
}
|
||||
|
||||
PF_ACPY(naddr, &(*sn)->raddr, af);
|
||||
if (nkif)
|
||||
*nkif = (*sn)->rkif;
|
||||
if (V_pf_status.debug >= PF_DEBUG_NOISY) {
|
||||
printf("pf_map_addr: src tracking maps ");
|
||||
pf_print_host(saddr, 0, af);
|
||||
printf(" to ");
|
||||
pf_print_host(naddr, 0, af);
|
||||
if (nkif)
|
||||
printf("@%s", (*nkif)->pfik_name);
|
||||
printf("\n");
|
||||
}
|
||||
goto done;
|
||||
@ -539,13 +544,22 @@ pf_map_addr(sa_family_t af, struct pf_krule *r, struct pf_addr *saddr,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*sn != NULL)
|
||||
|
||||
if (nkif)
|
||||
*nkif = rpool->cur->kif;
|
||||
|
||||
if (*sn != NULL) {
|
||||
PF_ACPY(&(*sn)->raddr, naddr, af);
|
||||
if (nkif)
|
||||
(*sn)->rkif = *nkif;
|
||||
}
|
||||
|
||||
if (V_pf_status.debug >= PF_DEBUG_NOISY &&
|
||||
(rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
|
||||
printf("pf_map_addr: selected address ");
|
||||
pf_print_host(naddr, 0, af);
|
||||
if (nkif)
|
||||
printf("@%s", (*nkif)->pfik_name);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
@ -711,7 +725,7 @@ pf_get_translation(struct pf_pdesc *pd, struct mbuf *m, int off,
|
||||
}
|
||||
break;
|
||||
case PF_RDR: {
|
||||
if (pf_map_addr(pd->af, r, saddr, naddr, NULL, sn))
|
||||
if (pf_map_addr(pd->af, r, saddr, naddr, NULL, NULL, sn))
|
||||
goto notrans;
|
||||
if ((r->rpool.opts & PF_POOL_TYPEMASK) == PF_POOL_BITMASK)
|
||||
PF_POOLMASK(naddr, naddr, &r->rpool.cur->addr.v.a.mask,
|
||||
|
Loading…
Reference in New Issue
Block a user