Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Input: lkkbd - disable pending work before freeing device

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 <ii4gsp@gmail.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20251212052314.16139-1-ii4gsp@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Minseong Kim and committed by
Dmitry Torokhov
e58c88f0 429c4727

+4 -1
+4 -1
drivers/input/keyboard/lkkbd.c
··· 670 670 671 671 return 0; 672 672 673 - fail3: serio_close(serio); 673 + fail3: disable_work_sync(&lk->tq); 674 + serio_close(serio); 674 675 fail2: serio_set_drvdata(serio, NULL); 675 676 fail1: input_free_device(input_dev); 676 677 kfree(lk); ··· 684 683 static void lkkbd_disconnect(struct serio *serio) 685 684 { 686 685 struct lkkbd *lk = serio_get_drvdata(serio); 686 + 687 + disable_work_sync(&lk->tq); 687 688 688 689 input_get_device(lk->dev); 689 690 input_unregister_device(lk->dev);