From: sashiko-bot@kernel.org
To: "Derek J. Clark" <derekjohn.clark@gmail.com>
Cc: dmitry.torokhov@gmail.com, linux-input@vger.kernel.org
Subject: Re: [PATCH v5 1/4] HID: hid-msi: Add MSI Claw configuration driver
Date: Sun, 17 May 2026 02:11:04 +0000 [thread overview]
Message-ID: <20260517021104.9FF60C19425@smtp.kernel.org> (raw)
In-Reply-To: <20260517013925.3120314-2-derekjohn.clark@gmail.com>
Thank you for your contribution! Sashiko AI review found 9 potential issue(s) to consider:
- [High] ABBA deadlock in `claw_remove` during sysfs group removal.
- [High] Dynamic endpoint querying in `msi_remove` can bypass cleanup on alternate setting changes, leading to a Use-After-Free.
- [High] Unbalanced `hid_hw_close` call in `claw_remove` causes reference count underflow if `drvdata` is NULL.
- [High] Late ACKs from timed-out commands incorrectly fulfill the completion wait of subsequent synchronous commands.
- [Medium] The 8ms timeout for hardware output reports is too short and will randomly fail due to jiffy timer granularity.
- [Medium] System suspend during initial probe permanently prevents sysfs attribute registration.
- [Medium] Kconfig dependency mismatch for LEDS_CLASS causes unmet dependency warnings.
- [Medium] cfg_resume_fn unconditionally forces a destructive USB disconnect on every system resume.
- [Medium] Unprotected data race on `drvdata->gamepad_mode` and `drvdata->mkeys_function` between interrupt and process contexts.
--
commit 518cb80b6362b58a1246f31d9fcaf94c7bfd77ee
Author: Derek J. Clark <derekjohn.clark@gmail.com>
Subject: HID: hid-msi: Add MSI Claw configuration driver
This commit adds a configuration driver for the MSI Claw series of handhelds.
It supports gamepad mode switching, M-key behavior, and a device reset via
sysfs attributes.
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index ff2f580b660ba..ec412bba1e1ed 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -485,6 +485,18 @@ config HID_GT683R
> Currently the following devices are know to be supported:
> - MSI GT683R
>
> +config HID_MSI
> + tristate "MSI Claw Gamepad Support"
> + depends on USB_HID
> + select LEDS_CLASS
> + select LEDS_CLASS_MULTICOLOR
Is it possible this will cause an unmet dependency Kconfig warning if NEW_LEDS
is not enabled?
LEDS_CLASS depends on NEW_LEDS, so selecting it without inheriting the
dependency can cause build issues on some configurations.
> diff --git a/drivers/hid/hid-msi.c b/drivers/hid/hid-msi.c
> new file mode 100644
> index 0000000000000..3f809dc70a4cc
> --- /dev/null
> +++ b/drivers/hid/hid-msi.c
[ ... ]
> +static int claw_gamepad_mode_event(struct claw_drvdata *drvdata,
> + struct claw_command_report *cmd_rep)
> +{
> + if (cmd_rep->data[0] >= ARRAY_SIZE(claw_gamepad_mode_text) ||
> + !claw_gamepad_mode_text[cmd_rep->data[0]] ||
> + cmd_rep->data[1] >= ARRAY_SIZE(claw_mkeys_function_text))
> + return -EINVAL;
> +
> + drvdata->gamepad_mode = cmd_rep->data[0];
> + drvdata->mkeys_function = cmd_rep->data[1];
Is there a potential data race here?
These fields are written from the raw event callback (which runs in interrupt
context), but they are read in process context by functions like cfg_resume_fn
and gamepad_mode_show without acquiring a shared lock.
> +
> + return 0;
> +}
> +
> +static int claw_raw_event(struct claw_drvdata *drvdata, struct hid_report *report,
> + u8 *data, int size)
> +{
[ ... ]
> + switch (cmd_rep->cmd) {
> + case CLAW_COMMAND_TYPE_GAMEPAD_MODE_ACK:
> + ret = claw_gamepad_mode_event(drvdata, cmd_rep);
> + break;
> + case CLAW_COMMAND_TYPE_ACK:
> + break;
> + default:
> + dev_dbg(&drvdata->hdev->dev, "Unknown command: %x\n", cmd_rep->cmd);
> + return 0;
> + }
> +
> + complete(&drvdata->send_cmd_complete);
If a previous synchronous command timed out, but the device later sends an ACK,
will this unconditionally complete the completion?
When the next command calls reinit_completion(), an immediate late ACK from the
previous command might falsely complete the new command's wait, causing the
driver to read stale state.
> +
> + return ret;
> +}
[ ... ]
> +static int claw_hw_output_report(struct hid_device *hdev, u8 index, u8 *data,
> + size_t len, unsigned int timeout)
> +{
[ ... ]
> + if (timeout) {
> + ret = wait_for_completion_interruptible_timeout(&drvdata->send_cmd_complete,
> + msecs_to_jiffies(timeout));
Could this timeout prematurely?
When the timeout is very short (like 8ms as used in gamepad_mode_show),
msecs_to_jiffies(8) evaluates to 1 jiffy on HZ=100 kernels.
A 1-jiffy timeout can expire almost instantly if the system jiffy tick occurs
immediately after wait_for_completion_interruptible_timeout() is called,
leading to a spurious -EBUSY.
> +
> + dev_dbg(&hdev->dev, "Remaining timeout: %u\n", ret);
> + if (ret >= 0) /* preserve errors */
> + ret = ret == 0 ? -EBUSY : 0; /* timeout occurred : time remained */
> + }
> +
> + return ret;
> +}
[ ... ]
> +static void cfg_resume_fn(struct work_struct *work)
> +{
> + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
> + struct claw_drvdata *drvdata = container_of(dwork, struct claw_drvdata, cfg_resume);
> + u8 data[2] = { drvdata->gamepad_mode, drvdata->mkeys_function };
> + int ret;
> +
> + ret = claw_hw_output_report(drvdata->hdev, CLAW_COMMAND_TYPE_SWITCH_MODE, data,
> + ARRAY_SIZE(data), 0);
The commit message mentions that sending the SWITCH_MODE command causes a USB
disconnect in the device.
Will this unconditional SWITCH_MODE call on every system resume forcibly
disconnect and re-enumerate the gamepad, potentially breaking active
applications holding an open file descriptor?
> + if (ret)
> + dev_err(&drvdata->hdev->dev, "Failed to set gamepad mode settings: %d\n", ret);
> +}
[ ... ]
> +static void claw_remove(struct hid_device *hdev)
> +{
> + struct claw_drvdata *drvdata = hid_get_drvdata(hdev);
> +
> + if (!drvdata) {
> + hid_hw_close(hdev);
If drvdata is NULL (meaning claw_probe was never called or failed), will
calling hid_hw_close() underflow the hdev->ll_open_count, since hid_hw_open()
was never successfully called?
> + return;
> + }
> +
> + cancel_delayed_work_sync(&drvdata->cfg_setup);
> + cancel_delayed_work_sync(&drvdata->cfg_resume);
> +
> + guard(mutex)(&drvdata->cfg_mutex);
> + if (drvdata->gamepad_registered)
> + device_remove_group(&hdev->dev, &claw_gamepad_attr_group);
Will holding the cfg_mutex while removing the sysfs group cause an ABBA
deadlock?
The sysfs core's removal blocks until active references to attributes are
drained. If a user concurrently accesses an attribute, the sysfs callback will
try to acquire the cfg_mutex (via claw_hw_output_report).
The driver would hold the mutex waiting for the sysfs reference to drop, while
the callback holds the sysfs reference waiting for the mutex.
> +
> + hid_hw_close(hdev);
> +}
> +
> +static void msi_remove(struct hid_device *hdev)
> +{
> + int ret;
> + u8 ep;
> +
> + ret = get_endpoint_address(hdev);
> + if (ret <= 0)
> + goto hw_stop;
> +
> + ep = ret;
> + if (ep == CLAW_XINPUT_CFG_INTF_IN || ep == CLAW_DINPUT_CFG_INTF_IN)
> + claw_remove(hdev);
If userspace dynamically changes the USB alternate setting via
USBDEVFS_SETINTERFACE, the endpoint check here could fail and bypass
claw_remove().
If claw_remove() is bypassed, the delayed works (cfg_setup and cfg_resume)
are never cancelled. Could this result in a use-after-free when those works
eventually execute and access the freed drvdata?
> +
> +hw_stop:
> + hid_hw_stop(hdev);
> +}
[ ... ]
> +static int claw_suspend(struct hid_device *hdev)
> +{
> + struct claw_drvdata *drvdata = hid_get_drvdata(hdev);
> +
> + if (!drvdata)
> + return -ENODEV;
> +
> + cancel_delayed_work_sync(&drvdata->cfg_setup);
If the system suspends before the cfg_setup delayed work fires, the work is
synchronously cancelled here.
Since claw_resume schedules cfg_resume but does not reschedule cfg_setup,
will drvdata->gamepad_registered remain false forever, permanently
preventing sysfs attribute registration?
> + cancel_delayed_work_sync(&drvdata->cfg_resume);
> +
> + return 0;
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260517013925.3120314-1-derekjohn.clark@gmail.com?part=1
next prev parent reply other threads:[~2026-05-17 2:11 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-17 1:39 [PATCH v5 0/4] Add MSI Claw HID Configuration Driver Derek J. Clark
2026-05-17 1:39 ` [PATCH v5 1/4] HID: hid-msi: Add MSI Claw configuration driver Derek J. Clark
2026-05-17 2:11 ` sashiko-bot [this message]
2026-05-17 1:39 ` [PATCH v5 2/4] HID: hid-msi: Add M-key mapping attributes Derek J. Clark
2026-05-17 2:56 ` sashiko-bot
2026-05-17 1:39 ` [PATCH v5 3/4] HID: hid-msi: Add RGB control interface Derek J. Clark
2026-05-17 3:24 ` sashiko-bot
2026-05-17 1:39 ` [PATCH v5 4/4] HID: hid-msi: Add Rumble Intensity Attributes Derek J. Clark
2026-05-17 3:50 ` sashiko-bot
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=20260517021104.9FF60C19425@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