From: sashiko-bot@kernel.org
To: "Derek J. Clark" <derekjohn.clark@gmail.com>
Cc: linux-input@vger.kernel.org, dmitry.torokhov@gmail.com
Subject: Re: [PATCH v8 3/4] HID: hid-msi: Add RGB control interface
Date: Fri, 22 May 2026 04:00:54 +0000 [thread overview]
Message-ID: <20260522040054.F05631F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260522015518.1111290-4-derekjohn.clark@gmail.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Explicitly unregistering a devm-managed LED class device causes a double unregister and list corruption upon device teardown.
- [High] Calling sleepable functions that allocate memory with GFP_KERNEL or take sleeping locks while holding a spinlock.
- [High] Race condition between sysfs/LED attributes and `claw_remove()` allows `rgb_queue` to be scheduled after cancellation.
- [High] Missing cancellation of the `rgb_queue` delayed work during system suspend can cause USB I/O to a suspended device.
--
commit 34d0916b058e394f024a63889da5c0fbe434c516
Author: Derek J. Clark <derekjohn.clark@gmail.com>
HID: hid-msi: Add RGB control interface
Adds RGB control interface for MSI Claw devices. The MSI Claw uses a
fairly unique RGB interface with 9 total zones, supporting up to 8
sequential frames of RGB zone data. The driver mirrors the effects
available in Windows while keeping effect names consistent with Lenovo
drivers.
> diff --git a/drivers/hid/hid-msi.c b/drivers/hid/hid-msi.c
> index b9901869075f6..0b875603dbb32 100644
> --- a/drivers/hid/hid-msi.c
> +++ b/drivers/hid/hid-msi.c
[ ... ]
> +static ssize_t effect_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct led_classdev *led_cdev = dev_get_drvdata(dev);
> + struct led_classdev_mc *led_mc = container_of(led_cdev, struct led_classdev_mc, led_cdev);
> + struct claw_drvdata *drvdata = container_of(led_mc, struct claw_drvdata, led_mc);
> + int ret;
> +
> + scoped_guard(spinlock_irqsave, &drvdata->registration_lock) {
> + /* Pairs with smp_store_release from cfg_setup_fn in system_wq context */
> + if (!smp_load_acquire(&drvdata->rgb_registered))
> + return -ENODEV;
> + }
> +
> + ret = sysfs_match_string(claw_rgb_effect_text, buf);
> + if (ret < 0)
> + return ret;
> +
> + drvdata->rgb_effect = ret;
> + mod_delayed_work(system_wq, &drvdata->rgb_queue, msecs_to_jiffies(50));
[Severity: High]
Can mod_delayed_work() here race with claw_remove()?
If claw_remove() runs concurrently, it acquires the registration_lock, sets
rgb_registered to false, drops the lock, and calls
cancel_delayed_work_sync(&drvdata->rgb_queue).
It then calls device_remove_group(), which blocks until this sysfs store
completes. Once device_remove_group() returns, devres frees drvdata.
However, since this sysfs store function already checked rgb_registered and
dropped the lock, it will continue executing and call mod_delayed_work(),
re-arming the workqueue. Will this lead to the delayed work executing on
freed memory?
> +
> + return count;
> +}
[ ... ]
> +static void cfg_setup_fn(struct work_struct *work)
> +{
[ ... ]
> +try_gamepad:
> + scoped_guard(spinlock_irqsave, &drvdata->registration_lock) {
> + /* Pairs with smp_store_release from below */
> + if (!smp_load_acquire(&drvdata->gamepad_registered) && gamepad_ready) {
> + ret = devm_device_add_group(&drvdata->hdev->dev, &claw_gamepad_attr_group);
[Severity: High]
Does devm_device_add_group() sleep?
It allocates memory using GFP_KERNEL inside devres_alloc() and acquires
the sleeping kernfs_mutex during sysfs group creation. Calling this inside a
spinlock block with interrupts disabled will trigger a scheduling while atomic
panic. Can this be called outside the spinlock?
> + if (ret) {
> + dev_err(&drvdata->hdev->dev,
> + "Failed to create gamepad attrs: %d\n", ret);
> + goto try_rgb;
> + }
> +
> + /* Pairs with smp_load_acquire in attribute show/store functions */
> + smp_store_release(&drvdata->gamepad_registered, true);
> + }
> }
> - scoped_guard(spinlock_irqsave, &drvdata->registration_lock)
> - /* Pairs with smp_load_acquire in attribute show/store functions */
> - smp_store_release(&drvdata->gamepad_registered, true);
>
> - kobject_uevent(&drvdata->hdev->dev.kobj, KOBJ_CHANGE);
> +try_rgb:
> + /* Add and enable RGB interface once we have the device state */
> + scoped_guard(spinlock_irqsave, &drvdata->registration_lock) {
> + /* Pairs with smp_store_release from below */
> + if (!smp_load_acquire(&drvdata->rgb_registered) && rgb_ready) {
> + ret = devm_led_classdev_multicolor_register(&drvdata->hdev->dev,
> + &drvdata->led_mc);
[Severity: High]
Does devm_led_classdev_multicolor_register() also sleep?
Similar to devm_device_add_group(), this registers a device which takes
sleeping locks and allocates memory with GFP_KERNEL. Should this be called
outside of the spinlock block?
> + if (ret) {
> + dev_err(&drvdata->hdev->dev,
> + "Failed to create led device: %d\n", ret);
> + goto update_kobjects;
> + }
> +
> + ret = device_add_group(drvdata->led_mc.led_cdev.dev, &claw_rgb_attr_group);
> + if (ret) {
> + dev_err(&drvdata->hdev->dev,
> + "Failed to create RGB attrs: %d\n", ret);
> + led_classdev_unregister(&drvdata->led_mc.led_cdev);
[Severity: High]
Does this manual unregister cause a double-free on device teardown?
Since devm_led_classdev_multicolor_register() attaches a devres cleanup
action, manually calling led_classdev_unregister() here leaves the devres
action queued. When the driver is unbound, devres will execute
led_classdev_unregister() a second time on the same LED class device pointer.
Will this result in list corruption and use-after-free?
> + goto update_kobjects;
> + }
> +
> + /* Pairs with smp_load_acquire in attribute show/store functions */
> + smp_store_release(&drvdata->rgb_registered, true);
> + }
> + }
[ ... ]
> @@ -971,9 +1593,11 @@ static int claw_probe(struct hid_device *hdev, u8 ep)
> spin_lock_init(&drvdata->cmd_lock);
> spin_lock_init(&drvdata->mode_lock);
> spin_lock_init(&drvdata->profile_lock);
> + spin_lock_init(&drvdata->frame_lock);
> init_completion(&drvdata->send_cmd_complete);
> INIT_DELAYED_WORK(&drvdata->cfg_resume, &cfg_resume_fn);
> INIT_DELAYED_WORK(&drvdata->cfg_setup, &cfg_setup_fn);
> + INIT_DELAYED_WORK(&drvdata->rgb_queue, &claw_rgb_queue_fn);
[Severity: High]
Is the rgb_queue delayed work properly cancelled during system suspend?
In claw_suspend(), the driver cancels cfg_resume and cfg_setup, but it does
not appear to cancel the newly introduced rgb_queue delayed work. Because
rgb_queue is queued on system_wq (which is not freezable), could it execute
after the device has been suspended? This might lead to USB I/O errors and
possible hardware lockups.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260522015518.1111290-1-derekjohn.clark@gmail.com?part=3
next prev parent reply other threads:[~2026-05-22 4:00 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-22 1:55 [PATCH v8 0/4] Add MSI Claw HID Configuration Driver Derek J. Clark
2026-05-22 1:55 ` [PATCH v8 1/4] HID: hid-msi: Add MSI Claw configuration driver Derek J. Clark
2026-05-22 2:33 ` sashiko-bot
2026-05-22 1:55 ` [PATCH v8 2/4] HID: hid-msi: Add M-key mapping attributes Derek J. Clark
2026-05-22 3:27 ` sashiko-bot
2026-05-22 1:55 ` [PATCH v8 3/4] HID: hid-msi: Add RGB control interface Derek J. Clark
2026-05-22 4:00 ` sashiko-bot [this message]
2026-05-22 1:55 ` [PATCH v8 4/4] HID: hid-msi: Add Rumble Intensity Attributes Derek J. Clark
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260522040054.F05631F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=derekjohn.clark@gmail.com \
--cc=dmitry.torokhov@gmail.com \
--cc=linux-input@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox