]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
HID: playstation: validate num_touch_reports in DualShock 4 reports
authorBenoît Sevens <bsevens@google.com>
Mon, 23 Mar 2026 12:47:37 +0000 (12:47 +0000)
committerJiri Kosina <jkosina@suse.com>
Thu, 9 Apr 2026 15:54:42 +0000 (17:54 +0200)
The DualShock 4 HID driver fails to validate the num_touch_reports field
received from the device in both USB and Bluetooth input reports.
A malicious device could set this field to a value larger than the
allocated size of the touch_reports array (3 for USB, 4 for Bluetooth),
leading to an out-of-bounds read in dualshock4_parse_report().

This can result in kernel memory disclosure when processing malicious
HID reports.

Validate num_touch_reports against the array size for the respective
connection types before processing the touch data.

Signed-off-by: Benoît Sevens <bsevens@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
drivers/hid/hid-playstation.c

index 2ec6d4445e84babf1ce7c913cbec1fea689aabd2..43c0340660c2a8c0ce4b0e5fc78ad1e3eff6a552 100644 (file)
@@ -2377,6 +2377,12 @@ static int dualshock4_parse_report(struct ps_device *ps_dev, struct hid_report *
                struct dualshock4_input_report_usb *usb =
                        (struct dualshock4_input_report_usb *)data;
 
+               if (usb->num_touch_reports > ARRAY_SIZE(usb->touch_reports)) {
+                       hid_err(hdev, "DualShock4 USB input report has invalid num_touch_reports=%d\n",
+                               usb->num_touch_reports);
+                       return -EINVAL;
+               }
+
                ds4_report = &usb->common;
                num_touch_reports = usb->num_touch_reports;
                touch_reports = usb->touch_reports;
@@ -2391,6 +2397,12 @@ static int dualshock4_parse_report(struct ps_device *ps_dev, struct hid_report *
                        return -EILSEQ;
                }
 
+               if (bt->num_touch_reports > ARRAY_SIZE(bt->touch_reports)) {
+                       hid_err(hdev, "DualShock4 BT input report has invalid num_touch_reports=%d\n",
+                               bt->num_touch_reports);
+                       return -EINVAL;
+               }
+
                ds4_report = &bt->common;
                num_touch_reports = bt->num_touch_reports;
                touch_reports = bt->touch_reports;