[PATCH v3] HID: hid-oxp: fix UAF on pending work in remove()

"Shengzhuo Wei" <[email protected]>
Newsgroups org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
oxp_cfg_probe() arms drvdata.oxp_mcu_init to run 50 ms after probe, and
oxp_mcu_init_fn() dereferences drvdata.hdev to issue MCU output reports
(hid_hw_output_report() followed by msleep(200)). The oxp_rgb_queue and
oxp_btn_queue workers are wired up the same way. oxp_hid_remove()
cancels all three with the non-synchronising cancel_delayed_work(), so a
worker already running is not waited for; removing the device while a
worker is asleep then frees the hid_device underneath it, leaving
drvdata.hdev stale -- a use-after-free when the worker wakes.

Drain all three works with cancel_delayed_work_sync() in oxp_hid_remove()
so they have exited before the hid_device is freed.

Fixes: 84910c459d65 ("HID: hid-oxp: Add OneXPlayer configuration driver")
Fixes: e4c850a6e750 ("HID: hid-oxp: Add Button Mapping Interface")
Fixes: 2f424f28fb39 ("HID: hid-oxp: Add Second Generation Gamepad Mode Switch")
Cc: [email protected]
Signed-off-by: Shengzhuo Wei <[email protected]>
---
Same delayed-work use-after-free class as the 7.2-rc6 sweep
(hid-lenovo-go, hid-lenovo-go-s, hid-lg-g15, hid-appleir, hid-letsketch);
hid-oxp was missed.
---
Changes in v3:
- Revert to cancel_delayed_work_sync() and drop v2's probe-change
  reordering: with the driver's static global drvdata,
  disable_delayed_work_sync() would permanently disable the works when
  any interface of the device is unbound (Derek J. Clark). The re-arm
  hardening and the per-device drvdata rework will be handled separately
  by the driver maintainer.
- Link to v2: https://lore.kernel.org/r/[email protected]

Changes in v2:
- Use disable_delayed_work_sync() instead of cancel_delayed_work_sync()
  so the works cannot be re-armed (e.g. via oxp_rgb_brightness_set())
  while the device is being torn down (Dmitry Torokhov).
- Arm oxp_mcu_init only after devm_device_add_group() succeeds, so a
  probe failure can no longer leave it pending to fire on a freed
  hid device (sashiko).
- Link to v1: https://lore.kernel.org/r/[email protected]
---
 drivers/hid/hid-oxp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-oxp.c b/drivers/hid/hid-oxp.c
index 20a54f337220dc2aee3483a14d542b66c487bd60..d8fb6a69d40d43f2595179df1067d42b4b3e166a 100644
--- a/drivers/hid/hid-oxp.c
+++ b/drivers/hid/hid-oxp.c
@@ -1552,9 +1552,9 @@ static int oxp_hid_probe(struct hid_device *hdev,
 
 static void oxp_hid_remove(struct hid_device *hdev)
 {
-	cancel_delayed_work(&drvdata.oxp_rgb_queue);
-	cancel_delayed_work(&drvdata.oxp_btn_queue);
-	cancel_delayed_work(&drvdata.oxp_mcu_init);
+	cancel_delayed_work_sync(&drvdata.oxp_rgb_queue);
+	cancel_delayed_work_sync(&drvdata.oxp_btn_queue);
+	cancel_delayed_work_sync(&drvdata.oxp_mcu_init);
 	hid_hw_close(hdev);
 	hid_hw_stop(hdev);
 }

---
base-commit: 075b74841bd0065a3bda3440873c747938e69b68
change-id: 20260804-oxp-fix-879390c5e47f

Best regards,
-- 
Shengzhuo Wei <[email protected]>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.