[PATCH] HID: playstation: Clamp num_touch_reports

T.J. Mercier posted 1 patch 1 month, 4 weeks ago
drivers/hid/hid-playstation.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
[PATCH] HID: playstation: Clamp num_touch_reports
Posted by T.J. Mercier 1 month, 4 weeks ago
A device would never lie about the number of touch reports would it?

If it does the loop in dualshock4_parse_report will read off the end of
the touch_reports array, up to about 2 KiB for the maximum number of 256
loop iteraions. The data that is read is emitted via evdev if the
DS4_TOUCH_POINT_INACTIVE bit happens to be set. Protect against this by
clamping the num_touch_reports value provided by the device to the
maximum size of the touch_reports array.

Fixes: 752038248808 ("HID: playstation: add DualShock4 touchpad support.")
Cc: stable@vger.kernel.org
Reported-by: Xingyu Jin <xingyuj@google.com>
Signed-off-by: T.J. Mercier <tjmercier@google.com>
---
 drivers/hid/hid-playstation.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c
index 3c0db8f93c82..8d06ddff356a 100644
--- a/drivers/hid/hid-playstation.c
+++ b/drivers/hid/hid-playstation.c
@@ -2378,7 +2378,8 @@ static int dualshock4_parse_report(struct ps_device *ps_dev, struct hid_report *
 			(struct dualshock4_input_report_usb *)data;
 
 		ds4_report = &usb->common;
-		num_touch_reports = usb->num_touch_reports;
+		num_touch_reports = min_t(u8, usb->num_touch_reports,
+					  ARRAY_SIZE(usb->touch_reports));
 		touch_reports = usb->touch_reports;
 	} else if (hdev->bus == BUS_BLUETOOTH && report->id == DS4_INPUT_REPORT_BT &&
 		   size == DS4_INPUT_REPORT_BT_SIZE) {
@@ -2392,7 +2393,8 @@ static int dualshock4_parse_report(struct ps_device *ps_dev, struct hid_report *
 		}
 
 		ds4_report = &bt->common;
-		num_touch_reports = bt->num_touch_reports;
+		num_touch_reports = min_t(u8, bt->num_touch_reports,
+					  ARRAY_SIZE(bt->touch_reports));
 		touch_reports = bt->touch_reports;
 	} else if (hdev->bus == BUS_BLUETOOTH &&
 		   report->id == DS4_INPUT_REPORT_BT_MINIMAL &&

base-commit: 3cd8b194bf3428dfa53120fee47e827a7c495815
-- 
2.54.0.rc1.513.gad8abe7a5a-goog
Re: [PATCH] HID: playstation: Clamp num_touch_reports
Posted by Jiri Kosina 1 month ago
On Fri, 17 Apr 2026, T.J. Mercier wrote:

> A device would never lie about the number of touch reports would it?
> 
> If it does the loop in dualshock4_parse_report will read off the end of
> the touch_reports array, up to about 2 KiB for the maximum number of 256
> loop iteraions. The data that is read is emitted via evdev if the
> DS4_TOUCH_POINT_INACTIVE bit happens to be set. Protect against this by
> clamping the num_touch_reports value provided by the device to the
> maximum size of the touch_reports array.
> 
> Fixes: 752038248808 ("HID: playstation: add DualShock4 touchpad support.")
> Cc: stable@vger.kernel.org
> Reported-by: Xingyu Jin <xingyuj@google.com>
> Signed-off-by: T.J. Mercier <tjmercier@google.com>

Applied, thanks.

-- 
Jiri Kosina
SUSE Labs
Re: [PATCH] HID: playstation: Clamp num_touch_reports
Posted by T.J. Mercier 1 month ago
On Tue, May 12, 2026 at 8:55 AM Jiri Kosina <jikos@kernel.org> wrote:
>
> On Fri, 17 Apr 2026, T.J. Mercier wrote:
>
> > A device would never lie about the number of touch reports would it?
> >
> > If it does the loop in dualshock4_parse_report will read off the end of
> > the touch_reports array, up to about 2 KiB for the maximum number of 256
> > loop iteraions. The data that is read is emitted via evdev if the
> > DS4_TOUCH_POINT_INACTIVE bit happens to be set. Protect against this by
> > clamping the num_touch_reports value provided by the device to the
> > maximum size of the touch_reports array.
> >
> > Fixes: 752038248808 ("HID: playstation: add DualShock4 touchpad support.")
> > Cc: stable@vger.kernel.org
> > Reported-by: Xingyu Jin <xingyuj@google.com>
> > Signed-off-by: T.J. Mercier <tjmercier@google.com>
>
> Applied, thanks.
>
> --
> Jiri Kosina
> SUSE Labs

Hi Jiri,

Thanks for applying this. However now I see that a different fix from
Benoît Sevens from around the same time has landed:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=82a4fc46330910b4c1d9b189561439d468e3ff11

That fix was not yet present at
3cd8b194bf3428dfa53120fee47e827a7c495815 which I used as my base.

His patch prints and returns an error in this situation while mine
silently avoids the OOB read.

So I think it probably makes sense to keep Benoît's patch, and drop
mine since his code means mine will never be reached.

Thanks,
T.J.