Commit baeb66f
usb: gadget: udc: fix use-after-free in usb_gadget_state_work
A race condition during gadget teardown can lead to a use-after-free
in usb_gadget_state_work(), as reported by KASAN:
BUG: KASAN: invalid-access in sysfs_notify+0x2c/0xd0
Workqueue: events usb_gadget_state_work
The fundamental race occurs because a concurrent event (e.g., an
interrupt) can call usb_gadget_set_state() and schedule gadget->work
at any time during the cleanup process in usb_del_gadget().
Commit 399a45e ("usb: gadget: core: flush gadget workqueue after
device removal") attempted to fix this by moving flush_work() to after
device_del(). However, this does not fully solve the race, as a new
work item can still be scheduled *after* flush_work() completes but
before the gadget's memory is freed, leading to the same use-after-free.
This patch fixes the race condition robustly by introducing a 'teardown'
flag and a 'state_lock' spinlock to the usb_gadget struct. The flag is
set during cleanup in usb_del_gadget() *before* calling flush_work() to
prevent any new work from being scheduled once cleanup has commenced.
The scheduling site, usb_gadget_set_state(), now checks this flag under
the lock before queueing the work, thus safely closing the race window.
Fixes: 5702f75 ("usb: gadget: udc-core: move sysfs_notify() to a workqueue")
Cc: stable <stable@kernel.org>
Signed-off-by: Jimmy Hu <hhhuuu@google.com>
Link: https://patch.msgid.link/20251023054945.233861-1-hhhuuu@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>1 parent eb9ac77 commit baeb66f
2 files changed
Lines changed: 21 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1126 | 1126 | | |
1127 | 1127 | | |
1128 | 1128 | | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
1129 | 1132 | | |
1130 | | - | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
1131 | 1136 | | |
1132 | 1137 | | |
1133 | 1138 | | |
| |||
1361 | 1366 | | |
1362 | 1367 | | |
1363 | 1368 | | |
| 1369 | + | |
| 1370 | + | |
1364 | 1371 | | |
1365 | 1372 | | |
1366 | 1373 | | |
| |||
1535 | 1542 | | |
1536 | 1543 | | |
1537 | 1544 | | |
| 1545 | + | |
1538 | 1546 | | |
1539 | 1547 | | |
1540 | 1548 | | |
| |||
1548 | 1556 | | |
1549 | 1557 | | |
1550 | 1558 | | |
| 1559 | + | |
| 1560 | + | |
| 1561 | + | |
| 1562 | + | |
| 1563 | + | |
| 1564 | + | |
| 1565 | + | |
1551 | 1566 | | |
1552 | 1567 | | |
1553 | 1568 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
376 | 376 | | |
377 | 377 | | |
378 | 378 | | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
379 | 382 | | |
380 | 383 | | |
381 | 384 | | |
| |||
451 | 454 | | |
452 | 455 | | |
453 | 456 | | |
| 457 | + | |
| 458 | + | |
454 | 459 | | |
455 | 460 | | |
456 | 461 | | |
| |||
0 commit comments