From nobody Thu Oct 29 06:03:10 2026 X-Original-To: dev-commits-src-branches@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 4jFYYp4pMGz6xr1Q for ; Thu, 29 Oct 2026 06:03:10 +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) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 4jFYYp2fcjz4sDf for ; Thu, 29 Oct 2026 06:03:10 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793253790; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=cwE63fiiAWgO1LSyd8B4L+a+l40io4LTTM7AmLRzBMw=; b=tGsZuFEAxSatKfNUxYoTey/HUTC6sFqD1kqr3Et9NIVlFTgjwwxJKnHFP9YnA5BXbe1jT6 clWY/jPExKTCANl6DR39D5/H2IXVpTpeLfBcCIYoWW+uY5qiiwiEm3cmQ2DlY7bPxbFURQ f/9LMT3g8pPnTAmddz+eZlXG/W4XndAEgR5o5ZZXHAoVhvGGA2+0Norcvf/x0VHCmbKr+P WlJFIxKUDS2wg+JdsSV+VVLbkgtxilmB3zb/q4EODXIV+QrErxWXAgSLSF84OOv+ZgPtSy 7F+dvw6LNuaQYMLO3Fx3t2LCsomiOGCQgBvJNlcFEAGIb5BSje8ZzRiDRAhwJw== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1793253790; b=ArP9bqPxvis6E5+Z2Tx++Bg1pSfT20wgv0LMdPvICH3k9eYUnBZW2nw2rpGhURB6p/rF1D xhUojTWXUJOEoTS1FM7EJZruLSDgEwF/lgDfpkD6wG8xIfX5bCNy+BoK6RQ9V//U6BGqxg PJjlj2eQdUNDPulBtqigmN8jrxAeVXfyASoRfJQWPG5TrZ2+r4/ucjTJ1smdUYiUoWfTWC 1/1fMJiXMFvzAtNNjJ9iTy7XKDafQOGgNaA+zn54+BxjlbAY/K5ktcfKDCV056DXQGLA0n cBDyIVJPmKVLOys8n9e+3MgL3I5A6zI32UHDqz5e+h28vyHajx/hOpH9VAONSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1793253790; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=cwE63fiiAWgO1LSyd8B4L+a+l40io4LTTM7AmLRzBMw=; b=OpWeerGOJhscisvHcuBPn3BWeQgdZnZKHqXobVpw7JK3V5DNTGd1KENQwXJ68WV4h/jiOZ QoU5jw3ij4gWbMDW5x56Gx9UGQx4ADDLflH7oSUgeLMk3COaEiH9aqFKQVt6uxXrdC5ukE sMUpV6j6oUu6/qAvDhAFCxOe5tnlhWPu9XU5yBGr/DOeivB1yjogszhK8ypwRo5j6IJjzg 1hp4rMm6VzomqWH1gOlC/GThCIjHv77WgG9N7mXLL777hGOtl6bJ1Kicx+R9z43RschohU CHMeaCSaTo5H3sSzw2JzCNrU6J/j8LyLB0iJ0+XciZDOHYAzL0GOxkhioF2m7Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4jFYYp2JQkzR9W for ; Thu, 29 Oct 2026 06:03:10 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3abd0 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Thu, 29 Oct 2026 06:03:10 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: Andrew Gallatin From: Kevin Bowling Subject: git: 60397132f051 - stable/15 - iflib: Fix several memory handling issues around iflib_encap() List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org List-Id: Commits to the stable branches of the FreeBSD src repository 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: kbowling X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 60397132f051c3a23654c7fb7234a5e54ac7900b Auto-Submitted: auto-generated Date: Thu, 29 Oct 2026 06:03:10 +0000 Message-Id: <6ae2e19e.3abd0.3f4699e1@gitrepo.freebsd.org> The branch stable/15 has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=60397132f051c3a23654c7fb7234a5e54ac7900b commit 60397132f051c3a23654c7fb7234a5e54ac7900b Author: Andrew Gallatin AuthorDate: 2026-08-14 19:38:34 +0000 Commit: Kevin Bowling CommitDate: 2026-10-29 05:28:17 +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 (cherry picked from commit 73cceb046cd86187bc3e3bad07dd2422ee102552) --- 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 05bec333e7c1..0b23e0ea31cb 100644 --- a/sys/net/iflib.c +++ b/sys/net/iflib.c @@ -3389,13 +3389,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 */ @@ -3491,13 +3490,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 */ @@ -3532,6 +3530,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; @@ -3546,8 +3547,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. */ @@ -3578,6 +3578,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); @@ -3593,14 +3595,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. */ @@ -3666,15 +3670,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; @@ -3684,10 +3687,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); @@ -3792,8 +3796,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); @@ -3903,6 +3906,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; } /*