Linux Input/HID development
 help / color / mirror / Atom feed
* [PATCH 1/4] HID: elo: ignore short touch reports
@ 2026-06-28 16:35 Yousef Alhouseen
  2026-06-28 16:35 ` [PATCH 2/4] HID: cougar: reject short vendor reports Yousef Alhouseen
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Yousef Alhouseen @ 2026-06-28 16:35 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires
  Cc: Stefan Achatz, linux-input, linux-kernel, stable,
	Yousef Alhouseen

elo_process_data() reads coordinates, flags, and pressure through data[7].
The raw-event callback only checks the packet marker, so a malformed USB
device can submit a one-byte marker report and trigger out-of-bounds
reads from the input buffer.

Only process touch packets that contain all eight protocol bytes.

Fixes: d23efc19478a ("HID: add driver for ELO 4000/4500")
Cc: stable@vger.kernel.org
Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
---
 drivers/hid/hid-elo.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c
index b8f5f3eb53a4..1aeec712c67b 100644
--- a/drivers/hid/hid-elo.c
+++ b/drivers/hid/hid-elo.c
@@ -89,7 +89,7 @@ static int elo_raw_event(struct hid_device *hdev, struct hid_report *report,
 
 	switch (report->id) {
 	case 0:
-		if (data[0] == 'T') {	/* Mandatory ELO packet marker */
+		if (size >= 8 && data[0] == 'T') { /* Mandatory ELO packet marker */
 			elo_process_data(hidinput->input, data, size);
 			return 1;
 		}
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] HID: cougar: reject short vendor reports
  2026-06-28 16:35 [PATCH 1/4] HID: elo: ignore short touch reports Yousef Alhouseen
@ 2026-06-28 16:35 ` Yousef Alhouseen
  2026-06-28 16:49   ` sashiko-bot
  2026-06-28 16:35 ` [PATCH 3/4] HID: zydacron: reject short key reports Yousef Alhouseen
  2026-06-28 16:35 ` [PATCH 4/4] HID: roccat-savu: reject short special reports Yousef Alhouseen
  2 siblings, 1 reply; 6+ messages in thread
From: Yousef Alhouseen @ 2026-06-28 16:35 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires
  Cc: Stefan Achatz, linux-input, linux-kernel, stable,
	Yousef Alhouseen

cougar_raw_event() reads the key code and action from bytes one and two
of every enabled vendor-interface report. A malformed USB device can
send a shorter report and make both accesses run beyond the received
buffer.

Consume short vendor reports without parsing them.

Fixes: b8e759b8f6da ("HID: cougar: Add support for the Cougar 500k Gaming Keyboard")
Cc: stable@vger.kernel.org
Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
---
 drivers/hid/hid-cougar.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/hid/hid-cougar.c b/drivers/hid/hid-cougar.c
index ad027c45f162..7156658166f5 100644
--- a/drivers/hid/hid-cougar.c
+++ b/drivers/hid/hid-cougar.c
@@ -270,6 +270,9 @@ static int cougar_raw_event(struct hid_device *hdev, struct hid_report *report,
 	if (!shared->enabled || !shared->input)
 		return -EPERM;
 
+	if (size <= COUGAR_FIELD_ACTION)
+		return -EPERM;
+
 	code = data[COUGAR_FIELD_CODE];
 	action = data[COUGAR_FIELD_ACTION];
 	for (i = 0; cougar_mapping[i][0]; i++) {
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] HID: zydacron: reject short key reports
  2026-06-28 16:35 [PATCH 1/4] HID: elo: ignore short touch reports Yousef Alhouseen
  2026-06-28 16:35 ` [PATCH 2/4] HID: cougar: reject short vendor reports Yousef Alhouseen
@ 2026-06-28 16:35 ` Yousef Alhouseen
  2026-06-28 16:35 ` [PATCH 4/4] HID: roccat-savu: reject short special reports Yousef Alhouseen
  2 siblings, 0 replies; 6+ messages in thread
From: Yousef Alhouseen @ 2026-06-28 16:35 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires
  Cc: Stefan Achatz, linux-input, linux-kernel, stable,
	Yousef Alhouseen

The raw-event handler reads data[1] for report IDs 2 and 3 without
checking that the report includes a payload byte. A malformed USB device
can submit a report containing only the report ID and trigger an
out-of-bounds read.

Ignore the key value when the payload byte is missing.

Fixes: d0742abaa1c3 ("HID: add omitted hid-zydacron.c file")
Cc: stable@vger.kernel.org
Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
---
 drivers/hid/hid-zydacron.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c
index 1aae80f848f5..b882d2a0ba1a 100644
--- a/drivers/hid/hid-zydacron.c
+++ b/drivers/hid/hid-zydacron.c
@@ -129,6 +129,9 @@ static int zc_raw_event(struct hid_device *hdev, struct hid_report *report,
 		switch (report->id) {
 		case 0x02:
 		case 0x03:
+			if (size < 2)
+				break;
+
 			switch (data[1]) {
 			case 0x10:
 				key = KEY_MODE;
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] HID: roccat-savu: reject short special reports
  2026-06-28 16:35 [PATCH 1/4] HID: elo: ignore short touch reports Yousef Alhouseen
  2026-06-28 16:35 ` [PATCH 2/4] HID: cougar: reject short vendor reports Yousef Alhouseen
  2026-06-28 16:35 ` [PATCH 3/4] HID: zydacron: reject short key reports Yousef Alhouseen
@ 2026-06-28 16:35 ` Yousef Alhouseen
  2026-06-28 16:49   ` sashiko-bot
  2 siblings, 1 reply; 6+ messages in thread
From: Yousef Alhouseen @ 2026-06-28 16:35 UTC (permalink / raw)
  To: Jiri Kosina, Benjamin Tissoires
  Cc: Stefan Achatz, linux-input, linux-kernel, stable,
	Yousef Alhouseen

savu_report_to_chrdev() casts special reports to a five-byte structure and
reads all of its payload fields without checking the received size. A
malformed USB device can therefore trigger out-of-bounds reads from the
input buffer when the character device is claimed.

Pass the report size into the helper and require the complete structure.

Fixes: 6a2a6390cf09 ("HID: roccat: add support for Roccat Savu")
Cc: stable@vger.kernel.org
Signed-off-by: Yousef Alhouseen <alhouseenyousef@gmail.com>
---
 drivers/hid/hid-roccat-savu.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c
index 679136933560..04fa4c50cfa4 100644
--- a/drivers/hid/hid-roccat-savu.c
+++ b/drivers/hid/hid-roccat-savu.c
@@ -152,12 +152,13 @@ static void savu_remove(struct hid_device *hdev)
 }
 
 static void savu_report_to_chrdev(struct roccat_common2_device const *savu,
-		u8 const *data)
+		u8 const *data, int size)
 {
 	struct savu_roccat_report roccat_report;
 	struct savu_mouse_report_special const *special_report;
 
-	if (data[0] != SAVU_MOUSE_REPORT_NUMBER_SPECIAL)
+	if (data[0] != SAVU_MOUSE_REPORT_NUMBER_SPECIAL ||
+	    size < sizeof(*special_report))
 		return;
 
 	special_report = (struct savu_mouse_report_special const *)data;
@@ -183,7 +184,7 @@ static int savu_raw_event(struct hid_device *hdev,
 		return 0;
 
 	if (savu->roccat_claimed)
-		savu_report_to_chrdev(savu, data);
+		savu_report_to_chrdev(savu, data, size);
 
 	return 0;
 }
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/4] HID: cougar: reject short vendor reports
  2026-06-28 16:35 ` [PATCH 2/4] HID: cougar: reject short vendor reports Yousef Alhouseen
@ 2026-06-28 16:49   ` sashiko-bot
  0 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-06-28 16:49 UTC (permalink / raw)
  To: Yousef Alhouseen; +Cc: linux-input, dmitry.torokhov

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [High] `cougar_raw_event()` accesses `shared->input` without synchronization against `cougar_remove()`, leading to a potential Use-After-Free if the keyboard interface is unbound.
- [High] A deadlock occurs if `devm_add_action_or_reset()` fails during probe.
- [High] A race condition between `kref_put()` and list lookup leads to a Use-After-Free of `cougar_shared`.
--

commit 27f66ec84e2d69ee2a0830cfc45515ced43d2bb5
Author: Yousef Alhouseen <alhouseenyousef@gmail.com>

    HID: cougar: reject short vendor reports

This commit fixes an out-of-bounds read in cougar_raw_event() by ensuring
that vendor-interface reports are large enough before parsing them. Short
reports are now properly rejected with an error.

> diff --git a/drivers/hid/hid-cougar.c b/drivers/hid/hid-cougar.c
> index ad027c45f1628..7156658166f51 100644
> --- a/drivers/hid/hid-cougar.c
> +++ b/drivers/hid/hid-cougar.c
> @@ -270,6 +270,9 @@ static int cougar_raw_event(struct hid_device *hdev, struct hid_report *report,
>  	if (!shared->enabled || !shared->input)
>  		return -EPERM;
>  

[Severity: High]
This is a pre-existing issue, but is cougar_raw_event() accessing shared->input
without synchronization against cougar_remove()?

If a thread is preempted right after checking shared->enabled and shared->input,
and cougar_remove() runs concurrently, it will set shared->enabled to false and
call hid_hw_stop(). This destroys and frees the input_dev structure.

When the first thread resumes, wouldn't it pass the freed shared->input to
input_event(), resulting in a Use-After-Free?

> +	if (size <= COUGAR_FIELD_ACTION)
> +		return -EPERM;
> +
>  	code = data[COUGAR_FIELD_CODE];
>  	action = data[COUGAR_FIELD_ACTION];

[ ... ]

While reviewing this file, I noticed a couple of other pre-existing issues in
functions outside of this patch.

drivers/hid/hid-cougar.c:cougar_bind_shared_data() {
...
	mutex_lock(&cougar_udev_list_lock);
...
	error = devm_add_action_or_reset(&hdev->dev, cougar_remove_shared_data, cougar);
...
}

[Severity: High]
This isn't a bug introduced by this patch, but could this create a deadlock if
devm_add_action_or_reset() fails during probe?

If it fails, it synchronously executes the cleanup callback
cougar_remove_shared_data(), which calls kref_put(). If the refcount drops to 0,
cougar_release_shared_data() is called and attempts to acquire
cougar_udev_list_lock. Since that lock is already held by
cougar_bind_shared_data(), this would cause a deadlock.

drivers/hid/hid-cougar.c:cougar_remove_shared_data() {
...
	if (cougar->shared) {
		kref_put(&cougar->shared->kref, cougar_release_shared_data);
		cougar->shared = NULL;
	}
...
}

[Severity: High]
This is also a pre-existing issue, but might there be a race condition between
kref_put() and the list lookup?

The refcount is decremented to zero without holding cougar_udev_list_lock.
Before the object is removed from the list in cougar_release_shared_data(), a
concurrent call to cougar_get_shared_data() might iterate the list and use
kref_get() on this object while it is pending deletion.

Would using kref_get_unless_zero() during the lookup, or holding the list lock
during kref_put(), prevent this Use-After-Free?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260628163527.14279-1-alhouseenyousef@gmail.com?part=2

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 4/4] HID: roccat-savu: reject short special reports
  2026-06-28 16:35 ` [PATCH 4/4] HID: roccat-savu: reject short special reports Yousef Alhouseen
@ 2026-06-28 16:49   ` sashiko-bot
  0 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-06-28 16:49 UTC (permalink / raw)
  To: Yousef Alhouseen; +Cc: dmitry.torokhov, linux-input

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] The driver acquires a mutex in the raw_event handler path, which executes in atomic (softIRQ) context, leading to a scheduling-while-atomic bug or deadlock.
- [Medium] The roccat driver leaks the memory allocated for circular buffer reports when the device is destroyed.
--

commit 60d1ec57aac96f7ad83f249887da4a3aa3a3f7c4
Author: Yousef Alhouseen <alhouseenyousef@gmail.com>

HID: roccat-savu: reject short special reports

savu_report_to_chrdev() casts special reports to a five-byte structure and
reads all of its payload fields without checking the received size. A
malformed USB device can therefore trigger out-of-bounds reads from the
input buffer when the character device is claimed. Pass the report size
into the helper and require the complete structure.

> diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c
> index 6791369335601..04fa4c50cfa4b 100644
> --- a/drivers/hid/hid-roccat-savu.c
> +++ b/drivers/hid/hid-roccat-savu.c

[ ... ]

> @@ -183,7 +184,7 @@ static int savu_raw_event(struct hid_device *hdev,
>  		return 0;
>  
>  	if (savu->roccat_claimed)
> -		savu_report_to_chrdev(savu, data);
> +		savu_report_to_chrdev(savu, data, size);

[Severity: High]
This is a pre-existing issue, but can this lead to a scheduling-while-atomic
bug?

The savu_raw_event() callback runs in atomic context (softIRQ). When it
calls savu_report_to_chrdev(), the execution path proceeds to
roccat_report_event() in drivers/hid/hid-roccat.c, which acquires
sleeping locks:

drivers/hid/hid-roccat.c:roccat_report_event() {
    ...
    mutex_lock(&device->readers_lock);
    mutex_lock(&device->cbuf_lock);
    ...
}


[Severity: Medium]
This is also a pre-existing issue, but does this code leak the memory
allocated for circular buffer reports when the device is destroyed?

In drivers/hid/hid-roccat.c:roccat_report_event(), kmemdup() dynamically
allocates memory for the report:

    new_value = kmemdup(data, device->report_size, GFP_ATOMIC);

However, when the device is freed in roccat_release() or
roccat_disconnect() using kfree(device), the dynamically allocated report
values in the circular buffer do not appear to be cleaned up.

>  
>  	return 0;
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260628163527.14279-1-alhouseenyousef@gmail.com?part=4

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-06-28 16:49 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-28 16:35 [PATCH 1/4] HID: elo: ignore short touch reports Yousef Alhouseen
2026-06-28 16:35 ` [PATCH 2/4] HID: cougar: reject short vendor reports Yousef Alhouseen
2026-06-28 16:49   ` sashiko-bot
2026-06-28 16:35 ` [PATCH 3/4] HID: zydacron: reject short key reports Yousef Alhouseen
2026-06-28 16:35 ` [PATCH 4/4] HID: roccat-savu: reject short special reports Yousef Alhouseen
2026-06-28 16:49   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox