kmb_irq_install() registers the LCD interrupt handler with the DRM device as its dev_id. If drm_dev_register() subsequently fails, the probe error path tears down polling but does not uninstall the IRQ. The DRM device is allocated with devm_drm_dev_alloc(), so its initial reference is automatically released by devres after probe returns an error. The missing IRQ cleanup can therefore leave the registered interrupt handler holding a pointer to the freed DRM device. The failure sequence is: kmb_probe() IRQ context ----------- ----------- kmb_irq_install() request_irq(..., drm) | | success v drm_dev_register() | | fails v err_register drm_kms_helper_poll_fini() | | IRQ remains registered v probe returns error | v devres cleanup drm_dev_put() | v kmb / drm freed interrupt occurs | v kmb_isr(..., drm) | v handle_lcd_irq(drm) | v access freed object A later interrupt can thus invoke kmb_isr() with a stale drm pointer and result in a potential use-after-free. Call kmb_irq_uninstall() after drm_dev_register() fails. This disables the LCD interrupts and frees the IRQ before the devm-managed DRM device can be released. This issue was found by manual code inspection. Fixes: 7f7b96a8a0a1 ("drm/kmb: Add support for KeemBay Display") Cc: stable@vger.kernel.org Signed-off-by: Guangshuo Li --- drivers/gpu/drm/kmb/kmb_drv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/kmb/kmb_drv.c b/drivers/gpu/drm/kmb/kmb_drv.c index 7c2eb1152fc2..d8e2fc28ee9e 100644 --- a/drivers/gpu/drm/kmb/kmb_drv.c +++ b/drivers/gpu/drm/kmb/kmb_drv.c @@ -569,6 +569,7 @@ static int kmb_probe(struct platform_device *pdev) err_register: drm_kms_helper_poll_fini(&kmb->drm); + kmb_irq_uninstall(&kmb->drm); err_irq: pm_runtime_disable(kmb->drm.dev); err_free: -- 2.43.0