git: bfeef0d32a00 - main - pf: fix pfi_ifnet leak on interface removal
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 14 Dec 2022 09:20:07 UTC
The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=bfeef0d32a0036bf6bec93a439e0466efe6f4482 commit bfeef0d32a0036bf6bec93a439e0466efe6f4482 Author: Nick Reilly <nreilly@blackberry.com> AuthorDate: 2022-11-30 14:19:44 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2022-12-14 09:19:01 +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 --- 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 7cbb750d3ab1..970d1398f870 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1545,14 +1545,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 f572d80c219f..71bd215d3d24 100644 --- a/sys/netpfil/pf/pf_if.c +++ b/sys/netpfil/pf/pf_if.c @@ -364,14 +364,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; @@ -391,6 +388,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) { @@ -1039,6 +1048,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(); NET_EPOCH_EXIT(et); } @@ -1099,6 +1110,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(); }