git: 51088797305c - main - bridge: Fix a potential memory leak in bridge_enqueue()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 11 Dec 2022 16:41:47 UTC
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=51088797305c8aba43e8ded60b99eef5baa14071 commit 51088797305c8aba43e8ded60b99eef5baa14071 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2022-12-11 16:40:12 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2022-12-11 16:41:12 +0000 bridge: Fix a potential memory leak in bridge_enqueue() A comment at the beginning of the function notes that we may be transmitting multiple fragments as distinct packets. So, the function loops over all fragments, transmitting each mbuf chain. If if_transmit fails, we need to free all of the fragments, but m_freem() only frees an mbuf chain - it doesn't follow m_nextpkt. Change the error handler to free each untransmitted packet fragment, and count each fragment as a separate error since we increment OPACKETS once per fragment when transmission is successful. Reviewed by: zlei, kp MFC after: 1 week Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D37635 --- sys/net/if_bridge.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index e8e552aa1853..5c3ce137931c 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -2062,8 +2062,13 @@ bridge_enqueue(struct bridge_softc *sc, struct ifnet *dst_ifp, struct mbuf *m) M_ASSERTPKTHDR(m); /* We shouldn't transmit mbuf without pkthdr */ if ((err = dst_ifp->if_transmit(dst_ifp, m))) { - m_freem(m0); - if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); + int n; + + for (m = m0, n = 1; m != NULL; m = m0, n++) { + m0 = m->m_nextpkt; + m_freem(m); + } + if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, n); break; }