git: 63a5fe834354 - main - pflow: limit to no more than 128 flow exporters

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Mon, 22 Jan 2024 18:20:06 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=63a5fe834354dc9249388e0805e6ea68dc9f02c7

commit 63a5fe834354dc9249388e0805e6ea68dc9f02c7
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2024-01-22 16:35:54 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2024-01-22 17:02:10 +0000

    pflow: limit to no more than 128 flow exporters
    
    While there are no inherent limits to the number of exporters we're
    likely to scale rather badly to very large numbers. There's also no
    obvious use case for more than a handful. Limit to 128 exporters to
    prevent foot-shooting.
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/net/pflow.h               |  2 ++
 sys/netpfil/pf/pflow.c        |  6 +++++-
 tests/sys/netpfil/pf/pflow.sh | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/sys/net/pflow.h b/sys/net/pflow.h
index 456e3de52ab1..4c194e14e001 100644
--- a/sys/net/pflow.h
+++ b/sys/net/pflow.h
@@ -39,6 +39,8 @@
 #include <netinet/ip.h>
 #endif
 
+#define PFLOW_MAX_ENTRIES	128
+
 #define PFLOW_ID_LEN	sizeof(u_int64_t)
 
 #define PFLOW_MAXFLOWS 30
diff --git a/sys/netpfil/pf/pflow.c b/sys/netpfil/pf/pflow.c
index 0000aa05ee0d..17a68e0d9e57 100644
--- a/sys/netpfil/pf/pflow.c
+++ b/sys/netpfil/pf/pflow.c
@@ -176,7 +176,7 @@ vnet_pflowattach(void)
 	CK_LIST_INIT(&V_pflowif_list);
 	mtx_init(&V_pflowif_list_mtx, "pflow interface list mtx", NULL, MTX_DEF);
 
-	V_pflow_unr = new_unrhdr(0, INT_MAX, &V_pflowif_list_mtx);
+	V_pflow_unr = new_unrhdr(0, PFLOW_MAX_ENTRIES - 1, &V_pflowif_list_mtx);
 
 	for (int i = 0; i < pflow_ncounters; i++)
 		V_pflowstats.c[i] = counter_u64_alloc(M_WAITOK);
@@ -1343,6 +1343,10 @@ pflow_nl_create(struct nlmsghdr *hdr, struct nl_pstate *npt)
 	ghdr_new->reserved = 0;
 
 	unit = alloc_unr(V_pflow_unr);
+	if (unit == -1) {
+		nlmsg_abort(nw);
+		return (ENOMEM);
+	}
 
 	error = pflow_create(unit);
 	if (error != 0) {
diff --git a/tests/sys/netpfil/pf/pflow.sh b/tests/sys/netpfil/pf/pflow.sh
index 10efcbb93ac4..f0552eb061da 100644
--- a/tests/sys/netpfil/pf/pflow.sh
+++ b/tests/sys/netpfil/pf/pflow.sh
@@ -282,6 +282,37 @@ rule_cleanup()
 	pft_cleanup
 }
 
+atf_test_case "max_entries" "cleanup"
+max_entries_head()
+{
+	atf_set descr 'Test that we can only create X pflow senders'
+	atf_set require.user root
+}
+
+max_entries_body()
+{
+	pflow_init
+
+	vnet_mkjail alcatraz
+
+	for i in `seq 1 128`
+	do
+		atf_check -s exit:0 -o ignore \
+		    jexec alcatraz pflowctl -c
+	done
+
+	# We cannot create the 129th pflow sender
+	atf_check -s exit:1 -o ignore -e ignore \
+	    jexec alcatraz pflowctl -c
+
+	jexec alcatraz pflowctl -l
+}
+
+max_entries_cleanup()
+{
+	pft_cleanup
+}
+
 atf_test_case "obs_dom" "cleanup"
 obs_dom_head()
 {
@@ -313,5 +344,6 @@ atf_init_test_cases()
 	atf_add_test_case "v6"
 	atf_add_test_case "nat"
 	atf_add_test_case "rule"
+	atf_add_test_case "max_entries"
 	atf_add_test_case "obs_dom"
 }