From: Hyunjung Ko The err IRQ handler (err_handler) schedules vindev->err_work (signal_change), which dereferences vindev (vindev->mgbdev, vindev->vdev, vindev->queue). mgb4_vin_free() disables and frees the err IRQ, so no new err_work is scheduled, but it never cancels an err_work that was already queued by the last interrupt before kfree(vindev). As err_work runs on the system workqueue with no timing bound, it can execute after vindev is freed, dereferencing freed memory -- a use-after-free. Cancel err_work after the interrupts are freed (so it cannot be re-queued) and before vindev is freed, mirroring the existing cancel_work_sync(&vindev->dma_work) in stop_streaming(). Fixes: 0ab13674a9bd ("media: pci: mgb4: Added Digiteq Automotive MGB4 driver") Cc: stable@vger.kernel.org Signed-off-by: Hyunjung Ko --- drivers/media/pci/mgb4/mgb4_vin.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/pci/mgb4/mgb4_vin.c b/drivers/media/pci/mgb4/mgb4_vin.c index b247854..64b7a9b 100644 --- a/drivers/media/pci/mgb4/mgb4_vin.c +++ b/drivers/media/pci/mgb4/mgb4_vin.c @@ -1068,6 +1068,8 @@ void mgb4_vin_free(struct mgb4_vin_dev *vindev) free_irq(vin_irq, vindev); free_irq(err_irq, vindev); + cancel_work_sync(&vindev->err_work); + device_remove_groups(&vindev->vdev.dev, module_groups(vindev->mgbdev)); mgb4_i2c_free(&vindev->deser); -- 2.43.0