aboutsummaryrefslogtreecommitdiff
path: root/lib/libpfctl
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2022-09-08 16:32:02 +0000
committerKristof Provost <kp@FreeBSD.org>2022-09-12 07:32:02 +0000
commit6049ee60e0160bc6d564b733f02015259473f166 (patch)
tree0eee502b05e77adc343c0ddf36fe19d6adaffaaf /lib/libpfctl
parent7d0e83c60bedf601e61d80187cdfa785fa4b1963 (diff)
downloadsrc-6049ee60e0160bc6d564b733f02015259473f166.tar.gz
src-6049ee60e0160bc6d564b733f02015259473f166.zip
libpfctl: improve syncookie watermark calculation
Ensure that we always pass sane limits for the high and low watermark values. This is especially important if users do something silly, like set the state limit to 1. In that case we wound up calculating 0/0 as a limit, which gets rejected by the kernel. While here also shift the calculation to use uint64_t, so we don't end up with overflows (and subsequently higher low than high values) with very large state limits. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D36497
Diffstat (limited to 'lib/libpfctl')
-rw-r--r--lib/libpfctl/libpfctl.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index 3adfb7b94af3..5b93fd1043d6 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -1335,17 +1335,25 @@ pfctl_set_syncookies(int dev, const struct pfctl_syncookies *s)
nvlist_t *nvl;
int ret;
uint state_limit;
+ uint64_t lim, hi, lo;
ret = pfctl_get_limit(dev, PF_LIMIT_STATES, &state_limit);
if (ret != 0)
return (ret);
+ lim = state_limit;
+ hi = lim * s->highwater / 100;
+ lo = lim * s->lowwater / 100;
+
+ if (lo == hi)
+ hi++;
+
nvl = nvlist_create(0);
nvlist_add_bool(nvl, "enabled", s->mode != PFCTL_SYNCOOKIES_NEVER);
nvlist_add_bool(nvl, "adaptive", s->mode == PFCTL_SYNCOOKIES_ADAPTIVE);
- nvlist_add_number(nvl, "highwater", state_limit * s->highwater / 100);
- nvlist_add_number(nvl, "lowwater", state_limit * s->lowwater / 100);
+ nvlist_add_number(nvl, "highwater", hi);
+ nvlist_add_number(nvl, "lowwater", lo);
nv.data = nvlist_pack(nvl, &nv.len);
nv.size = nv.len;