aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2021-03-11 10:37:05 +0000
committerKristof Provost <kp@FreeBSD.org>2021-03-23 12:23:55 +0000
commit7d588615865023c5d159f47c98279d05b102ea27 (patch)
tree795043bc040603b478157294023d417ad0ebb236
parent395e612b7bb1874811f5bcd6136296dd7a76da1b (diff)
downloadsrc-7d588615865023c5d159f47c98279d05b102ea27.tar.gz
src-7d588615865023c5d159f47c98279d05b102ea27.zip
pf: pool/kpool conversion code
stuct pf_pool and struct pf_kpool are different. We should not simply bcopy() them. Happily it turns out that their differences were all pointers, and the userspace provided pointers were overwritten by the kernel, so this did actually work correctly, but we should fix it anyway. Reviewed by: glebius MFC after: 1 week Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D29216 (cherry picked from commit 15b82e00a1640d1b9a1d720c95f65e580be30187)
-rw-r--r--sys/netpfil/pf/pf_ioctl.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index c930a67ecf80..ce889c8d797e 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -1466,6 +1466,39 @@ pf_pooladdr_to_kpooladdr(const struct pf_pooladdr *pool,
}
static void
+pf_kpool_to_pool(const struct pf_kpool *kpool, struct pf_pool *pool)
+{
+ bzero(pool, sizeof(*pool));
+
+ bcopy(&kpool->key, &pool->key, sizeof(pool->key));
+ bcopy(&kpool->counter, &pool->counter, sizeof(pool->counter));
+
+ pool->tblidx = kpool->tblidx;
+ pool->proxy_port[0] = kpool->proxy_port[0];
+ pool->proxy_port[1] = kpool->proxy_port[1];
+ pool->opts = kpool->opts;
+}
+
+static int
+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));
+
+ kpool->tblidx = pool->tblidx;
+ 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(const struct pf_krule *krule, struct pf_rule *rule)
{
@@ -1491,7 +1524,7 @@ pf_krule_to_rule(const struct pf_krule *krule, struct pf_rule *rule)
strlcpy(rule->overload_tblname, krule->overload_tblname,
sizeof(rule->overload_tblname));
- bcopy(&krule->rpool, &rule->rpool, sizeof(krule->rpool));
+ pf_kpool_to_pool(&krule->rpool, &rule->rpool);
rule->evaluations = counter_u64_fetch(krule->evaluations);
for (int i = 0; i < 2; i++) {
@@ -1628,7 +1661,9 @@ pf_rule_to_krule(const struct pf_rule *rule, struct pf_krule *krule)
strlcpy(krule->overload_tblname, rule->overload_tblname,
sizeof(rule->overload_tblname));
- bcopy(&rule->rpool, &krule->rpool, sizeof(krule->rpool));
+ ret = pf_pool_to_kpool(&rule->rpool, &krule->rpool);
+ if (ret != 0)
+ return (ret);
/* Don't allow userspace to set evaulations, packets or bytes. */
/* kif, anchor, overload_tbl are not copied over. */