All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Luca Ceresoli" <luca.ceresoli@bootlin.com>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 06/11] drm/bridge: tc358767: don't create a panel_bridge
Date: Fri, 14 Aug 2026 14:17:55 +0000	[thread overview]
Message-ID: <20260814141756.713AA1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260814-drm-bridge-every-panel-v1-6-19cd5277cc8d@bootlin.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [Critical] Refcount underflow and use-after-free for bridges acquired in DPI mode.
- [High] Resource leak of the bridge reference on probe error paths.

Pre-existing issues:
- [High] Undefined behavior due to a negative bitshift when evaluating `tc->hpd_pin`.
--

--- Patch [6]: [PATCH 06/11] drm/bridge: tc358767: don't create a panel_bridge ---
commit ae8aef2f483ffa927af25a2f1ac42b0420349ca8
Author: Luca Ceresoli <luca.ceresoli@bootlin.com>

drm/bridge: tc358767: don't create a panel_bridge

This commit prevents creating a second panel_bridge by retrieving the
already-existing one using of_drm_get_bridge_by_endpoint() for eDP
endpoints. It updates tc_remove() to release the reference.

> diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c
> index e3a57f8228dae..2fef5d9fa361d 100644
> --- a/drivers/gpu/drm/bridge/tc358767.c
> +++ b/drivers/gpu/drm/bridge/tc358767.c
> @@ -2347,24 +2347,15 @@ static int tc_probe_dpi_bridge_endpoint(struct tc_data *tc)
>  static int tc_probe_edp_bridge_endpoint(struct tc_data *tc)
>  {
>  	struct device *dev = tc->dev;
> -	struct drm_panel *panel;
> -	int ret;
> +	struct drm_bridge *bridge;
>  
>  	/* port@2 is the output port */
> -	ret = drm_of_find_panel_or_bridge(dev->of_node, 2, 0, &panel, NULL);
> -	if (ret && ret != -ENODEV)
> -		return dev_err_probe(dev, ret,
> -				     "Could not find DSI panel or bridge\n");
> +	bridge = of_drm_get_bridge_by_endpoint(dev->of_node, 2, 0);
> +	if (IS_ERR(bridge) && PTR_ERR(bridge) != -ENODEV)
> +		return dev_err_probe(dev, PTR_ERR(bridge), "Could not find DSI bridge\n");
>  
> -	if (panel) {
> -		struct drm_bridge *panel_bridge;
> -
> -		panel_bridge = devm_drm_panel_bridge_add(dev, panel);
> -		drm_panel_put(panel);
> -		if (IS_ERR(panel_bridge))
> -			return PTR_ERR(panel_bridge);
> -
> -		tc->panel_bridge = panel_bridge;
> +	if (!IS_ERR(bridge)) {
> +		tc->panel_bridge = bridge;
>  		tc->bridge.type = DRM_MODE_CONNECTOR_eDP;
>  	} else {
>  		tc->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
>  	}

[Severity: High]
If of_drm_get_bridge_by_endpoint() successfully returns a refcounted bridge
pointer, it is stored in tc->panel_bridge. If any subsequent initialization
step in tc_probe() fails, it appears to return directly without cleaning up
the bridge reference:

tc_probe() {
    ...
    tc_probe_edp_bridge_endpoint(tc);
    ...
    tc->refclk = devm_clk_get_enabled(dev, "ref");
    if (IS_ERR(tc->refclk))
        return dev_err_probe(dev, PTR_ERR(tc->refclk),
                             "Failed to get and enable the ref clk\n");
    ...
}

Could this cause a resource leak on probe error paths?

[Severity: High]
This is a pre-existing issue, but does evaluating tc->hpd_pin here lead to a
negative bitshift later?

Due to initialization order, tc_data is zero-allocated, meaning tc->hpd_pin
is 0 when checked in tc_probe_edp_bridge_endpoint():

    if (tc->hpd_pin >= 0)
        tc->bridge.ops |= DRM_BRIDGE_OP_DETECT;

Later in tc_probe(), if the DT property is absent, tc->hpd_pin is assigned
-ENODEV (-19).

When the DRM core periodically polls the connector, it calls
tc_bridge_detect(), which executes:

    conn = val & BIT(tc->hpd_pin);

Does this lead to undefined behavior by evaluating BIT(-19)?

[ ... ]

> @@ -2609,6 +2600,7 @@ static void tc_remove(struct i2c_client *client)
>  {
>  	struct tc_data *tc = i2c_get_clientdata(client);
>  
> +	drm_bridge_put(tc->panel_bridge);
>  	drm_bridge_remove(&tc->bridge);
>  }

[Severity: Critical]
Does this unconditional drm_bridge_put() cause a double-free for bridges
acquired in DPI mode?

When operating in DPI mode, tc_probe_dpi_bridge_endpoint() is called instead,
which assigns tc->panel_bridge to a devm-managed bridge:

tc_probe_dpi_bridge_endpoint() {
    ...
    bridge = devm_drm_panel_bridge_add(dev, panel);
    ...
    tc->panel_bridge = bridge;
}

When the device unbinds, tc_remove() drops a reference it does not own. For
the devm-managed bridge, this prematurely drops its refcount to 0, freeing
the bridge immediately. Later, the devres framework will attempt to clean up
the same bridge, causing a double-free.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260814-drm-bridge-every-panel-v1-0-19cd5277cc8d@bootlin.com?part=6

  reply	other threads:[~2026-08-14 14:17 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-14 14:05 [PATCH 00/11] drm/panel: add a panel_bridge to every panel Luca Ceresoli
2026-08-14 14:05 ` [PATCH 01/11] drm: of: drm_of_find_panel_or_bridge: simplify freeing the remote node pointer Luca Ceresoli
2026-08-14 14:05 ` [PATCH 02/11] drm: of: drm_of_find_panel_or_bridge: simplify error return paths Luca Ceresoli
2026-08-14 14:05 ` [PATCH 03/11] drm: of: drm_of_find_panel_or_bridge: prioritize the bridge, not the panel Luca Ceresoli
2026-08-14 14:20   ` sashiko-bot
2026-08-14 14:05 ` [PATCH 04/11] drm/panel: merge the drm_kms_helper module into the drm module Luca Ceresoli
2026-08-14 14:13   ` sashiko-bot
2026-08-14 14:05 ` [PATCH 05/11] drm/bridge: panel: add a panel_bridge to every panel Luca Ceresoli
2026-08-14 14:25   ` sashiko-bot
2026-08-14 14:05 ` [PATCH 06/11] drm/bridge: tc358767: don't create a panel_bridge Luca Ceresoli
2026-08-14 14:17   ` sashiko-bot [this message]
2026-08-14 14:05 ` [PATCH 07/11] drm/bridge: waveshare-dsi: " Luca Ceresoli
2026-08-14 14:05 ` [PATCH 08/11] drm/mcde: dsi: simplify device_node management using scoped for_each variant Luca Ceresoli
2026-08-14 14:19   ` sashiko-bot
2026-08-14 14:05 ` [PATCH 09/11] drm/mcde: dsi: don't create a panel_bridge Luca Ceresoli
2026-08-14 14:24   ` sashiko-bot
2026-08-14 14:05 ` [PATCH 10/11] drm/bridge: fsl-ldb: " Luca Ceresoli
2026-08-14 14:18   ` sashiko-bot
2026-08-14 14:05 ` [PATCH 11/11] drm/bridge: samsung-dsim: " Luca Ceresoli
2026-08-14 14:23   ` sashiko-bot
2026-08-14 14:13 ` [PATCH 00/11] drm/panel: add a panel_bridge to every panel Luca Ceresoli

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260814141756.713AA1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=luca.ceresoli@bootlin.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.