[PATCH] drm/bridge: imx8qxp-pxl2dpi: avoid of_node_put() on ERR_PTR()
Frank Li
Frank.li at nxp.com
Sun Apr 19 18:56:26 PDT 2026
On Sun, Apr 19, 2026 at 08:21:34PM +0800, Guangshuo Li wrote:
> imx8qxp_pxl2dpi_get_available_ep_from_port() may return ERR_PTR(-ENODEV)
> or ERR_PTR(-EINVAL). imx8qxp_pxl2dpi_find_next_bridge() stores that
> value in a __free(device_node) variable and then immediately checks
> IS_ERR(ep).
>
> On the error path, returning from the function triggers the cleanup
> handler for __free(device_node). Since the device_node cleanup helper
> only checks for NULL before calling of_node_put(), this results in
> of_node_put(ERR_PTR(...)), which may lead to an invalid kobject_put()
Please fix
DEFINE_FREE(device_node, struct device_node *, if (_T) of_node_put(_T))
If (!IS_ERR(_T))
Frank
> dereference and crash the kernel.
>
> Fix it by avoiding __free(device_node) for the endpoint pointer and
> releasing it explicitly after obtaining the remote port parent.
>
> This issue was found by a custom static analysis tool.
>
> Fixes: ceea3f7806a10 ("drm/bridge: imx8qxp-pxl2dpi: simplify put of device_node pointers")
> Cc: stable at vger.kernel.org
> Signed-off-by: Guangshuo Li <lgs201920130244 at gmail.com>
> ---
> drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c | 7 +++++--
> 1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c
> index 441fd32dc91c..3610ca94a8e6 100644
> --- a/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c
> +++ b/drivers/gpu/drm/bridge/imx/imx8qxp-pxl2dpi.c
> @@ -264,12 +264,15 @@ imx8qxp_pxl2dpi_get_available_ep_from_port(struct imx8qxp_pxl2dpi *p2d,
>
> static int imx8qxp_pxl2dpi_find_next_bridge(struct imx8qxp_pxl2dpi *p2d)
> {
> - struct device_node *ep __free(device_node) =
> - imx8qxp_pxl2dpi_get_available_ep_from_port(p2d, 1);
> + struct device_node *ep;
> +
> + ep = imx8qxp_pxl2dpi_get_available_ep_from_port(p2d, 1);
> if (IS_ERR(ep))
> return PTR_ERR(ep);
>
> struct device_node *remote __free(device_node) = of_graph_get_remote_port_parent(ep);
> + of_node_put(ep);
> +
> if (!remote || !of_device_is_available(remote)) {
> DRM_DEV_ERROR(p2d->dev, "no available remote\n");
> return -ENODEV;
> --
> 2.43.0
>
More information about the linux-arm-kernel
mailing list