All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hui Peng <benquike@gmail.com>
To: jikos@kernel.org, bentiss@kernel.org
Cc: linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] HID: fix sony Rock Band 3 IRQ sleep and hid_debug_events_read() UAF
Date: Sat, 19 Sep 2026 22:26:30 +0000	[thread overview]
Message-ID: <20260919222630.3798292-1-benquike@gmail.com> (raw)

Fix two issues in drivers/hid/:

1. In sony_raw_event() (drivers/hid/hid-sony.c), defer the Rock Band 3
   Pro controller full-report feature request to sony_state_worker()
   instead of calling hid_hw_raw_request() synchronously from interrupt
   context.
2. In hid_debug_events_read() and hid_debug_events_release()
   (drivers/hid/hid-debug.c), remove list->node from hdev->debug_list
   under hdev->debug_list_lock before freeing or when hdev is unbound so
   hid_dump_input() cannot access a freed debug list entry.

Fixes: bd28ce008bdc ("HID: move sony quirks")
Assisted-by: LLM
Signed-off-by: Hui Peng <benquike@gmail.com>
---
diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c
index f44e6e708404..edc45ca9e024 100644
--- a/drivers/hid/hid-debug.c
+++ b/drivers/hid/hid-debug.c
@@ -3728,15 +3728,14 @@ static ssize_t hid_debug_events_read(struct file *file, char __user *buffer,
 				break;
 			}
 
-			/* if list->hdev is NULL we cannot remove_wait_queue().
-			 * if list->hdev->debug is 0 then hid_debug_unregister()
-			 * was already called and list->hdev is being destroyed.
-			 * if we add remove_wait_queue() here we can hit a race.
+			/* if list->hdev->debug is 0 then hid_debug_unregister()
+			 * was already called; break out of the wait loop so
+			 * remove_wait_queue() is unconditionally called before
+			 * returning.
 			 */
 			if (!list->hdev || !list->hdev->debug) {
 				ret = -EIO;
-				__set_current_state(TASK_RUNNING);
-				goto out;
+				break;
 			}
 
 			if (file->f_flags & O_NONBLOCK) {
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 50f5ad6bbeb4..d3862ddf68c9 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -561,6 +561,7 @@ struct sony_sc {
 
 	/* Rock Band 3 Pro Instruments */
 	unsigned long rb3_pro_poke_jiffies;
+	struct work_struct rb3_pro_poke_work;
 };
 
 static void sony_set_leds(struct sony_sc *sc);
@@ -657,6 +658,14 @@ static int rb3_pro_instrument_enable_full_report(struct sony_sc *sc)
 	return ret;
 }
 
+static void rb3_pro_poke_worker(struct work_struct *work)
+{
+	struct sony_sc *sc = container_of(work, struct sony_sc,
+					  rb3_pro_poke_work);
+
+	rb3_pro_instrument_enable_full_report(sc);
+}
+
 static int djh_turntable_mapping(struct hid_device *hdev, struct hid_input *hi,
 			  struct hid_field *field, struct hid_usage *usage,
 			  unsigned long **bit, int *max)
@@ -1101,7 +1110,7 @@ static int rb3_pro_instrument_raw_event(struct sony_sc *sc, u8 *rd, int size)
 	/* Only attempt to enable full report every 8 seconds */
 	if (time_after(jiffies, sc->rb3_pro_poke_jiffies)) {
 		sc->rb3_pro_poke_jiffies = jiffies + secs_to_jiffies(8);
-		rb3_pro_instrument_enable_full_report(sc);
+		schedule_work(&sc->rb3_pro_poke_work);
 	}
 
 	return 0;
@@ -2124,6 +2133,8 @@ static inline void sony_cancel_work_sync(struct sony_sc *sc)
 		}
 		cancel_work_sync(&sc->state_worker);
 	}
+	if (sc->quirks & RB3_PRO_INSTRUMENT)
+		cancel_work_sync(&sc->rb3_pro_poke_work);
 }
 
 static void sony_cleanup(struct sony_sc *sc)
@@ -2350,6 +2361,11 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 	hid_set_drvdata(hdev, sc);
 	sc->hdev = hdev;
 
+	if (sc->quirks & RB3_PRO_INSTRUMENT) {
+		sc->rb3_pro_poke_jiffies = 0;
+		INIT_WORK(&sc->rb3_pro_poke_work, rb3_pro_poke_worker);
+	}
+
 	ret = hid_parse(hdev);
 	if (ret) {
 		hid_err(hdev, "parse failed\n");
@@ -2391,9 +2407,6 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		goto err;
 	}
 
-	if (sc->quirks & RB3_PRO_INSTRUMENT)
-		sc->rb3_pro_poke_jiffies = 0;
-
 	if (sc->quirks & (GHL_GUITAR_PS3WIIU | GHL_GUITAR_PS4)) {
 		if (!hid_is_usb(hdev)) {
 			ret = -EINVAL;

             reply	other threads:[~2026-09-19 22:26 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-19 22:26 Hui Peng [this message]
2026-09-19 22:52 ` [PATCH] HID: fix sony Rock Band 3 IRQ sleep and hid_debug_events_read() UAF 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=20260919222630.3798292-1-benquike@gmail.com \
    --to=benquike@gmail.com \
    --cc=bentiss@kernel.org \
    --cc=jikos@kernel.org \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /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.