From nobody Fri Aug 14 19:44:54 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hMCP30jg3z6ndFR for ; Fri, 14 Aug 2026 19:44:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hMCP24gdSz3N3Z for ; Fri, 14 Aug 2026 19:44:54 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786736694; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=S57mz7MNxO30O7W0B22IZKKgukb4gCMhDlkg2Aa26ps=; b=vPfYl+tSa7hWr9cyoN1slpyRCM5jd5YbPeCamdzA2zhaRdp/TuxnPh5aBrxzG0Azx2jcW7 02YOYHVNa/f81U5eGwY0u/r84/IqTpPnvGOUZZLj9WToI0ZGTQZVsYyPTjjyneQmFnR4eL Q1iCnuKu37meVQ5JaQQ8jno8+j5OxjV9pgPi5d7iCV5FXe6kBwWUJiBR7zSuRY5q2b4+ON mytc+gTAPJ6TGxaihHYLaQpz6HefPNb8kq+QzOceDtnzhkiSvvxUih1k5Se0z2PMZIPN6k Fa6o7ql1dWMaYeUjHuA9zgruXca3PLteClMItTTy9WszWoHTNh1mCc1vkmzHeg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1786736694; a=rsa-sha256; cv=none; b=RLQFykEKr3oU1yq4KjY4itGTZupT6pDldoz1CMYUztGRvE9Qs26GGpL3TOuMn4fHzAUfYq ET+/a1g36sgB/gKryeKSlvQrF8tCve6NVJLJEtbhi502nxRNJGI4h4npgSntbM4VQ5uSvI yHInbGN1D1DRxADmTtfC0Xhgm9/uNOf4aLgOumRN5/5dFoNZU4RxEF1oO/RZWypiTscoqH xkPG4UYXXAgITAxRgO5KRVjAjMeOhcVyY9FYN+r1WQSR1odl8bb80um9zOcmmqa6iT5d6O hXct2AFmQJjdUiJGz4Du8R58hEbPTPuT21tmDo3jEucqJoRcVEoB1nyyA8hbUQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1786736694; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=S57mz7MNxO30O7W0B22IZKKgukb4gCMhDlkg2Aa26ps=; b=w8JIMfqmQ80e8eNwXq0MisO+zgY1jE3gGedZTyX2RzyTZytT+VPHMWqZxPS6yP9IKMc4E/ Wa0WCepQAc/Yo/MibsmIH+bphL7XYsfwg6kmUQCk8Jpjc9cfJ3d4lbCLNE4a8DaF1V1V5y p4rfp+0rDyAszHb3XzAn5Qvr2aLS1mD38i+zPyn1bSQEk4YtnuDO/Qt0CtQ+yeI+SrCWh5 MUSAz/eHbn1zFb2fRnL/W8EOHc8vIykrSauZdKP7+7IL6Vjx22k4E4+7clHMQnyvn5YDYt oNMTN/FPIhrI7sT36ZxdbXZ1dyh4DfEfolokk5RAZn3BJ+qmjdBawqO1KUF+qQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hMCP23kwvz1BS8 for ; Fri, 14 Aug 2026 19:44:54 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 37a9d by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 14 Aug 2026 19:44:54 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Andrew Gallatin Subject: git: 73cceb046cd8 - main - iflib: Fix several memory handling issues around iflib_encap() List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: gallatin X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 73cceb046cd86187bc3e3bad07dd2422ee102552 Auto-Submitted: auto-generated Date: Fri, 14 Aug 2026 19:44:54 +0000 Message-Id: <6a7f7036.37a9d.a16905f@gitrepo.freebsd.org> The branch main has been updated by gallatin: URL: https://cgit.FreeBSD.org/src/commit/?id=73cceb046cd86187bc3e3bad07dd2422ee102552 commit 73cceb046cd86187bc3e3bad07dd2422ee102552 Author: Andrew Gallatin AuthorDate: 2026-08-14 19:38:34 +0000 Commit: Andrew Gallatin CommitDate: 2026-08-14 19:42:50 +0000 iflib: Fix several memory handling issues around iflib_encap() - Fixed memory leaks around m_dup() not freeing the original chain on failure. If we return ENOMEM, we are expected to have freed the chain, else the mbuf would be leaked. Also updated iflib_ether_pad() to follow the same structure. - In iflib_parse_header() o Fixed a bug where the ip/ip6 and th pointers may point into a freed chain after m_pullup. Those pointers must be reset to point into the new chain. o Eliminate ENXIO returns for non-TCP TSO sends (which would violate the mbuf ownership contract if they could happen). Since they cannot happen, I made them assertions instead. - in iflib_ether_pad(), return ENOMEM after freeing mbuf, so that mp_ring knows it is free. An ENOBUFS error will cause the mp_ring path to retain the mbuf and retry - in iflib_encap(): o Fix a leak when bus_dmamap_load_mbuf_sg() returns ENOMEM o Fix a use-after-free in the mp_ring path when a driver using ktls frees an mbuf and returns ENOBUFS via iflib_encap() After this change the expection from iflib_encap is that: mp_ring: ENOBUFS can be returned only when we run out of descriptors (ENOBUFS causes mp_ring to retain the mbuf). simple_tx: iflib_encap() always consumes the mbuf, regardless of the return Note that iflib_debugnet_transmit(), like simple_tx, expects that iflib_encap() always consumes mbufs. This will be true after mp_ring is removed, and its such a rare special case (overrunning the ring during panic dumps) that I don't think its worth fixing in the meantime. Sponsored by: Netflix Reviewed by: kbowling, sumit.saxena_broadcom.com Differential Revision: https://reviews.freebsd.org/D58843 Fixes: 074ff8746388 --- sys/net/iflib.c | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/sys/net/iflib.c b/sys/net/iflib.c index abc56f159547..d2ac8d884a60 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -3262,13 +3262,12 @@ iflib_parse_header_partial(if_pkt_info_t pi, struct mbuf **mp, uint64_t *pullups *pullups = 0; m = *mp; if (!M_WRITABLE(m)) { - if ((m = m_dup(m, M_NOWAIT)) == NULL) { + m = m_dup(m, M_NOWAIT); + m_freem(*mp); + DBG_COUNTER_INC(tx_frees); + *mp = m; + if (m == NULL) return (ENOMEM); - } else { - m_freem(*mp); - DBG_COUNTER_INC(tx_frees); - *mp = m; - } } /* Fills out pi->ipi_etype */ @@ -3364,13 +3363,12 @@ iflib_parse_header(iflib_txq_t txq, if_pkt_info_t pi, struct mbuf **mp) m = *mp; if ((sctx->isc_flags & IFLIB_NEED_SCRATCH) && M_WRITABLE(m) == 0) { - if ((m = m_dup(m, M_NOWAIT)) == NULL) { + m = m_dup(m, M_NOWAIT); + m_freem(*mp); + DBG_COUNTER_INC(tx_frees); + *mp = m; + if (m == NULL) return (ENOMEM); - } else { - m_freem(*mp); - DBG_COUNTER_INC(tx_frees); - *mp = m; - } } /* Fills out pi->ipi_etype */ @@ -3405,6 +3403,9 @@ iflib_parse_header(iflib_txq_t txq, if_pkt_info_t pi, struct mbuf **mp) txq->ift_pullups++; if ((m = m_pullup(m, hlen)) == NULL) return (ENOMEM); + /* reset pointers after pullup */ + ip = (struct ip *)(m->m_data + pi->ipi_ehdrlen); + th = (struct tcphdr *)((char *)ip + (ip->ip_hl << 2)); } pi->ipi_ip_hlen = ip->ip_hl << 2; pi->ipi_ipproto = ip->ip_p; @@ -3419,8 +3420,7 @@ iflib_parse_header(iflib_txq_t txq, if_pkt_info_t pi, struct mbuf **mp) pi->ipi_tcp_seq = th->th_seq; } if (IS_TSO4(pi)) { - if (__predict_false(ip->ip_p != IPPROTO_TCP)) - return (ENXIO); + MPASS(ip->ip_p == IPPROTO_TCP); /* * TSO always requires hardware checksum offload. */ @@ -3451,6 +3451,8 @@ iflib_parse_header(iflib_txq_t txq, if_pkt_info_t pi, struct mbuf **mp) txq->ift_pullups++; if (__predict_false((m = m_pullup(m, pi->ipi_ehdrlen + sizeof(struct ip6_hdr))) == NULL)) return (ENOMEM); + /* reset pointers after pullup */ + ip6 = (struct ip6_hdr *)(m->m_data + pi->ipi_ehdrlen); } th = (struct tcphdr *)((caddr_t)ip6 + pi->ipi_ip_hlen); @@ -3466,14 +3468,16 @@ iflib_parse_header(iflib_txq_t txq, if_pkt_info_t pi, struct mbuf **mp) txq->ift_pullups++; if (__predict_false((m = m_pullup(m, pi->ipi_ehdrlen + sizeof(struct ip6_hdr) + sizeof(struct tcphdr))) == NULL)) return (ENOMEM); + /* reset pointers after pullup */ + ip6 = (struct ip6_hdr *)(m->m_data + pi->ipi_ehdrlen); + th = (struct tcphdr *)((caddr_t)ip6 + pi->ipi_ip_hlen); } pi->ipi_tcp_hflags = tcp_get_flags(th); pi->ipi_tcp_hlen = th->th_off << 2; pi->ipi_tcp_seq = th->th_seq; } if (IS_TSO6(pi)) { - if (__predict_false(ip6->ip6_nxt != IPPROTO_TCP)) - return (ENXIO); + MPASS(ip6->ip6_nxt == IPPROTO_TCP); /* * TSO always requires hardware checksum offload. */ @@ -3539,15 +3543,14 @@ iflib_ether_pad(device_t dev, struct mbuf **m_head, uint16_t min_frame_size) if (!M_WRITABLE(*m_head)) { new_head = m_dup(*m_head, M_NOWAIT); + m_freem(*m_head); + *m_head = new_head; if (new_head == NULL) { - m_freem(*m_head); device_printf(dev, "cannot pad short frame, m_dup() failed"); DBG_COUNTER_INC(encap_pad_mbuf_fail); DBG_COUNTER_INC(tx_frees); return (ENOMEM); } - m_freem(*m_head); - *m_head = new_head; } for (n = min_frame_size - (*m_head)->m_pkthdr.len; @@ -3557,10 +3560,11 @@ iflib_ether_pad(device_t dev, struct mbuf **m_head, uint16_t min_frame_size) if (n > 0) { m_freem(*m_head); + *m_head = NULL; device_printf(dev, "cannot pad short frame\n"); DBG_COUNTER_INC(encap_pad_mbuf_fail); DBG_COUNTER_INC(tx_frees); - return (ENOBUFS); + return (ENOMEM); } return (0); @@ -3665,8 +3669,7 @@ defrag: goto retry; break; case ENOMEM: - txq->ift_no_tx_dma_setup++; - break; + /* FALLTHROUGH */ default: txq->ift_no_tx_dma_setup++; m_freem(*m_headp); @@ -3776,6 +3779,9 @@ defrag: } goto defrag_failed; } + /* mp_ring assumes ENOBUFS means we didn't consume the mbuf */ + if (err == ENOBUFS && !ctx->ifc_sysctl_simple_tx) + err = ENOMEM; goto out_with_error; } /*