Skip to content

HID: ayaneo: fix LED teardown use-after-free on unbind - #5

Merged
NeroReflex merged 1 commit into
OpenGamingCollective:masterfrom
matmartinez:hid-ayaneo-teardown-fix
Aug 25, 2026
Merged

HID: ayaneo: fix LED teardown use-after-free on unbind#5
NeroReflex merged 1 commit into
OpenGamingCollective:masterfrom
matmartinez:hid-ayaneo-teardown-fix

Conversation

@matmartinez

Copy link
Copy Markdown

Follow-up to #3, as offered — backports the crash fix from the v2 upstream submission as a standalone patch, since the merged v1 carries the vulnerable teardown.

The bug: a brightness write racing a driver unbind can queue the LED's set_brightness_work after the flush inside led_classdev_unregister() but before the sysfs node is removed. With the LED registered via devm, that work runs after hid_hw_stop() and after devres frees the driver data → write through freed memory. I reproduced it as a hard system hang with display artifacts by unbinding under a brightness-write loop. The window is reachable in normal use: the controller power-cycles on resume and on module eject while userspace (e.g. InputPlumber) may be writing the LED — journals on my device show the race firing (benignly, that time) during a routine resume re-enumeration.

The fix: register the LED without devm, unregister it first in remove, and flush set_brightness_work once more after the unregister (sysfs provably gone, transport still up). Survived 6 rounds of rmmod-under-brightness-hammer with varied timing on my AYANEO 3, zero corruption markers, driver fully functional after each reload.

Deliberately not syncing the rest of v2 here (LED rename, hw_pattern, sensitivity bytes) — upstream review is still settling scope; I'll follow up with a full sync once it lands. This fix is the part that shouldn't wait.

checkpatch --strict clean.

A brightness write racing a driver unbind can queue the LED's
set_brightness_work after the flush inside led_classdev_unregister()
but before the sysfs node is removed. With the LED registered through
devm, that work then runs after aya3_remove() has called
hid_hw_stop() and after devres has freed the driver data, writing
through freed memory. Reproducible memory corruption (system hang
with display artifacts) by unbinding under a brightness-write loop;
the window is also reachable in normal use, since the controller
power-cycles on resume and on module eject while userspace may be
writing the LED.

Register the LED without devm, unregister it first in remove, and
flush set_brightness_work once more after the unregister -- at that
point the sysfs node is provably gone and nothing can requeue it,
and the transport is still up for a final send.

Same fix as in the v2 upstream submission
(lore.kernel.org/linux-input/20260824223103.93947-1-hello@matias.me);
validated there on hardware with repeated unbinds under a concurrent
brightness-write load.

Signed-off-by: Matías Martínez <hello@matias.me>
@NeroReflex
NeroReflex merged commit 88b5f75 into OpenGamingCollective:master Aug 25, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants