]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
phy: lynx-28g: reject probing on devices with unsupported OF nodes
authorVladimir Oltean <vladimir.oltean@nxp.com>
Wed, 10 Jun 2026 15:19:38 +0000 (18:19 +0300)
committerVinod Koul <vkoul@kernel.org>
Thu, 11 Jun 2026 07:09:46 +0000 (12:39 +0530)
It is possible to bind the lynx-28g driver to an arbitrary device with
an OF node, using the driver_override mechanism that is available for
the platform bus, and trigger a crash this way:

$ echo 1ea0000.serdes > /sys/bus/platform/drivers/lynx-10g/unbind
$ echo lynx-28g > /sys/bus/platform/devices/1ea0000.serdes/driver_override
$ echo 1ea0000.serdes > /sys/bus/platform/drivers/lynx-28g/bind
Internal error: Oops: 0000000096000004 [#1]  SMP
Hardware name: LS1028A RDB Board (DT)
pc : lynx_probe+0x118/0x4fc
lr : lynx_probe+0x110/0x4fc
Call trace:
 lynx_probe+0x118/0x4fc (P)
 lynx_28g_probe+0x54/0x7c
 platform_probe+0x68/0xa4
 really_probe+0x14c/0x2ec
 __driver_probe_device+0xc8/0x170
 device_driver_attach+0x58/0xa8
 bind_store+0xd8/0x118
 drv_attr_store+0x24/0x38

The crash is caused by the fact that of_device_get_match_data() returns
NULL (the bound device has a different compatible string) and this is
not checked.

There was a previous attempt to avoid this in commit c9d80e861034 ("phy:
lynx-28g: require an OF node to probe"), but the mechanism was not fully
understood and it only covered the case where the driver was bound to a
device with no OF node.

The issue was found during Sashiko review. Elevated privilege is
required to override the driver for a device, so the real life impact of
the issue should not be very high.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Link: https://patch.msgid.link/20260610151952.2141019-3-vladimir.oltean@nxp.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/phy/freescale/phy-fsl-lynx-28g.c

index cacc128dc96a161c3ff79a398e5d4637bf29e05a..1f5cb02931f5653a8e17a0cba6104c07e89430ed 100644 (file)
@@ -1477,6 +1477,9 @@ static int lynx_28g_probe(struct platform_device *pdev)
 
        priv->dev = dev;
        priv->info = of_device_get_match_data(dev);
+       if (!priv->info)
+               return -ENODEV;
+
        dev_set_drvdata(dev, priv);
        spin_lock_init(&priv->pcc_lock);
        INIT_DELAYED_WORK(&priv->cdr_check, lynx_28g_cdr_lock_check);