Skip to content

Commit e58c88f

Browse files
ii4gspdtor
authored andcommitted
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>
1 parent 429c472 commit e58c88f

1 file changed

Lines changed: 4 additions & 1 deletion

File tree

drivers/input/keyboard/lkkbd.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,8 @@ static int lkkbd_connect(struct serio *serio, struct serio_driver *drv)
670670

671671
return 0;
672672

673-
fail3: serio_close(serio);
673+
fail3: disable_work_sync(&lk->tq);
674+
serio_close(serio);
674675
fail2: serio_set_drvdata(serio, NULL);
675676
fail1: input_free_device(input_dev);
676677
kfree(lk);
@@ -684,6 +685,8 @@ static void lkkbd_disconnect(struct serio *serio)
684685
{
685686
struct lkkbd *lk = serio_get_drvdata(serio);
686687

688+
disable_work_sync(&lk->tq);
689+
687690
input_get_device(lk->dev);
688691
input_unregister_device(lk->dev);
689692
serio_close(serio);

0 commit comments

Comments
 (0)