HID: ayaneo: fix LED teardown use-after-free on unbind - #5
Merged
NeroReflex merged 1 commit intoAug 25, 2026
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_workafter the flush insideled_classdev_unregister()but before the sysfs node is removed. With the LED registered via devm, that work runs afterhid_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_workonce 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.