diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -169,7 +169,7 @@ } static inline u_int64_t -pf_counter_u64_fetch(struct pf_counter_u64 *pfcu64) +pf_counter_u64_fetch(const struct pf_counter_u64 *pfcu64) { struct pf_counter_u64_pcpu *pcpu; u_int64_t sum; @@ -263,7 +263,7 @@ } static inline u_int64_t -pf_counter_u64_fetch(struct pf_counter_u64 *pfcu64) +pf_counter_u64_fetch(const struct pf_counter_u64 *pfcu64) { return (counter_u64_fetch(pfcu64->counter)); @@ -2155,6 +2155,7 @@ struct pf_kruleset *pf_find_or_create_kruleset(const char *); void pf_rs_initialize(void); +struct pf_krule *pf_krule_alloc(void); void pf_krule_free(struct pf_krule *); #endif diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -1512,6 +1512,16 @@ } #endif /* ALTQ */ +struct pf_krule * +pf_krule_alloc(void) +{ + struct pf_krule *rule; + + rule = malloc(sizeof(struct pf_krule), M_PFRULE, M_WAITOK | M_ZERO); + mtx_init(&rule->rpool.mtx, "pf_krule_pool", NULL, MTX_DEF); + return (rule); +} + void pf_krule_free(struct pf_krule *rule) { @@ -1584,14 +1594,12 @@ pool->opts = kpool->opts; } -static int +static void pf_pool_to_kpool(const struct pf_pool *pool, struct pf_kpool *kpool) { _Static_assert(sizeof(pool->key) == sizeof(kpool->key), ""); _Static_assert(sizeof(pool->counter) == sizeof(kpool->counter), ""); - bzero(kpool, sizeof(*kpool)); - bcopy(&pool->key, &kpool->key, sizeof(kpool->key)); bcopy(&pool->counter, &kpool->counter, sizeof(kpool->counter)); @@ -1599,12 +1607,10 @@ kpool->proxy_port[0] = pool->proxy_port[0]; kpool->proxy_port[1] = pool->proxy_port[1]; kpool->opts = pool->opts; - - return (0); } static void -pf_krule_to_rule(struct pf_krule *krule, struct pf_rule *rule) +pf_krule_to_rule(const struct pf_krule *krule, struct pf_rule *rule) { bzero(rule, sizeof(*rule)); @@ -1727,8 +1733,6 @@ if (ret != 0) return (ret); - bzero(krule, sizeof(*krule)); - bcopy(&rule->src, &krule->src, sizeof(rule->src)); bcopy(&rule->dst, &krule->dst, sizeof(rule->dst)); @@ -1757,9 +1761,7 @@ if (ret != 0) return (ret); - ret = pf_pool_to_kpool(&rule->rpool, &krule->rpool); - if (ret != 0) - return (ret); + pf_pool_to_kpool(&rule->rpool, &krule->rpool); /* Don't allow userspace to set evaulations, packets or bytes. */ /* kif, anchor, overload_tbl are not copied over. */ @@ -1862,8 +1864,6 @@ int rs_num; int error = 0; - mtx_init(&rule->rpool.mtx, "pf_krule_pool", NULL, MTX_DEF); - if ((rule->return_icmp >> 8) > ICMP_MAXTYPE) { error = EINVAL; goto errout_unlocked; @@ -2357,7 +2357,7 @@ if (! nvlist_exists_nvlist(nvl, "rule")) ERROUT(EINVAL); - rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK | M_ZERO); + rule = pf_krule_alloc(); error = pf_nvrule_to_krule(nvlist_get_nvlist(nvl, "rule"), rule); if (error) @@ -2390,10 +2390,10 @@ struct pfioc_rule *pr = (struct pfioc_rule *)addr; struct pf_krule *rule; - rule = malloc(sizeof(*rule), M_PFRULE, M_WAITOK | M_ZERO); + rule = pf_krule_alloc(); error = pf_rule_to_krule(&pr->rule, rule); if (error != 0) { - free(rule, M_PFRULE); + pf_krule_free(rule); break; } @@ -2647,7 +2647,7 @@ } if (pcr->action != PF_CHANGE_REMOVE) { - newrule = malloc(sizeof(*newrule), M_PFRULE, M_WAITOK | M_ZERO); + newrule = pf_krule_alloc(); error = pf_rule_to_krule(&pcr->rule, newrule); if (error != 0) { free(newrule, M_PFRULE); diff --git a/sys/netpfil/pf/pf_nv.c b/sys/netpfil/pf/pf_nv.c --- a/sys/netpfil/pf/pf_nv.c +++ b/sys/netpfil/pf/pf_nv.c @@ -223,8 +223,6 @@ { int error = 0; - bzero(kpool, sizeof(*kpool)); - PFNV_CHK(pf_nvbinary(nvl, "key", &kpool->key, sizeof(kpool->key))); if (nvlist_exists_nvlist(nvl, "counter")) { diff --git a/tests/sys/netpfil/pf/ioctl/validation.c b/tests/sys/netpfil/pf/ioctl/validation.c --- a/tests/sys/netpfil/pf/ioctl/validation.c +++ b/tests/sys/netpfil/pf/ioctl/validation.c @@ -869,6 +869,32 @@ COMMON_CLEANUP(); } +ATF_TC_WITH_CLEANUP(rpool_mtx2); +ATF_TC_HEAD(rpool_mtx2, tc) +{ + atf_tc_set_md_var(tc, "require.user", "root"); +} + +ATF_TC_BODY(rpool_mtx2, tc) +{ + struct pfioc_rule rule; + + COMMON_HEAD(); + + memset(&rule, 0, sizeof(rule)); + + rule.pool_ticket = 1000000; + rule.action = PF_CHANGE_ADD_HEAD; + rule.rule.af = AF_INET; + + ioctl(dev, DIOCCHANGERULE, &rule); +} + +ATF_TC_CLEANUP(rpool_mtx2, tc) +{ + COMMON_CLEANUP(); +} + ATF_TP_ADD_TCS(tp) { @@ -893,6 +919,7 @@ ATF_TP_ADD_TC(tp, getsrcnodes); ATF_TP_ADD_TC(tp, tag); ATF_TP_ADD_TC(tp, rpool_mtx); + ATF_TP_ADD_TC(tp, rpool_mtx2); return (atf_no_error()); }