From: Manish Khadka <maskmemanish@gmail.com>
To: linux-input@vger.kernel.org
Cc: "Derek J . Clark" <derekjohn.clark@gmail.com>,
Mark Pearson <mpearson-lenovo@squebb.ca>,
Jiri Kosina <jikos@kernel.org>,
Benjamin Tissoires <bentiss@kernel.org>,
linux-kernel@vger.kernel.org
Subject: [PATCH v2] HID: hid-lenovo-go: cancel cfg_setup work in hid_go_cfg_remove()
Date: Fri, 15 May 2026 23:30:11 +0545 [thread overview]
Message-ID: <20260515174511.78486-1-maskmemanish@gmail.com> (raw)
In-Reply-To: <20260515161830.E6E2BC2BCB3@smtp.kernel.org>
hid_go_cfg_probe() initialises drvdata.go_cfg_setup and schedules it
to run 2 ms later:
INIT_DELAYED_WORK(&drvdata.go_cfg_setup, &cfg_setup);
schedule_delayed_work(&drvdata.go_cfg_setup, msecs_to_jiffies(2));
cfg_setup() dereferences drvdata.hdev to issue MCU command requests.
hid_go_cfg_remove() tears down sysfs and stops the HID device, but
never drains the delayed work. If the device is unbound within the
2 ms scheduling delay (a probe failure rolling back via remove, or a
fast rmmod after probe), the work fires after hid_destroy_device()
has dropped its reference and released the underlying hdev struct,
leaving cfg_setup() with a stale drvdata.hdev pointer.
Mirror the sibling driver hid-lenovo-go-s.c, whose hid_gos_cfg_remove()
already calls cancel_delayed_work_sync() on its analogous work, and
drain go_cfg_setup at the top of hid_go_cfg_remove(). The cancel
must come before guard(mutex)(&drvdata.cfg_mutex) because cfg_setup()
acquires that mutex; reversing the order would deadlock.
Fixes: d69ccfcbc955 ("HID: hid-lenovo-go: Add Lenovo Legion Go Series HID Driver")
Cc: stable@vger.kernel.org
Signed-off-by: Manish Khadka <maskmemanish@gmail.com>
---
v1 -> v2:
- Address Sashiko AI review feedback:
* [Low] Correct the inaccurate description of how drvdata.hdev
becomes stale. hid_set_drvdata(hdev, NULL) only clears the
per-hdev driver_data, not the global drvdata.hdev; the actual
stale-pointer mechanism is hid_destroy_device()'s put_device()
releasing the underlying hdev struct. Commit message and the
inline comment in hid_go_cfg_remove() are corrected accordingly.
- The other six review points (ABBA deadlock with sysfs_remove_groups,
global static drvdata corruption on multi-device/rebind, devm vs.
explicit teardown race, probe error-path leaks, mcu_property_out
unconditional return 0, schedule_delayed_work boolean misuse)
are all valid pre-existing bugs in the driver but predate and are
independent of this patch. Each deserves its own fix; will be
addressed in separate patches.
Thanks to Sashiko AI review for all seven points.
drivers/hid/hid-lenovo-go.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/hid/hid-lenovo-go.c b/drivers/hid/hid-lenovo-go.c
index d4d26c783356..b9d8cde53136 100644
--- a/drivers/hid/hid-lenovo-go.c
+++ b/drivers/hid/hid-lenovo-go.c
@@ -2408,6 +2408,15 @@ static int hid_go_cfg_probe(struct hid_device *hdev,
static void hid_go_cfg_remove(struct hid_device *hdev)
{
+ /*
+ * cfg_setup is scheduled from hid_go_cfg_probe() with a 2 ms delay
+ * and dereferences drvdata.hdev. Drain it here before tearing
+ * down so the workqueue cannot run after hid_destroy_device()'s
+ * put_device() has released the underlying hdev and dereference
+ * a stale drvdata.hdev pointer.
+ */
+ cancel_delayed_work_sync(&drvdata.go_cfg_setup);
+
guard(mutex)(&drvdata.cfg_mutex);
sysfs_remove_groups(&hdev->dev.kobj, top_level_attr_groups);
hid_hw_close(hdev);
--
2.43.0
next prev parent reply other threads:[~2026-05-15 17:45 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-15 15:36 [PATCH] HID: hid-lenovo-go: cancel cfg_setup work in hid_go_cfg_remove() Manish Khadka
2026-05-15 16:18 ` sashiko-bot
2026-05-15 17:45 ` Manish Khadka [this message]
2026-05-15 18:23 ` [PATCH v2] " 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=20260515174511.78486-1-maskmemanish@gmail.com \
--to=maskmemanish@gmail.com \
--cc=bentiss@kernel.org \
--cc=derekjohn.clark@gmail.com \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mpearson-lenovo@squebb.ca \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.