diff options
| author | Chen Changcheng <chenchangcheng@kylinos.cn> | 2026-07-27 09:35:00 +0800 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.com> | 2026-08-03 21:22:08 +0200 |
| commit | eb51c9f8cb4f064981d9c6cae13de8eda280785d (patch) | |
| tree | 0f91b9072cd7058530167f0e7b905960c949fe44 /tools/perf/scripts/python/libxed.py | |
| parent | 9405601fb7649dc1d52e785c1b5717d7e9129613 (diff) | |
HID: corsair: cancel worker before unregistering LED to fix use-after-free
The cleanup functions k90_cleanup_backlight() and
k90_cleanup_macro_functions() call led_classdev_unregister() before
cancel_work_sync():
led_classdev_unregister() <-- may free led->cdev.dev
cancel_work_sync() <-- wait for worker
If the LED worker (k90_backlight_work / k90_record_led_work) is
already running on another CPU, the following race can occur:
CPU 1 (worker) CPU 2 (remove)
--------------------- --------------------
if (led->removed) -> false
(passed the guard, about to read led->cdev.dev)
* preempted
removed = true
led_classdev_unregister()
-> led->cdev.dev freed
cancel_work_sync()
-> waits for worker
* resumes
dev = led->cdev.dev->parent <-- UAF!
Fix by swapping the order so that the worker is cancelled first:
cancel_work_sync() <-- wait for worker first
led_classdev_unregister() <-- then safe to unregister
The removed flag is set before cancel_work_sync() so that if
led_classdev_unregister() internally triggers another brightness
update (which re-schedules the work), the worker will see the flag
and return immediately.
Signed-off-by: Chen Changcheng <chenchangcheng@kylinos.cn>
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Diffstat (limited to 'tools/perf/scripts/python/libxed.py')
0 files changed, 0 insertions, 0 deletions
