nt35950_probe() registers the panel before attaching it to the DSI hosts. If mipi_dsi_attach() fails, the probe error path returns without removing the panel from the DRM panel registry. The panel is allocated with devm_drm_panel_alloc(), so its storage is released after probe returns an error. Leaving the panel registered therefore leaves the global panel list pointing at freed memory, which can result in a potential use-after-free when the stale entry is later accessed. There is an additional cleanup issue for dual-DSI panels. If attaching DSI0 succeeds but attaching DSI1 fails, the error path unregisters the secondary DSI device without detaching the already attached DSI0. The failure sequence is: drm_panel_add() | v attach DSI0 | | success v attach DSI1 | | failure v probe cleanup | +-- DSI0 remains attached | +-- panel remains registered | v probe returns error | v devm panel storage is released | v panel registry contains a dangling pointer Detach any DSI hosts that were successfully attached before the failure and remove the panel from the DRM panel registry before returning the probe error. This issue was found by manual code inspection. Fixes: 623a3531e9cf ("drm/panel: Add driver for Novatek NT35950 DSI DriverIC panels") Cc: stable@vger.kernel.org Signed-off-by: Guangshuo Li --- drivers/gpu/drm/panel/panel-novatek-nt35950.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-novatek-nt35950.c b/drivers/gpu/drm/panel/panel-novatek-nt35950.c index 94aa6489d99f..8edd0aa363ce 100644 --- a/drivers/gpu/drm/panel/panel-novatek-nt35950.c +++ b/drivers/gpu/drm/panel/panel-novatek-nt35950.c @@ -514,12 +514,19 @@ static int nt35950_probe(struct mipi_dsi_device *dsi) ret = mipi_dsi_attach(nt->dsi[i]); if (ret < 0) { - /* If we fail to attach to either host, we're done */ + dev_err_probe(dev, ret, + "Cannot attach to DSI%d host.\n", i); + + /* Detach from all previously attached DSI hosts */ + while (i--) + mipi_dsi_detach(nt->dsi[i]); + if (num_dsis == 2) mipi_dsi_device_unregister(nt->dsi[1]); - return dev_err_probe(dev, ret, - "Cannot attach to DSI%d host.\n", i); + drm_panel_remove(&nt->panel); + + return ret; } } -- 2.43.0