lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20250826-lynx-28g-nullptr-v1-1-e4de0098f822@solid-run.com>
Date: Tue, 26 Aug 2025 20:32:03 +0200
From: Josua Mayer <josua@...id-run.com>
To: Ioana Ciornei <ioana.ciornei@....com>, Vinod Koul <vkoul@...nel.org>,
 Kishon Vijay Abraham I <kishon@...nel.org>
Cc: Yazan Shhady <yazan.shhady@...id-run.com>,
 Jon Nettleton <jon@...id-run.com>, netdev@...r.kernel.org,
 linux-phy@...ts.infradead.org, linux-kernel@...r.kernel.org,
 Josua Mayer <josua@...id-run.com>
Subject: [PATCH] phy: lynx-28g: check return value when calling
 lynx_28g_pll_get

The lynx_28g_pll_get function may return NULL when called with an
unsupported submode argument.

This function is only called from the lynx_28g_lane_set_{10gbaser,sgmii}
functions, and lynx_28g_set_mode checks available modes before setting a
protocol.

NXP vendor kernel based on v6.6.52 however is missing any checks and
connecting a 2.5/5gbase-t ethernet phy can cause null pointer
dereference [1].

Check return value at every invocation and abort in the unlikely error
case. Further print a warning message the first time lynx_28g_pll_get
returns null, to catch this case should it occur after future changes.

[1]
[  127.019924] fsl_dpaa2_eth dpni.4 eth5: dpmac_set_protocol(2500base-x) = -ENOTSUPP
[  127.027451] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000014
[  127.036245] Mem abort info:
[  127.039044]   ESR = 0x0000000096000004
[  127.042794]   EC = 0x25: DABT (current EL), IL = 32 bits
[  127.048107]   SET = 0, FnV = 0
[  127.051161]   EA = 0, S1PTW = 0
[  127.054301]   FSC = 0x04: level 0 translation fault
[  127.059179] Data abort info:
[  127.062059]   ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[  127.067547]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[  127.072596]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[  127.077907] user pgtable: 4k pages, 48-bit VAs, pgdp=00000020816c9000
[  127.084344] [0000000000000014] pgd=0000000000000000, p4d=0000000000000000
[  127.091133] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
[  127.097390] Modules linked in: cfg80211 rfkill fsl_jr_uio caam_jr dpaa2_caam caamkeyblob_desc crypto_engine caamhash_desc onboard_usb_hub caamalg_desc crct10dif_ce libdes caam error at24 rtc_ds1307 rtc_fsl_ftm_alarm nvmem_layerscape_sfp layerscape_edac_mod dm_mod nfnetlink ip_tables
[  127.122436] CPU: 5 PID: 96 Comm: kworker/u35:0 Not tainted 6.6.52-g3578ef896722 #10
[  127.130083] Hardware name: SolidRun LX2162A Clearfog (DT)
[  127.135470] Workqueue: events_power_efficient phylink_resolve
[  127.141219] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  127.148170] pc : lynx_28g_set_lane_mode+0x300/0x818
[  127.153041] lr : lynx_28g_set_lane_mode+0x2fc/0x818
[  127.157909] sp : ffff8000806f3b80
[  127.161212] x29: ffff8000806f3b80 x28: 0000000000000000 x27: 0000000000000000
[  127.168340] x26: ffff29d6c11f3098 x25: 0000000000000000 x24: 0000000000000000
[  127.175467] x23: ffff29d6c11f31f0 x22: ffff29d6c11f3080 x21: 0000000000000001
[  127.182595] x20: ffff29d6c11f4c00 x19: 0000000000000000 x18: 0000000000000006
[  127.189722] x17: 4f4e452d203d2029 x16: 782d657361623030 x15: 3532286c6f636f74
[  127.196849] x14: 6f72705f7465735f x13: ffffd7a8ff991cc0 x12: 0000000000000acb
[  127.203976] x11: 0000000000000399 x10: ffffd7a8ff9e9cc0 x9 : 0000000000000000
[  127.211104] x8 : 0000000000000000 x7 : 0000000000000000 x6 : ffff29d6c11f3080
[  127.218231] x5 : 0000000000000000 x4 : 0000000040800030 x3 : 000000000000034c
[  127.225358] x2 : ffff29d6c11f3080 x1 : 000000000000034c x0 : 0000000000000000
[  127.232486] Call trace:
[  127.234921]  lynx_28g_set_lane_mode+0x300/0x818
[  127.239443]  lynx_28g_set_mode+0x12c/0x148
[  127.243529]  phy_set_mode_ext+0x5c/0xa8
[  127.247356]  lynx_pcs_config+0x64/0x294
[  127.251184]  phylink_major_config+0x184/0x49c
[  127.255532]  phylink_resolve+0x2a0/0x5d8
[  127.259446]  process_one_work+0x138/0x248
[  127.263448]  worker_thread+0x320/0x438
[  127.267187]  kthread+0x114/0x118
[  127.270406]  ret_from_fork+0x10/0x20
[  127.273973] Code: 2a1303e1 aa0603e0 97fffd3b aa0003e5 (b9401400)
[  127.280055] ---[ end trace 0000000000000000 ]---

Signed-off-by: Josua Mayer <josua@...id-run.com>
---
 drivers/phy/freescale/phy-fsl-lynx-28g.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/phy/freescale/phy-fsl-lynx-28g.c b/drivers/phy/freescale/phy-fsl-lynx-28g.c
index f7994e8983c8ecf52148ba4024684c0c452fc5a1..c20d2636c5e9c079d9178fdfa9030dd8041ce0ba 100644
--- a/drivers/phy/freescale/phy-fsl-lynx-28g.c
+++ b/drivers/phy/freescale/phy-fsl-lynx-28g.c
@@ -188,6 +188,10 @@ static struct lynx_28g_pll *lynx_28g_pll_get(struct lynx_28g_priv *priv,
 			return pll;
 	}
 
+	/* no pll supports requested mode, either caller forgot to check
+	 * lynx_28g_supports_lane_mode, or this is a bug.
+	 */
+	dev_WARN_ONCE(priv->dev, 1, "no pll for interface %s\n", phy_modes(intf));
 	return NULL;
 }
 
@@ -276,8 +280,12 @@ static void lynx_28g_lane_set_sgmii(struct lynx_28g_lane *lane)
 	lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_SGMII, PROTO_SEL_MSK);
 	lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_10_BIT, IF_WIDTH_MSK);
 
-	/* Switch to the PLL that works with this interface type */
+	/* Find the PLL that works with this interface type */
 	pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_SGMII);
+	if (unlikely(pll == NULL))
+		return;
+
+	/* Switch to the PLL that works with this interface type */
 	lynx_28g_lane_set_pll(lane, pll);
 
 	/* Choose the portion of clock net to be used on this lane */
@@ -312,8 +320,12 @@ static void lynx_28g_lane_set_10gbaser(struct lynx_28g_lane *lane)
 	lynx_28g_lane_rmw(lane, LNaGCR0, PROTO_SEL_XFI, PROTO_SEL_MSK);
 	lynx_28g_lane_rmw(lane, LNaGCR0, IF_WIDTH_20_BIT, IF_WIDTH_MSK);
 
-	/* Switch to the PLL that works with this interface type */
+	/* Find the PLL that works with this interface type */
 	pll = lynx_28g_pll_get(priv, PHY_INTERFACE_MODE_10GBASER);
+	if (unlikely(pll == NULL))
+		return;
+
+	/* Switch to the PLL that works with this interface type */
 	lynx_28g_lane_set_pll(lane, pll);
 
 	/* Choose the portion of clock net to be used on this lane */

---
base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
change-id: 20250826-lynx-28g-nullptr-15de2b5b1eb6

Best regards,
-- 
Josua Mayer <josua@...id-run.com>


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ