6.6-stable review patch. If anyone has any objections, please let me know. ------------------ From: Minseong Kim [ Upstream commit e58c88f0cb2d8ed89de78f6f17409d29cfab6c5c ] lkkbd_interrupt() schedules lk->tq via schedule_work(), and the work handler lkkbd_reinit() dereferences the lkkbd structure and its serio/input_dev fields. lkkbd_disconnect() and error paths in lkkbd_connect() free the lkkbd structure without preventing the reinit work from being queued again until serio_close() returns. This can allow the work handler to run after the structure has been freed, leading to a potential use-after-free. Use disable_work_sync() instead of cancel_work_sync() to ensure the reinit work cannot be re-queued, and call it both in lkkbd_disconnect() and in lkkbd_connect() error paths after serio_open(). Signed-off-by: Minseong Kim Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20251212052314.16139-1-ii4gsp@gmail.com Signed-off-by: Dmitry Torokhov Signed-off-by: Sasha Levin --- drivers/input/keyboard/lkkbd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/input/keyboard/lkkbd.c b/drivers/input/keyboard/lkkbd.c index 047b654b3752c..7b57577a1715c 100644 --- a/drivers/input/keyboard/lkkbd.c +++ b/drivers/input/keyboard/lkkbd.c @@ -671,6 +671,7 @@ static int lkkbd_connect(struct serio *serio, struct serio_driver *drv) return 0; fail3: serio_close(serio); + cancel_work_sync(&lk->tq); fail2: serio_set_drvdata(serio, NULL); fail1: input_free_device(input_dev); kfree(lk); @@ -687,6 +688,7 @@ static void lkkbd_disconnect(struct serio *serio) input_get_device(lk->dev); input_unregister_device(lk->dev); serio_close(serio); + cancel_work_sync(&lk->tq); serio_set_drvdata(serio, NULL); input_put_device(lk->dev); kfree(lk); -- 2.53.0