Project

General

Profile

Regression #12660 ยป 0001-pf-protect-the-rpool-from-races.patch

Kristof Provost, 01/10/2022 01:20 PM

View differences:

sys/net/pfvar.h
TAILQ_HEAD(pf_kpalist, pf_kpooladdr);
struct pf_kpool {
struct mtx mtx;
struct pf_kpalist list;
struct pf_kpooladdr *cur;
struct pf_poolhashkey key;
sys/netpfil/pf/pf_ioctl.c
counter_u64_free(rule->states_cur);
counter_u64_free(rule->states_tot);
counter_u64_free(rule->src_nodes);
mtx_destroy(&rule->rpool.mtx);
free(rule, M_PFRULE);
}
......
TAILQ_INSERT_TAIL(ruleset->rules[rs_num].inactive.ptr,
rule, entries);
ruleset->rules[rs_num].inactive.rcount++;
mtx_init(&rule->rpool.mtx, "pf_krule_pool", NULL, MTX_DEF);
PF_RULES_WUNLOCK();
return (0);
sys/netpfil/pf/pf_lb.c
return (0);
}
mtx_lock(&rpool->mtx);
/* Find the route using chosen algorithm. Store the found route
in src_node if it was given or found. */
if (rpool->cur->addr.type == PF_ADDR_NOROUTE)
if (rpool->cur->addr.type == PF_ADDR_NOROUTE) {
mtx_unlock(&rpool->mtx);
return (1);
}
if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
switch (af) {
#ifdef INET
case AF_INET:
if (rpool->cur->addr.p.dyn->pfid_acnt4 < 1 &&
(rpool->opts & PF_POOL_TYPEMASK) !=
PF_POOL_ROUNDROBIN)
PF_POOL_ROUNDROBIN) {
mtx_unlock(&rpool->mtx);
return (1);
raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
}
raddr = &rpool->cur->addr.p.dyn->pfid_addr4;
rmask = &rpool->cur->addr.p.dyn->pfid_mask4;
break;
#endif /* INET */
#ifdef INET6
case AF_INET6:
if (rpool->cur->addr.p.dyn->pfid_acnt6 < 1 &&
(rpool->opts & PF_POOL_TYPEMASK) !=
PF_POOL_ROUNDROBIN)
PF_POOL_ROUNDROBIN) {
mtx_unlock(&rpool->mtx);
return (1);
}
raddr = &rpool->cur->addr.p.dyn->pfid_addr6;
rmask = &rpool->cur->addr.p.dyn->pfid_mask6;
break;
#endif /* INET6 */
}
} else if (rpool->cur->addr.type == PF_ADDR_TABLE) {
if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN)
if ((rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_ROUNDROBIN) {
mtx_unlock(&rpool->mtx);
return (1); /* unsupported */
}
} else {
raddr = &rpool->cur->addr.v.a.addr;
rmask = &rpool->cur->addr.v.a.mask;
......
/* table contains no address of type 'af' */
if (rpool->cur != acur)
goto try_next;
mtx_unlock(&rpool->mtx);
return (1);
}
} else if (rpool->cur->addr.type == PF_ADDR_DYNIFTL) {
......
/* table contains no address of type 'af' */
if (rpool->cur != acur)
goto try_next;
mtx_unlock(&rpool->mtx);
return (1);
}
} else {
......
if (*sn != NULL)
PF_ACPY(&(*sn)->raddr, naddr, af);
mtx_unlock(&rpool->mtx);
if (V_pf_status.debug >= PF_DEBUG_MISC &&
(rpool->opts & PF_POOL_TYPEMASK) != PF_POOL_NONE) {
printf("pf_map_addr: selected address ");
    (1-1/1)