git: 5f7454d8904c - stable/12 - pf: fix pfi_ifnet leak on interface removal
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 Dec 2022 09:03:13 UTC
The branch stable/12 has been updated by kp:
URL: https://cgit.FreeBSD.org/src/commit/?id=5f7454d8904ca68697dda569f71af6ef5ec178c7
commit 5f7454d8904ca68697dda569f71af6ef5ec178c7
Author: Nick Reilly <nreilly@blackberry.com>
AuthorDate: 2022-11-30 14:19:44 +0000
Commit: Kristof Provost <kp@FreeBSD.org>
CommitDate: 2022-12-28 04:56:08 +0000
pf: fix pfi_ifnet leak on interface removal
The detach of the interface and group were leaving pfi_ifnet memory
behind. Check if the kif still has references, and clean it up if it
doesn't
On interface detach, the group deletion was notified first and then a
change notification was sent. This would recreate the group in the kif
layer. Reorder the change to before the delete.
PR: 257218
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D37569
(cherry picked from commit bfeef0d32a0036bf6bec93a439e0466efe6f4482)
---
sys/net/if.c | 3 +--
sys/netpfil/pf/pf_if.c | 23 ++++++++++++++++++-----
2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/sys/net/if.c b/sys/net/if.c
index f2c306af7095..14f03286358d 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1574,14 +1574,13 @@ _if_delgroup_locked(struct ifnet *ifp, struct ifg_list *ifgl,
IFNET_WUNLOCK();
epoch_wait_preempt(net_epoch_preempt);
+ EVENTHANDLER_INVOKE(group_change_event, groupname);
if (freeifgl) {
EVENTHANDLER_INVOKE(group_detach_event, ifgl->ifgl_group);
free(ifgl->ifgl_group, M_TEMP);
}
free(ifgm, M_TEMP);
free(ifgl, M_TEMP);
-
- EVENTHANDLER_INVOKE(group_change_event, groupname);
}
/*
diff --git a/sys/netpfil/pf/pf_if.c b/sys/netpfil/pf/pf_if.c
index 55e5e4ccac83..e9d18d717257 100644
--- a/sys/netpfil/pf/pf_if.c
+++ b/sys/netpfil/pf/pf_if.c
@@ -340,14 +340,11 @@ pfi_kkif_ref(struct pfi_kkif *kif)
kif->pfik_rulerefs++;
}
-void
-pfi_kkif_unref(struct pfi_kkif *kif)
+static void
+pfi_kkif_remove_if_unref(struct pfi_kkif *kif)
{
PF_RULES_WASSERT();
- KASSERT(kif->pfik_rulerefs > 0, ("%s: %p has zero refs", __func__, kif));
-
- kif->pfik_rulerefs--;
if (kif->pfik_rulerefs > 0)
return;
@@ -367,6 +364,18 @@ pfi_kkif_unref(struct pfi_kkif *kif)
mtx_unlock(&pfi_unlnkdkifs_mtx);
}
+void
+pfi_kkif_unref(struct pfi_kkif *kif)
+{
+
+ PF_RULES_WASSERT();
+ KASSERT(kif->pfik_rulerefs > 0, ("%s: %p has zero refs", __func__, kif));
+
+ kif->pfik_rulerefs--;
+
+ pfi_kkif_remove_if_unref(kif);
+}
+
void
pfi_kkif_purge(void)
{
@@ -1012,6 +1021,8 @@ pfi_detach_ifnet_event(void *arg __unused, struct ifnet *ifp)
#ifdef ALTQ
pf_altq_ifnet_event(ifp, 1);
#endif
+ pfi_kkif_remove_if_unref(kif);
+
PF_RULES_WUNLOCK();
}
@@ -1061,6 +1072,8 @@ pfi_detach_group_event(void *arg __unused, struct ifg_group *ifg)
kif->pfik_group = NULL;
ifg->ifg_pf_kif = NULL;
+
+ pfi_kkif_remove_if_unref(kif);
PF_RULES_WUNLOCK();
}