[PATCH v2 1/4] HID: intel-ish-hid: fix report_list iterator pointer arithmetic

Shen Yongchao <[email protected]> Thu, 30 Jul 2026 20:52:49 +0800
Newsgroups org.kernel.vger.linux-input,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Since commit 63cafaf47a83 ("HID: ishtp-hid-client: replace
fake-flex arrays with flex-array members", v6.13), the
HOSTIF_PUBLISH_INPUT_REPORT_LIST handler iterates over sub-reports
using a struct report * pointer:

	report += sizeof(*report) + payload_len;

Because report is a struct report * (not a char *), the compiler
multiplies the advance by sizeof(struct report) = 8, making the
actual stride (8 + payload_len) * 8 bytes instead of the intended
8 + payload_len bytes.  On v6.13+ a legitimate aggregated list
with num_of_reports >= 2 drives the second iteration far outside
the message buffer.

Replace the struct report * iterator with a byte-granular u8 *pos
so the advance is computed in bytes.


Assisted-by: LLM
Signed-off-by: Shen Yongchao <[email protected]>
Fixes: 63cafaf47a83 ("HID: ishtp-hid-client: replace fake-flex arrays with flex-array members")
Cc: [email protected]
---
diff --git a/drivers/hid/intel-ish-hid/ishtp-hid-client.c b/drivers/hid/intel-ish-hid/ishtp-hid-client.c
index 6d64008f2..ba52e185c 100644
--- a/drivers/hid/intel-ish-hid/ishtp-hid-client.c
+++ b/drivers/hid/intel-ish-hid/ishtp-hid-client.c
@@ -74,6 +74,7 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
 	int report_type;
 	struct report_list *reports_list;
 	struct report *report;
+	u8 *pos;
 	size_t report_len;
 	struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
 	int curr_hid_dev = client_data->cur_hid_dev;
@@ -280,9 +281,10 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
 		case HOSTIF_PUBLISH_INPUT_REPORT_LIST:
 			report_type = HID_INPUT_REPORT;
 			reports_list = (struct report_list *)payload;
-			report = reports_list->reports;
+			pos = (u8 *)reports_list->reports;
 
 			for (j = 0; j < reports_list->num_of_reports; j++) {
+				report = (struct report *)pos;
 				recv_msg = container_of(&report->msg,
 							struct hostif_msg, hdr);
 				report_len = report->size;
@@ -303,7 +305,7 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
 						0);
 					}
 
-				report += sizeof(*report) + payload_len;
+				pos += sizeof(struct report) + payload_len;
 			}
 			break;
 		default:
@@ -956,4 +958,4 @@ MODULE_AUTHOR("Daniel Drubin <[email protected]>");
  */
 MODULE_AUTHOR("Srinivas Pandruvada <[email protected]>");
 
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL");
\ No newline at end of file