git: 275ff85b254c - main - pf: fix struct pf_krule_global leak
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 02 Sep 2025 21:10:58 UTC
The branch main has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=275ff85b254c1f160f965dd9dbb5801f66022eab
commit 275ff85b254c1f160f965dd9dbb5801f66022eab
Author: Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2025-09-01 08:32:30 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2025-09-02 21:10:21 +0000
pf: fix struct pf_krule_global leak
Make sure we free all of the trees we allocated when we free the ruleset.
Found by 'kldunload pf' after a test run, now that the allocation is done from a
pf-specific malloc type.
Sponsored by: Rubicon Communications, LLC ("Netgate")
---
sys/net/pfvar.h | 1 +
sys/netpfil/pf/pf_ioctl.c | 2 +-
sys/netpfil/pf/pf_ruleset.c | 6 ++++++
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 79855fa84359..f73420494000 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -2614,6 +2614,7 @@ struct pf_kruleset *pf_find_kruleset(const char *);
struct pf_kruleset *pf_get_leaf_kruleset(char *, char **);
struct pf_kruleset *pf_find_or_create_kruleset(const char *);
void pf_rs_initialize(void);
+void pf_rule_tree_free(struct pf_krule_global *);
struct pf_krule *pf_krule_alloc(void);
diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c
index 934eff020074..06c40a03f575 100644
--- a/sys/netpfil/pf/pf_ioctl.c
+++ b/sys/netpfil/pf/pf_ioctl.c
@@ -1189,7 +1189,7 @@ pf_rule_tree_alloc(int flags)
return (tree);
}
-static void
+void
pf_rule_tree_free(struct pf_krule_global *tree)
{
diff --git a/sys/netpfil/pf/pf_ruleset.c b/sys/netpfil/pf/pf_ruleset.c
index 259f586fa127..1711e690f6bb 100644
--- a/sys/netpfil/pf/pf_ruleset.c
+++ b/sys/netpfil/pf/pf_ruleset.c
@@ -336,6 +336,12 @@ pf_remove_if_empty_kruleset(struct pf_kruleset *ruleset)
int i;
while (ruleset != NULL) {
+ for (int i = 0; i < PF_RULESET_MAX; i++) {
+ pf_rule_tree_free(ruleset->rules[i].active.tree);
+ ruleset->rules[i].active.tree = NULL;
+ pf_rule_tree_free(ruleset->rules[i].inactive.tree);
+ ruleset->rules[i].inactive.tree = NULL;
+ }
if (ruleset == &pf_main_ruleset ||
!RB_EMPTY(&ruleset->anchor->children) ||
ruleset->anchor->refcnt > 0 || ruleset->tables > 0 ||