From nobody Wed Apr 1 08:37:53 2026 Received: from mail-oa1-f48.google.com (mail-oa1-f48.google.com [209.85.160.48]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4A894D531 for ; Wed, 1 Apr 2026 04:47:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.160.48 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775018873; cv=none; b=m2QKfEeusHpVceLgqvv+JgqLzvW4NZwitmkffxURRd0bTz5z4BDvseYYad+I4UAR4S0m5A9ey6VT4BifWGwcCnGjRXXHn3+Mm/0eS97nwXTzunXtcheAry/qXiFpbnp6cK0QV0x/0FWbYCMI7P+5y07L85J9slsGm0Ksa2Sqe+4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775018873; c=relaxed/simple; bh=PpxbFaO33bEnNjvzKyApo/Q9GShxwpa/nEGQ/v232KI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IbUEeR+B5L4wsGlpsYIw8gpzgDFKAINSvFfTWgZtJ5TPa7mAv2+uKEJJGwx88C9JOil+UNC1eughbUOCgJQpxNQhIxS0nsgrVODJfnldnydWC/KUvnDyhlesRDRpEFKWKy8Z/kFn0s5OZR40yh+bGKiMX9ivjIlgXUlY6rJtJpg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kV7iIagN; arc=none smtp.client-ip=209.85.160.48 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kV7iIagN" Received: by mail-oa1-f48.google.com with SMTP id 586e51a60fabf-40974bf7781so552264fac.0 for ; Tue, 31 Mar 2026 21:47:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1775018869; x=1775623669; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=caSr3lZmDOdG5gDgsxTCqvAp/bk5INHxsGesKdHh4yc=; b=kV7iIagN3OPwY8LqxeWEyUuTT3d3FY0XnkDkZYZ4907I/BDBFH8ZdQ9JYLeSAc0I9e sm+qs3VCOowkoM6xUeo4qXo433SexMDgmlqdbEWV6NFXf5R+RauF7Zfz4oax3Cz1jA2D HeesVXNxACkQvB31wBblVLzQxI6Jg99yGqu/bpcymlw6RcdK12aFDkpsY6KlSAxBHfEw omjk/K6wp2Dr/1VpR5TMJLTb2fFE5HvzCmvWZfq/efS2mFFHCCXtt/96p+8JOJTQul9f kciEv8BeiB7mflINxT8E7XPuBRUDHtUkDLjAPyUwtIqSprJz73lOl3765HIXVvxgWUMH bRnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775018869; x=1775623669; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=caSr3lZmDOdG5gDgsxTCqvAp/bk5INHxsGesKdHh4yc=; b=PNJrrn2IqZp8hKkxdIw1wVn9iTC38VYATAcxS9AJ2RHuyQLKfLlyNC+DhrMhVuugPo 9SvFy/grIUVnC+jJ2PKkXmS+wSgrsuWdOqGl/5eXbspLM9nr6E3Ch0G/gQzQXMlY6Jtv MeFbfwjR1n5DGVF1deQbxGk7myejhWpnZgguuGuyAzIbgaV10Qo9YuB/0xQrUdXvKioy 55IJdsBUAosw8PUCfndD7wFP9ZORmz+nHq+adQTR0DGvvQdqm/v5/ZbJQpjdCNzrrvaz bQtN1GpM9PnxN9R+DTPDBl3uV3yzAdQA0umOe2bBbThz30UGZn3j6V/RdbUrFrRiHCoU jqzw== X-Forwarded-Encrypted: i=1; AJvYcCUQH9fyya5YImIS7ZRcboynaBsES5/vKBejpXDmwnFweSymo0XS6HvnLgcQfUn3II0jaJyQUBCB7H6/C4E=@vger.kernel.org X-Gm-Message-State: AOJu0Yx6tiyBXdu4ZRxbMZCZ9wEJvyH/qtjXSsiVk8mcQx8RzWmK7P64 6mDEQIgjYLof1DLFIzGd/zJayij2BV1lQQSRyY0/sgDS+M3wXTzOe6wU+cvhExJ2 X-Gm-Gg: ATEYQzym1uWPqEwdkgtGQlbC8YFZRJ04EwFmkBEYOQLVo7sLBDgT7P50gSwOtqUoUNL AyMGmpjLUlTlYum2ji887x19hTQRc89/bwQCUXRVQvhH+sTVdt3QfCG3WNnxkHVzUCarFO5ZfPG otMyMkeVOQt58ria61/dMyRJTIKw5+a8hGOTf3nH3B6GC3IIjJaVQxMQYqn6PkFDLdVDfAUrj3X CA7XqWmt88vGZsgyu+cH5T0eg76HCHas8SrF2DDOnEJQ9Ql78K0PPW0aEV4tHGCDiiXp5aMIPpO pKhgF86OCcS2ZwB32lnatYIEEh+v/S+lwNpKwZA5EOgEz3wwYAPYyDkc3xlsu4umEi8QnDkFHhy L+GPdy2fLtSYXmAv9y1myooWNfpluSxMvRXn/knhzu6Hyj/9Mz4PS5PC7JBQCUquDe2uaCPPUKn oqGlIjg7inFxmUdHnb7tdRbq51zV3rAuYvSGydzM6rMzozT88nZRhIetZouiCK3BuZFZ/oDtJ3C xrp X-Received: by 2002:a05:6870:3211:b0:41c:1d37:3825 with SMTP id 586e51a60fabf-422a5156c4bmr3477405fac.17.1775018869186; Tue, 31 Mar 2026 21:47:49 -0700 (PDT) Received: from CS-396-Lab-Machine.. (c-24-12-10-127.hsd1.il.comcast.net. [24.12.10.127]) by smtp.gmail.com with ESMTPSA id 586e51a60fabf-41d04d79c35sm8741721fac.18.2026.03.31.21.47.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 31 Mar 2026 21:47:47 -0700 (PDT) From: Tyllis Xu X-Google-Original-From: Tyllis Xu To: netdev@vger.kernel.org Cc: andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com, kuba@kernel.org, pabeni@redhat.com, peppe.cavallaro@st.com, rayagond@vayavyalabs.com, stable@vger.kernel.org, linux-kernel@vger.kernel.org, danisjiang@gmail.com, ychen@northwestern.edu, Tyllis Xu Subject: [PATCH net v2] net: stmmac: fix integer underflow in chain mode Date: Tue, 31 Mar 2026 23:47:07 -0500 Message-ID: <20260401044708.1386919-1-LivelyCarpet87@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The jumbo_frm() chain-mode implementation unconditionally computes len =3D nopaged_len - bmax; where nopaged_len =3D skb_headlen(skb) (linear bytes only) and bmax is BUF_SIZE_8KiB or BUF_SIZE_2KiB. However, the caller stmmac_xmit() decides to invoke jumbo_frm() based on skb->len (total length including page fragments): is_jumbo =3D stmmac_is_jumbo_frm(priv, skb->len, enh_desc); When a packet has a small linear portion (nopaged_len <=3D bmax) but a large total length due to page fragments (skb->len > bmax), the subtraction wraps as an unsigned integer, producing a huge len value (~0xFFFFxxxx). This causes the while (len !=3D 0) loop to execute hundreds of thousands of iterations, passing skb->data + bmax * i pointers far beyond the skb buffer to dma_map_single(). On IOMMU-less SoCs (the typical deployment for stmmac), this maps arbitrary kernel memory to the DMA engine, constituting a kernel memory disclosure and potential memory corruption from hardware. Fix this by introducing a buf_len local variable clamped to min(nopaged_len, bmax). Computing len =3D nopaged_len - buf_len is then always safe: it is zero when the linear portion fits within a single descriptor, causing the while (len !=3D 0) loop to be skipped naturally, and the fragment loop in stmmac_xmit() handles page fragments afterward. Fixes: 286a83721720 ("stmmac: add CHAINED descriptor mode support (V4)") Cc: stable@vger.kernel.org Signed-off-by: Tyllis Xu --- v2: Instead of restructuring into an if/else block (v1), introduce a buf_len local variable clamped to min(nopaged_len, bmax) so the subtraction and the existing while loop remain structurally intact. Suggested by Russell King. drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c b/drivers/net= /ethernet/stmicro/stmmac/chain_mode.c index 120a009c9992..37f9417c7c0e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c +++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c @@ -20,7 +20,7 @@ static int jumbo_frm(struct stmmac_tx_queue *tx_q, struct= sk_buff *skb, unsigned int nopaged_len =3D skb_headlen(skb); struct stmmac_priv *priv =3D tx_q->priv_data; unsigned int entry =3D tx_q->cur_tx; - unsigned int bmax, des2; + unsigned int bmax, buf_len, des2; unsigned int i =3D 1, len; struct dma_desc *desc; =20 @@ -31,17 +31,18 @@ static int jumbo_frm(struct stmmac_tx_queue *tx_q, stru= ct sk_buff *skb, else bmax =3D BUF_SIZE_2KiB; =20 - len =3D nopaged_len - bmax; + buf_len =3D min_t(unsigned int, nopaged_len, bmax); + len =3D nopaged_len - buf_len; =20 des2 =3D dma_map_single(priv->device, skb->data, - bmax, DMA_TO_DEVICE); + buf_len, DMA_TO_DEVICE); desc->des2 =3D cpu_to_le32(des2); if (dma_mapping_error(priv->device, des2)) return -1; tx_q->tx_skbuff_dma[entry].buf =3D des2; - tx_q->tx_skbuff_dma[entry].len =3D bmax; + tx_q->tx_skbuff_dma[entry].len =3D buf_len; /* do not close the descriptor and do not set own bit */ - stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum, STMMAC_CHAIN_MODE, + stmmac_prepare_tx_desc(priv, desc, 1, buf_len, csum, STMMAC_CHAIN_MODE, 0, false, skb->len); =20 while (len !=3D 0) { --=20 2.43.0