From nobody Mon Apr 6 09:08:20 2026 Received: from mail-ot1-f42.google.com (mail-ot1-f42.google.com [209.85.210.42]) (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 AC35D3BED06 for ; Thu, 19 Mar 2026 18:41:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773945671; cv=none; b=ksHKr1zOCLVoEn9wf9olHhPtoHAJvqiQt/NBGJWy1xo85kZ4topYpPu4G1ugnWynC7cdMLSoPmI8Q35otC4mTyO/xwsw6rVlQfRAByZdZno1WWYpHMtj9LU6rTBFbLpx0GfO45FUhhUD1byZbTriDsxBaka+f2Xdd85Eg60tLhU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773945671; c=relaxed/simple; bh=Un+tjKghOnSOGQJqIv2n+A/mJ2xTSQ27PpNpWvuI/2I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oB3GnZeGKaEq+uzvQxSqVvUH/EGPtKbrejkMZfyqkiki9Er76jt6HSeTPKTv//G9kBONLjAB53aagT84YJRQSjlwg/9nB1H7/kdPwdXyJfiBlrO9Bk2YeuGI3ClAEN5OPl1hjNyR2SXmqQwdfK2UaZKazwXaB1ilIgxsXRBR8M4= 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=GAe82fXB; arc=none smtp.client-ip=209.85.210.42 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="GAe82fXB" Received: by mail-ot1-f42.google.com with SMTP id 46e09a7af769-7d7653db148so534413a34.2 for ; Thu, 19 Mar 2026 11:41:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773945667; x=1774550467; 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=FLw+KspfNI17fHokU2DyOGE90apcIrKC40CCDarAeuo=; b=GAe82fXBPp4IO7bTdInpZQ/m8FT6DtbVlsAwaUjc/xxt2ctFYH1ghLshR5/ke+gqKY FNyJqkHOLBJDK/v6OfAY4MPSWt7uN92PVvGpcP6IzNQyE6RrpkRT83TGhQJtols6HkE6 F1x7ipXgh/xQzPeDfbJAL02rQwyydLlgqz4OxAb/U/5EkiodRaoq4m3YqbxaS16czCYy assYte3AXuBPvyFJF6nXJi62RlnZgG+gsnIJTA41K/+g4TYMtOS9Psmj9Om2dlH9cSjl XOqTw+7BLa10T1d+knLtMHG4/XGvzwZrs/2fOhNL5099L/fLo2VOaPHImuU4pJOrHEJ8 iqcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773945667; x=1774550467; 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=FLw+KspfNI17fHokU2DyOGE90apcIrKC40CCDarAeuo=; b=KAUlKHASH2B4QthkXgu/T5RZ++LfDFWjoAPYXF6cr3QhsrOdxhqxDv32Vfm43RRpL6 AwlGPkzYwn1ChCB81fs6PVVlcW5/A1JLoNskEK8RZPpepARznUkG9PuvuoJm9ujpmHAz Hn9DojtYPplKr8DJn2yEqeeyXkTWfDghKjXjQkRv0FlqzirECeq96aPiauL+QXaPzIkA OzNCOTnNKsxG/bfwA2osWewdxZDxUymmsmMQD4h1O6nEc0h2r87ND73ui5AcA3Ms1RSt yuxAgI6oQwEdHA2DQIQ/9HaWU+eep1+WA7TCvy174+QfsHFo2rm5kDOzcGogfUdTY1id Yiwg== X-Forwarded-Encrypted: i=1; AJvYcCU9GkaR9YwDICBb7OdfSYot090UGTfOwW9ra4tCMdmB6X9bmwcxz8TjGx6x1QSuyCYyWC1DRpktibxKMVI=@vger.kernel.org X-Gm-Message-State: AOJu0YytoceH0vDUngzgAbQcwazqXPjJd3YvXNPSU7yKhF3g1ZawuBdT eIyr4UReu9DH1NeiaqH9AcnHGllwrW2e2Ou3wSfow2OPzG0nEtUII7E4 X-Gm-Gg: ATEYQzwTWrpcyr7TVOE4XCKacLCtFrJlkc3OqitjEZwFtv5GZvDJ3caSAbE9kbmntQB vCh/b0jC78xPfL7aU7wXBQNnCqP3inElVQ24Oy7dezWsB6KeXtc4vtjf4VNOygW/yx7hppDOi0e HqMdC7rcvRaZhwjfXhpn6LES3BgfOCqcrwmPMXwHu+KkUA4kz0B7u2E0hpxQ286fNwIh50mB0ez ciWMgWL2JIoQzkuSZBANZd+D3Q9aAY19ifNBYTf88KCEgSgP0D+fde76tojOVAxwoRgO/Uu0a2i auYEoQ3rhd/fBF70rGHkJtJ0Nct77G/rHf1Qe6cMJYnZW4KXqAMQ58CD28XWxXDgBY2+vJpXV4J zxKjwFB7DEcE4fZfAh9PmElBBePxfaGHxFeG6VtipeqUg3OfEOdWfOnONZFOmlAdA8GuoCXcLQV M6BQZhnJLnQMocbAn0FVg2rLb7hTeBwF8zUK7hhKcP2K3qC9Y5pEmUr9ByJWEUU73GXikVwhjEy ZrJ9YCWoxc= X-Received: by 2002:a05:6830:651c:b0:7d7:d0d5:5bf6 with SMTP id 46e09a7af769-7d7eaf4f4femr168906a34.21.1773945667481; Thu, 19 Mar 2026 11:41:07 -0700 (PDT) Received: from celestia.turtle.lan (static-23-234-115-121.cust.tzulo.com. [23.234.115.121]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7d7eadcb757sm181486a34.15.2026.03.19.11.41.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2026 11:41:06 -0700 (PDT) From: Sam Edwards X-Google-Original-From: Sam Edwards To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: Russell King , Maxime Chevallier , Ovidiu Panait , Vladimir Oltean , Baruch Siach , Serge Semin , netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Sam Edwards , stable@vger.kernel.org Subject: [PATCH net v2 1/2] net: stmmac: Prevent NULL deref when RX memory exhausted Date: Thu, 19 Mar 2026 11:40:30 -0700 Message-ID: <20260319184031.8596-2-CFSworks@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260319184031.8596-1-CFSworks@gmail.com> References: <20260319184031.8596-1-CFSworks@gmail.com> 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 CPU receives frames from the MAC through conventional DMA: the CPU allocates buffers for the MAC, then the MAC fills them and returns ownership to the CPU. For each hardware RX queue, the CPU and MAC coordinate through a shared ring array of DMA descriptors: one descriptor per DMA buffer. Each descriptor includes the buffer's physical address and a status flag ("OWN") indicating which side owns the buffer: OWN=3D0 for CPU, OWN=3D1 for MAC. The CPU is only allowed to set the flag and the MAC is only allowed to clear it, and both must move through the ring in sequence: thus the ring is used for both "submissions" and "completions." In the stmmac driver, stmmac_rx() bookmarks its position in the ring with the `cur_rx` index. The main receive loop in that function checks for rx_descs[cur_rx].own=3D0, gives the corresponding buffer to the network stack (NULLing the pointer), and increments `cur_rx` modulo the ring size. After the loop exits, stmmac_rx_refill(), which bookmarks its position with `dirty_rx`, allocates fresh buffers and rearms the descriptors (setting OWN=3D1). If it fails any allocation, it simply stops early (leaving OWN=3D0) and will retry where it left off when next called. This means descriptors have a three-stage lifecycle (terms my own): - `empty` (OWN=3D1, buffer valid) - `full` (OWN=3D0, buffer valid and populated) - `dirty` (OWN=3D0, buffer NULL) But because stmmac_rx() only checks OWN, it confuses `full`/`dirty`. In the past (see 'Fixes:'), there was a bug where the loop could cycle `cur_rx` all the way back to the first descriptor it dirtied, resulting in a NULL dereference when mistaken for `full`. The aforementioned commit resolved that *specific* failure by capping the loop's iteration limit at `dma_rx_size - 1`, but this is only a partial fix: if the previous stmmac_rx_refill() didn't complete, then there are leftover `dirty` descriptors that the loop might encounter without needing to cycle fully around. The current code therefore panics (see 'Closes:') when stmmac_rx_refill() is memory-starved long enough for `cur_rx` to catch up to `dirty_rx`. Fix this by further tightening the clamp from `dma_rx_size - 1` to `dma_rx_size - stmmac_rx_dirty() - 1`, subtracting any remnant dirty entries and limiting the loop so that `cur_rx` cannot catch back up to `dirty_rx`. This carries no risk of arithmetic underflow: since the maximum possible return value of stmmac_rx_dirty() is `dma_rx_size - 1`, the worst the clamp can do is prevent the loop from running at all. Fixes: b6cb4541853c7 ("net: stmmac: avoid rx queue overrun") Closes: https://bugzilla.kernel.org/show_bug.cgi?id=3D221010 Cc: stable@vger.kernel.org Signed-off-by: Sam Edwards --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/ne= t/ethernet/stmicro/stmmac/stmmac_main.c index 6827c99bde8c..f98b070073c0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -5609,7 +5609,8 @@ static int stmmac_rx(struct stmmac_priv *priv, int li= mit, u32 queue) =20 dma_dir =3D page_pool_get_dma_dir(rx_q->page_pool); bufsz =3D DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE; - limit =3D min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit); + limit =3D min(priv->dma_conf.dma_rx_size - stmmac_rx_dirty(priv, queue) -= 1, + (unsigned int)limit); =20 if (netif_msg_rx_status(priv)) { void *rx_head; --=20 2.52.0 From nobody Mon Apr 6 09:08:20 2026 Received: from mail-ot1-f43.google.com (mail-ot1-f43.google.com [209.85.210.43]) (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 3552F3E95B0 for ; Thu, 19 Mar 2026 18:41:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773945675; cv=none; b=tmYp+JGgkgaaT7iG9ym0I0ks83r5n2FF3j9ykN5uNjs3ufZ71TO1JO8InsU+TimprMNfx4tMdHgT4E5q09QAMvxQqamnklYr1A4a+isNP2nO+zbYKlnG6GeQYeftdiD2ZTxXev+Jug8qujcTuEu/YyWEhqBDpXqfB/qLSJyCbEg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773945675; c=relaxed/simple; bh=ezG3pC99w4U2uwQ/yG5pLTV/NpoABjnTbl6EjBflYnw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HKNYygpe/Vo+bJNt7cgKcQyeLjhWbQR+LWQdp1tbQdejOB0D7Xgpc1kJfMaYL51IILCv7Wn41IJCKqnUe/vangSWCD5KwDuqEiaIq+vhwQa8Ue/DvJKxrirsU2XfNefGUkF2DqTQLqle0A2ol9a91DYmMi5p7KpwxZItOiGNL3Y= 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=e3YBlNPP; arc=none smtp.client-ip=209.85.210.43 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="e3YBlNPP" Received: by mail-ot1-f43.google.com with SMTP id 46e09a7af769-7d741f61ee5so1040000a34.1 for ; Thu, 19 Mar 2026 11:41:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773945670; x=1774550470; 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=wX6S1CdKc2mUwaozX73tCsBdgQ9rtIDSRhAEJ71WCy8=; b=e3YBlNPPJhBndwM7QhT4+/pIvEfTThLD9Kaz/rhgubMYCHO0CTApNCHL5iZBhvjEax ls+jMrI3ZcTgodf1ZwRhZJGu9d3A8VXSqKT8UAegFhlG7t9V/1bBQvfVTCPqiSwRLTiu BpQ52b6SAhsk7jvEf8iMfZRsbZG6S8MFXHmIegtvHxOgXMVvknfRfIcRIthb3B9lyzb8 fEhwJwi9xjUVTtSGfX6oBOOuPIwXwAOBBq2fhy27GwAx29SLdJm7HhfMdjeasQtQmp6b DpBUELMaW+feb6an/xsU/3W7Ed06XIMV5TQaA6ezebpHp+Ix4ZGztNJALnD76/rIhysZ sWIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773945670; x=1774550470; 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=wX6S1CdKc2mUwaozX73tCsBdgQ9rtIDSRhAEJ71WCy8=; b=h4hUDgdfbY4H/M59MTaCmwg1as58xJUhgU5tS7ZK5VEw3mlHwBG2Qv8mMcHcH6AAaW nlrwsASPydVMeVmGwPzAVEmWIH+brcRLOdmnVNOiE51GPmxts4w6g7MFo7+1NIGZx3y1 UjRXcX+4v4rYxxLUOMnZ7iitlqx48xH9xziG7fmHuHf6PhrpVhPsOl82mTZ+gqd3f6Yd ZJikF/0cCAKlTfRYC+f3SAfsabN9hUlVJ6FixJhooiHQ6T1vCBt/1NkCZPJ0MZNNUcGf /r56jnm1q29jSneq0cQI3GLxeWYOXiLtJGIA2YH8fWPqgGn6mm2FhwHGlxM1GGXe6GO5 5SKA== X-Forwarded-Encrypted: i=1; AJvYcCW+rBAPxdI1op+qQ662HnUcfgq3fCnn+YlR1Rsyf/Dof+w2Gd19yGG+KeXUrAK/tXlT6JdwDHJAqnWxkBc=@vger.kernel.org X-Gm-Message-State: AOJu0Yy737YjCtzt4HYwhkND5hLoAGIEYSsZrkcWNAhHzEgwVK7UlRSj lu6ZDABmobQhOJMwgRZOkrEy8aFQiZxNasyQlgwxTnZYJq/0Nfotqn5Z X-Gm-Gg: ATEYQzwNc/vdRYtElpxbRJl6H0CtzjSUWOm3/Io+lDbisfdFSeoXZCLl0h5tjmn7Hh2 PV3WcCGLsEdBepcLvFF68e2WOk2zZXv6fcX6/173CAUXjBdlBNU3boEOQmV621xXd1D9t/lsKW9 +avBsBZQ9MHnp2al4byXFVBjk1is1KvREdxvJBG/4gxP8RJO4GloIavdbD9huH6KdeCjrM1It7s Hed77muz+QSw13I6rQEzqWJtjblMZJSBgqQYEj/9RyF0Ipd64NqEUKe0Gcj5sUWKwpUzBzP84w6 sp6+1Okx50C7c94lQIVVsUW5F195vH+93sTD3FsFVoPCoMfZim+oA5zfYZ9qMcovP4xhrWRrtGI o9aL9kOerTgjgGFPi4WDjhmKHQe7F/yEE1hK9ZW+apu06exjBaWBY5yIS+PrVOUZo//B7LDYXKB 09ugQndy8h6Ri2QDftvk+sTPIe16cXBQK1EGXLjUfUuho7xrgB4q88S8dJmmwLAVVIb1xlmu107 sEfM71g4zQ= X-Received: by 2002:a05:6830:700f:b0:7c7:6043:dd8f with SMTP id 46e09a7af769-7d7eaedc687mr238381a34.15.1773945669849; Thu, 19 Mar 2026 11:41:09 -0700 (PDT) Received: from celestia.turtle.lan (static-23-234-115-121.cust.tzulo.com. [23.234.115.121]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-7d7eadcb757sm181486a34.15.2026.03.19.11.41.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2026 11:41:09 -0700 (PDT) From: Sam Edwards X-Google-Original-From: Sam Edwards To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: Russell King , Maxime Chevallier , Ovidiu Panait , Vladimir Oltean , Baruch Siach , Serge Semin , netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Sam Edwards , stable@vger.kernel.org Subject: [PATCH net v2 2/2] net: stmmac: Prevent indefinite RX stall on buffer exhaustion Date: Thu, 19 Mar 2026 11:40:31 -0700 Message-ID: <20260319184031.8596-3-CFSworks@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260319184031.8596-1-CFSworks@gmail.com> References: <20260319184031.8596-1-CFSworks@gmail.com> 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 stmmac driver handles interrupts in the usual NAPI way: an interrupt arrives, the NAPI instance is scheduled and interrupts are masked, and the actual work occurs in the NAPI polling function. Once no further work remains, interrupts are unmasked and the NAPI instance is put to sleep to await a future interrupt. In the receive case, the MAC only sends the interrupt when a DMA operation completes; thus the driver must make sure a usable RX DMA descriptor exists before expecting a future interrupt. The main receive loop in stmmac_rx() exits under one of 3 conditions: 1) It encounters a DMA descriptor with OWN=3D1, indicating that no further pending data exists. The MAC will use this descriptor for the next RX DMA operation, so the driver can expect a future interrupt. 2) It exhausts the NAPI budget. In this case, the driver doesn't know whether the MAC has any usable DMA descriptors. But when the driver consumes its full budget, that signals NAPI to keep polling, so the question is moot. 3) It runs out of (non-dirty) descriptors in the RX ring. In this case, the MAC will only have a usable descriptor if stmmac_rx_refill() succeeds (at least partially). Currently, stmmac_rx() lacks any check against scenario #3 and stmmac_rx_refill() failing: it will stop NAPI polling and unmask interrupts to await an interrupt that will never arrive, stalling the receive pipeline indefinitely. Fix this by checking if stmmac_rx_dirty() returns its maximal value, returning the full budget (which tells NAPI to keep polling) if so. Fixes: 47dd7a540b8a ("net: add support for STMicroelectronics Ethernet cont= rollers.") Cc: stable@vger.kernel.org Signed-off-by: Sam Edwards --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/ne= t/ethernet/stmicro/stmmac/stmmac_main.c index f98b070073c0..05d3c548ce28 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -5604,6 +5604,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int li= mit, u32 queue) unsigned int desc_size; struct sk_buff *skb =3D NULL; struct stmmac_xdp_buff ctx; + int budget =3D limit; int xdp_status =3D 0; int bufsz; =20 @@ -5870,6 +5871,12 @@ static int stmmac_rx(struct stmmac_priv *priv, int l= imit, u32 queue) priv->xstats.rx_dropped +=3D rx_dropped; priv->xstats.rx_errors +=3D rx_errors; =20 + /* If the RX queue is completely dirty, we can't expect a future + * interrupt; tell NAPI to keep polling. + */ + if (unlikely(stmmac_rx_dirty(priv, queue) =3D=3D priv->dma_conf.dma_rx_si= ze - 1)) + return budget; + return count; } =20 --=20 2.52.0