git: b70fadca623f - main - pf: fix dealing with 0 limits
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 08 May 2025 13:10:44 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=b70fadca623f1ce62c34c67270feae6cf48ca4ba
commit b70fadca623f1ce62c34c67270feae6cf48ca4ba
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-05-07 08:43:14 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-05-08 13:10:25 +0000
pf: fix dealing with 0 limits
uma doesn't like setting a limit on a zone which previously had none.
At startup pf applies the default limit to all zones, so we can assume a limit
was always set. We cope with the uma limitation by translating a limit of '0'
(i.e. unlimited) to INT_MAX. This is high enough that we'll never realistically
hit this limit, but it keeps uma happy.
Add a test case to provoke this, and while we're here also fix syncookie
handling of a 0 state limit.
See also: d53927b0bae45
Reported-by: syzbot+02b784f183f79d4c07e4@syzkaller.appspotmail.com
Sponsored by: Rubicon Communications, LLC ("Netgate")
---
lib/libpfctl/libpfctl.c | 6 +++++
sys/netpfil/pf/pf_ioctl.c | 3 ++-
tests/sys/netpfil/pf/limits.sh | 53 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c
index 271fb33babfe..a4afa26f0afe 100644
--- a/lib/libpfctl/libpfctl.c
+++ b/lib/libpfctl/libpfctl.c
@@ -2271,6 +2271,9 @@ pfctl_set_syncookies(int dev, const struct pfctl_syncookies *s)
if (ret != 0)
return (ret);
+ if (state_limit == 0)
+ state_limit = INT_MAX;
+
lim = state_limit;
hi = lim * s->highwater / 100;
lo = lim * s->lowwater / 100;
@@ -2311,6 +2314,9 @@ pfctl_get_syncookies(int dev, struct pfctl_syncookies *s)
if (ret != 0)
return (ret);
+ if (state_limit == 0)
+ state_limit = INT_MAX;
+
bzero(s, sizeof(*s));
nvl = nvlist_create(0);
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 5c3aec906b79..bd3c2b93c954 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -2537,7 +2537,8 @@ pf_ioctl_set_limit(int index, unsigned int limit, unsigned int *old_limit)
PF_RULES_WUNLOCK();
return (EINVAL);
}
- uma_zone_set_max(V_pf_limits[index].zone, limit);
+ uma_zone_set_max(V_pf_limits[index].zone,
+ limit == 0 ? INT_MAX : limit);
if (old_limit != NULL)
*old_limit = V_pf_limits[index].limit;
V_pf_limits[index].limit = limit;
diff --git a/tests/sys/netpfil/pf/limits.sh b/tests/sys/netpfil/pf/limits.sh
index 474684bef660..69f0b6af2ccf 100644
--- a/tests/sys/netpfil/pf/limits.sh
+++ b/tests/sys/netpfil/pf/limits.sh
@@ -60,7 +60,60 @@ basic_cleanup()
pft_cleanup
}
+atf_test_case "zero" "cleanup"
+zero_head()
+{
+ atf_set descr 'Test changing a limit from zero on an in-use zone'
+ atf_set require.user root
+}
+
+zero_body()
+{
+ pft_init
+
+ epair=$(vnet_mkepair)
+ ifconfig ${epair}b 192.0.2.2/24 up
+
+ vnet_mkjail alcatraz ${epair}a
+ jexec alcatraz ifconfig ${epair}a 192.0.2.1/24 up
+
+ atf_check -s exit:0 -o ignore \
+ ping -c 3 192.0.2.1
+
+ jexec alcatraz pfctl -e
+ # Set no limit
+ pft_set_rules noflush alcatraz \
+ "set limit states 0" \
+ "pass"
+
+ # Check that we really report no limit
+ atf_check -s exit:0 -o 'match:states hard limit 0' \
+ jexec alcatraz pfctl -sa
+
+ # Create a state
+ atf_check -s exit:0 -o ignore \
+ ping -c 3 192.0.2.1
+
+ # Limit states
+ pft_set_rules noflush alcatraz \
+ "set limit states 1000" \
+ "pass"
+
+ # And create a new state
+ atf_check -s exit:0 -o ignore \
+ ping -c 3 192.0.2.1
+
+ atf_check -s exit:0 -o 'match:states hard limit 1000' \
+ jexec alcatraz pfctl -sa
+}
+
+zero_cleanup()
+{
+ pft_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case "basic"
+ atf_add_test_case "zero"
}