git: e2903636a069 - main - iflib: Fix mbufs leaked by 0 len packets emitted from the if driver

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Wed, 17 Jun 2026 19:30:04 UTC
The branch main has been updated by kp:

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

commit e2903636a069d5ef364c8f56452bff5818d15f99
Author:     Reid Linnemann <reid.linnemann@spectralogic.com>
AuthorDate: 2026-06-17 18:22:44 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2026-06-17 19:29:31 +0000

    iflib: Fix mbufs leaked by 0 len packets emitted from the if driver
    
    Some interface drivers, notably bnxt, can insert 0 length packets onto
    their receive queues when certain conditions are met, such as discarding
    packets in the case of bnxt.
    
    When this packet gets processed by assemble_segments(), The solitary
    mbuf on the queue that composes it consist of a single zero length
    fragment. The loop in assemble_segments() doesn't seem to expect
    that a 0 length fragment can exist in the iri_frags list without a
    non-zero length header preceding it. In this situation, without filter
    intervention rxd_frag_to_sd() returns a pointer to the corresponding
    mbuf in the rxq, where it is matched as a zero-length fragment and
    immediately discarded without freeing as mh has not yet been assigned.
    
    This change corrects this behavior by falling through the mh == NULL
    case and freeing m on the condition that it is not NULL before
    continuing the loop.
    
    Reviewed by:    gallatin
    Sponsored by:   Spectra Logic
    Differential Revision:  https://reviews.freebsd.org/D57537
---
 sys/net/iflib.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sys/net/iflib.c b/sys/net/iflib.c
index 0ad805cb7c16..1af9d22db9a2 100644
--- a/sys/net/iflib.c
+++ b/sys/net/iflib.c
@@ -2797,14 +2797,14 @@ assemble_segments(iflib_rxq_t rxq, if_rxd_info_t ri, if_rxsd_t sd, int *pf_rv)
 		if (ri->iri_frags[i].irf_len == 0 || consumed ||
 		    *pf_rv == PFIL_CONSUMED || *pf_rv == PFIL_DROPPED) {
 			if (mh == NULL) {
-				/* everything saved here */
 				consumed = true;
 				pf_rv_ptr = NULL;
-				continue;
 			}
 			/* XXX we can save the cluster here, but not the mbuf */
-			m_init(m, M_NOWAIT, MT_DATA, 0);
-			m_free(m);
+			if (m != NULL) {
+				m_init(m, M_NOWAIT, MT_DATA, 0);
+				m_free(m);
+			}
 			continue;
 		}
 		if (mh == NULL) {