From nobody Thu Apr 2 12:25:52 2026 Received: from mail-dy1-f170.google.com (mail-dy1-f170.google.com [74.125.82.170]) (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 DA274345752 for ; Sat, 28 Mar 2026 19:12:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774725182; cv=none; b=PgEPCibysPEjj/o7UKKy/uN42kPRR2CyGxvA8KwidKT8OFiLfIfCnk60Dsrui4pxvql4+mMoJwlVmNDBbYuq13a6cXILoS+SHZYBivreIQ3YPARPwKyb+jsJeXgihnAH4IQvCCZn8C40dt0+EfreXqvSPh3HqoloCelr2fmBHrA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774725182; c=relaxed/simple; bh=Un+tjKghOnSOGQJqIv2n+A/mJ2xTSQ27PpNpWvuI/2I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=laXBORQe16RvLQ5SRJ38F6N00sAN8gSPtyArnZYhNBDqlXAXqR7u/EdxTnDsQmAY0KZh7xh35AAZbYt7SCZoTDu/J1bi10XjJ4gdGTPxu5BK0u5++O7CJ/sAshMp9dOeEhv47uWTBUAkj+dSR+ZEpsXlrJGqgfefRJCL9rCUu5g= 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=cs3pZk8P; arc=none smtp.client-ip=74.125.82.170 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="cs3pZk8P" Received: by mail-dy1-f170.google.com with SMTP id 5a478bee46e88-2c18af885c0so2539819eec.0 for ; Sat, 28 Mar 2026 12:12:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774725179; x=1775329979; 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=cs3pZk8P3fzlPj+zJ3uyS0v1ZtLqoutbwiz2kIZeG9rct5Bvz0f3vJ1z3dU4TJAEF4 YfFUpS1gmOrcq43E2R2FtuUAZQC6xUKVKgLXMaEuuRRiYqTp19X+YNiI4nFWOfyeWvM3 IOHaCmObeKhMovV70RDkX5psvDvYR2ez99NOY4tAg9epafGV0XUtE5I2yTqOPbfbWsN9 gvPfsQ+Fb4plvPphyEY0+49C4C5F88CbVIYlAA9TU7Vgw/tXg98JCafxS8sBxiJCO1Cp YsjqITDi3I6xQcQvqrAW7kbHe9Km58ESRpkMMrE9X5qFM3sv6oezkKMKwOu5ORRflwFF p/Bw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774725179; x=1775329979; 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=KMgWdxEMIodJxaEAF7mq/8ABMQevELpAvvM2j9Vai3+xaLYgv2iYKbdnorvGTjVVuF ef3xFm2J3Op5Xz80Mf3BK7eoGlYPlCV/DLQEboKTYH5MS5Bqy5tAxZttdNUTZ8ZXCzeN uwB9d7UWmLqOXa7OmU2oG4v9MWvKrUcb0yz1NqT2sTYP6LphhBnLwxiP1ALtvj8m1KRH lyxIB/ElkNDdb/9JXSKqPNiw2ogmjHAVD9SeKrpHJbV7WSnGZiM9NiBEa779PXWfHnUp XjeaVAXcFaqW+tU6kbkbohV2vhOeC1exLKvQlcdPLwlSA3O2lBNflQDMq45gRu2LdT8N jK3w== X-Forwarded-Encrypted: i=1; AJvYcCWCwhzfc6N402+wlaqsuEuYq6py09v5VuwNpnkazxvz9cI+AzcJGuVEu+KQ5ijsTqoQ6JLXhN1NpOGNnHI=@vger.kernel.org X-Gm-Message-State: AOJu0YyBZg6mvzNHUoy0IttGMluM/InwELFaH5nkrFPOTz8LXAb9qF0w WComRRrd6PbnhKDpIx30d8Mb+DhrDJTMnc96B88WX06gD60SAybsPuv9 X-Gm-Gg: ATEYQzzL8YqycaMkxPd9ySVfx/pTu8bFZtWRF+SK6wr9fhm1CYQnNxt+alrcVEZ/wcS WELQMl5QORnwxgtDIHU7f5FaPqArk1mdJl9GKvR4DLCuP024N3HwauSiA0qwq+VB5WaCuxIiNLc hj6hRFQ4YlcR+ybOx0Mvz+EExQ0DDQZHEzE7IqIG+TPW5UgiQkXxi5ZE0w65EYPCvxANYYxeNMW K0IbfS/qk9xsQnFIgO9niWl95q7RNdGv9jPrArX9f+16h6f1cxMbAZonChgWETPae5Bb1b5tZTX 0VJmR624PXcrV2+mXkp63X6DeDKZWhRbLpjG6NGP2My4QbxBJVxQxj21sKveplTZcOw6/5UeoRW w2yd0dNUCn81NOK1MebA+Wzm9iuE6OJeDtDJu3FOmLOXpJq5IwcIJnP69kVXv6cdMYfhhaWd3aC z35kUUeKRKzV2tSZiecBNxL6l3Vy247eqRskk3OxTKvqUE9Cf9LM/GSIxU X-Received: by 2002:a05:7300:7fa4:b0:2c1:67e1:61c4 with SMTP id 5a478bee46e88-2c185ce8740mr4319411eec.5.1774725178830; Sat, 28 Mar 2026 12:12:58 -0700 (PDT) Received: from localhost (static-23-234-93-211.cust.tzulo.com. [23.234.93.211]) by smtp.gmail.com with UTF8SMTPSA id 5a478bee46e88-2c3c68b2721sm2508384eec.14.2026.03.28.12.12.56 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 28 Mar 2026 12:12:58 -0700 (PDT) From: Sam Edwards X-Google-Original-From: Sam Edwards To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: Maxime Coquelin , Alexandre Torgue , "Russell King (Oracle)" , Maxime Chevallier , Ovidiu Panait , Vladimir Oltean , Baruch Siach , Serge Semin , Giuseppe Cavallaro , netdev@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Sam Edwards , stable@vger.kernel.org Subject: [PATCH v3 1/2] net: stmmac: Prevent NULL deref when RX memory exhausted Date: Sat, 28 Mar 2026 12:12:32 -0700 Message-ID: <20260328191233.519950-2-CFSworks@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260328191233.519950-1-CFSworks@gmail.com> References: <20260328191233.519950-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 Thu Apr 2 12:25:52 2026 Received: from mail-dl1-f41.google.com (mail-dl1-f41.google.com [74.125.82.41]) (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 B65C6346A01 for ; Sat, 28 Mar 2026 19:13:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774725185; cv=none; b=TA27O+fjL8uUV20MIYAZPTT4JOv9+WjqaGimKGNzSRpb8PiD9+69eQdRrlKpo6wN5BzOLWYqzWKgcUeNSQoJZL736H3Djwic6Z2i1NJ5WPQoVykcs8+kKOiKiZnS6Z1JPqxOGFq5Le6lfKKsOUJ0gqueH1CFT4Dk6g+H+ASp1oA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774725185; c=relaxed/simple; bh=qGFTzlpUUEI4pKdSdaSVMTnjSAfvQHYO8xeTqhyGGNE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pranHOw+ExaTlsRQquTaFmvfrBgDv1hLiLqzQ+/YLAVeaYxa1k5xnp7azwZ5hUhqG3h67L5lIxNHM1KkON1CDt/qhns4N50cyhPPCchkWSMyPhWf8gmv6sLoebaTWHrt/6HOgVkQzim8/HWbg1Qo5Gv4gzY9nrmaLOmWarAGNpc= 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=bq635Hk0; arc=none smtp.client-ip=74.125.82.41 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="bq635Hk0" Received: by mail-dl1-f41.google.com with SMTP id a92af1059eb24-12732e6a123so562302c88.1 for ; Sat, 28 Mar 2026 12:13:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1774725183; x=1775329983; 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=nV0vTDjXno/BRjs9UsVyAooL1Z9SQRTeEW/NqAyKUfY=; b=bq635Hk08G52PmB4wUjBX1P9YGeKaD4Gl3lrxEBOaE5c9Gg9KGzd/w8GhZ8T+ugp2p j0mBWYH+5bnAxRcuKqaXM9h2LD+N1xEh0y+WamdrA3mxlSOibdl880GmCOguQ0g7uVYD k+Oo1eU6QKRA0Ktch/xVyjsCBAMj1PqMdOkET5HWAwAaNgMwCj66xvPrsqLyKu8ZkiML sPQtFDYwMnF/9OsWHQ8gb0eaIiL9rSx1ozqTzxAFYqaxTJWpe686GOG0qBIJ8qSm8Fff I/he+SDCkRGZ0WfaK5w/JdvQik/xmoCMZ/9hG6yACD7bXknPHnF6ykqNEtQC/JWl+6te ScHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774725183; x=1775329983; 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=nV0vTDjXno/BRjs9UsVyAooL1Z9SQRTeEW/NqAyKUfY=; b=N7Huo7+isyaOkNsXrKGBLFUy0N5L8/1/65IeBGH0fAjwHJpqoR7eLAjAPPaaxZ5kyK hotbDOt43r0rBnz5YK18m9IB+0p2YHio/Pdk1cgVVYBR7jcH/PDWF1ZJczJCYwi49vvn 91uj+oEKC0Lu+XzKIer5qddTNC9ZI0qhN96WySMC+XkeA6WbbJ1iM0EWL1vKuRKBPWce SHpU+8ipi4Y5BvKuM3aRuRkQthR21O61+6rZK1ev0GosEzjjgWQT4bbgJ4+Jmr1amGgY WIlWtQmMBazXdgxxyYwToP6caYC046geutL4JDH/19p49ND8hgu+JX9U3uGGMH1MBBAi g15w== X-Forwarded-Encrypted: i=1; AJvYcCXWipJ9QGOHSqCsOBfAoPhmfr7xc9++ZP7FZEir5fdXBKCUNFdrmM6ppA/2UtaBGk1XWEL8CDTBwFQJiuE=@vger.kernel.org X-Gm-Message-State: AOJu0YyCSOcDuwuA8cei71ouwp41NiKxFcb90ODbH4/I2BL+SrQ/Hmri N1A7aaRJPfq6+IBO1aQtCMxCTvZI/CUbQK91VwxtwNbaZRPEIuptEs9V X-Gm-Gg: ATEYQzxXr6Xg+fgF+CKejqGJYBZpvj7faPA39QzCB5FRI0UvnMKreygTEQL+ejgjcVB 5aP1RIHL5najM2Q/nzJDyWJvXLX52j1YyofklL0AMEjjghR6e1TKCIm64sYDW1RZWoXFAkDt4Zo 6y3fTbiI/PjgfXNHOCuPxVrdbqI5uGqHE/3xiQK1PQVapHWMuRUDs8kajJWm/dPMc109kJqe92l HoWJtCXlQ8xLd9IZSpWnSuwea1Hn7Alp18DpwVAmJKEq/EnGEhjqSUvxB+d9GbyjmtlcZcGOX8+ e2cs4CXL9XgYBS3rZuJ/dyge+3o0KGKHTWwDqcXgybklhquo9bvOo8y2e0ZVNx1M5XZObkFI9CC M+YuFvQK8Q8DXv8TAdbqUlf1Uk7bwxV/B08Wnkd8BxPl9f80yPQuZeo3b0v7vJw8Pn2EKUE5GgS uGvHL9Ss11nt0lwVmwZ8vYLzPxKE92Hs57pc6Ey3kxWips4wdu6AWaJHXQ X-Received: by 2002:a05:7022:f102:b0:11d:fd26:234e with SMTP id a92af1059eb24-12ab28cdebbmr4140608c88.16.1774725182824; Sat, 28 Mar 2026 12:13:02 -0700 (PDT) Received: from localhost (static-23-234-93-211.cust.tzulo.com. [23.234.93.211]) by smtp.gmail.com with UTF8SMTPSA id a92af1059eb24-12abbe21787sm2071517c88.11.2026.03.28.12.13.00 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Sat, 28 Mar 2026 12:13:02 -0700 (PDT) From: Sam Edwards X-Google-Original-From: Sam Edwards To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni Cc: Maxime Coquelin , Alexandre Torgue , "Russell King (Oracle)" , Maxime Chevallier , Ovidiu Panait , Vladimir Oltean , Baruch Siach , Serge Semin , Giuseppe Cavallaro , netdev@vger.kernel.org, linux-stm32@st-md-mailman.stormreply.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Sam Edwards , stable@vger.kernel.org Subject: [PATCH v3 2/2] net: stmmac: Prevent indefinite RX stall on buffer exhaustion Date: Sat, 28 Mar 2026 12:12:33 -0700 Message-ID: <20260328191233.519950-3-CFSworks@gmail.com> X-Mailer: git-send-email 2.52.0 In-Reply-To: <20260328191233.519950-1-CFSworks@gmail.com> References: <20260328191233.519950-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 stmmac_rx_dirty(): it will return 0 if stmmac_rx_refill() fully succeeded and we can safely await an interrupt. Any nonzero value means some allocations failed, in which case we risk dropping frames if a large traffic burst exhausts the surviving non-dirties. Therefore, simply return the full budget (to keep polling) until all allocations succeed. 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 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/ne= t/ethernet/stmicro/stmmac/stmmac_main.c index f98b070073c0..81f764352f3d 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,10 @@ 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 stmmac_rx_refill() failed, keep trying until it doesn't. */ + if (unlikely(stmmac_rx_dirty(priv, queue) > 0)) + return budget; + return count; } =20 --=20 2.52.0