From: Benoît Sevens Date: Mon, 23 Mar 2026 12:47:37 +0000 (+0000) Subject: HID: playstation: validate num_touch_reports in DualShock 4 reports X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=82a4fc46330910b4c1d9b189561439d468e3ff11;p=thirdparty%2Fkernel%2Flinux.git HID: playstation: validate num_touch_reports in DualShock 4 reports 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 Signed-off-by: Jiri Kosina --- diff --git a/drivers/hid/hid-playstation.c b/drivers/hid/hid-playstation.c index 2ec6d4445e84b..43c0340660c2a 100644 --- a/drivers/hid/hid-playstation.c +++ b/drivers/hid/hid-playstation.c @@ -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;