Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
to consider:
- [High] Use-after-free of `ctx->dsi` in the deferred work item during device 
unbind due to incorrect devres registration order.
--

commit f4afb8a9dbec6141c1ce6b1a75c1128b1885dc29
Author: Yi Zhang <[email protected]>

drm/bridge: add support for lontium lt9211c bridge

This commit extends the existing lontium-lt9211 driver to support the
LT9211C variant. It adds LT9211C-specific regmap support, initialization
sequences, and schedules a work item to handle RX auto-detection once a
DSI stream is active.

> diff --git a/drivers/gpu/drm/bridge/lontium-lt9211.c 
> b/drivers/gpu/drm/bridge/lontium-lt9211.c
> --- a/drivers/gpu/drm/bridge/lontium-lt9211.c
> +++ b/drivers/gpu/drm/bridge/lontium-lt9211.c

[ ... ]

> @@ -454,6 +552,656 @@ static int lt9211_configure_tx(struct lt9211 *ctx, bool 
> jeida,
>       return 0;
>  }
>  
> +static int lt9211c_configure_rx(struct lt9211 *ctx)
> +{
> +     unsigned int pval;
> +
> +     const struct reg_sequence lt9211c_rx_phy_seq[] = {
> +             { REG_DSI_LANE, REG_DSI_LANE_COUNT(ctx->dsi->lanes) },

[Severity: High]
Does this code dereference a freed pointer during driver unbind?

When the device is unbound, the workqueue is destroyed, which flushes any
pending work. If the work item executes here, it dereferences ctx->dsi,
but ctx->dsi might have already been freed due to the devres teardown order
configured in lt9211_probe().

[ ... ]

> @@ -748,45 +1516,48 @@ static int lt9211_probe(struct i2c_client *client)
>       if (ret)
>               return ret;
>  
> -     ctx->regmap = devm_regmap_init_i2c(client, &lt9211_regmap_config);
> +     ctx->chip_data = i2c_get_match_data(client);
> +     if (!ctx->chip_data)
> +             return -ENODEV;
> +
> +     ctx->regmap = devm_regmap_init_i2c(client, 
> ctx->chip_data->regmap_config);
>       if (IS_ERR(ctx->regmap))
>               return PTR_ERR(ctx->regmap);
>  
> -     dev_set_drvdata(dev, ctx);
> -     i2c_set_clientdata(client, ctx);
> +     if (ctx->chip_data->chip_type == LT9211C) {
> +             ctx->wq = create_workqueue("lt9211_work");
> +             if (!ctx->wq)
> +                     return -ENOMEM;
> +             ret = devm_add_action_or_reset(dev, lt9211_destroy_wq, ctx->wq);
> +             if (ret)
> +                     return ret;
> +             INIT_WORK(&ctx->lt9211_work, lt9211_work_func);
> +     }
>  
>       ctx->bridge.of_node = dev->of_node;
> -     drm_bridge_add(&ctx->bridge);
> -
> -     ret = lt9211_host_attach(ctx);
> +     ret = devm_drm_bridge_add(dev, &ctx->bridge);
>       if (ret)
> -             drm_bridge_remove(&ctx->bridge);
> -
> -     return ret;
> -}
> -
> +             return ret;
>  
> +     return lt9211_host_attach(ctx);
>  }

[Severity: High]
Is there a devres order mismatch here that leads to a use-after-free?

Because devres actions are executed in reverse order of addition, registering
the workqueue teardown action before registering the DSI device in
lt9211_host_attach() means the DSI device will be unregistered and freed
before the workqueue is destroyed.

During driver unbind, if the initialization work is pending, the workqueue
destruction flushes and executes it. The work function then calls
lt9211c_configure_rx(), which accesses the already freed ctx->dsi pointer.

Could the workqueue destruction be deferred until after the DSI device is
attached, or could the DSI device attachment be moved earlier in the probe?

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=2

Reply via email to