From: sashiko-bot@kernel.org
To: "Shen Yongchao" <grayhat@foxmail.com>
Cc: linux-input@vger.kernel.org, dmitry.torokhov@gmail.com
Subject: Re: [PATCH v2 1/4] HID: intel-ish-hid: fix report_list iterator pointer arithmetic
Date: Thu, 30 Jul 2026 13:17:49 +0000 [thread overview]
Message-ID: <20260730131750.3D05A1F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <tencent_F203F6206515915C81D1210ECEBCBCA5D707@qq.com>
Thank you for your contribution! Sashiko AI review found 7 potential issue(s) to consider:
Pre-existing issues:
- [High] Missing validation of `hid_dev_count` against `MAX_HID_DEVICES` allows firmware to trigger out-of-bounds array accesses.
- [High] Missing boundary checks when iterating over aggregated reports in `HOSTIF_PUBLISH_INPUT_REPORT_LIST`.
- [High] Integer underflow when calculating `payload_len` in `HOSTIF_PUBLISH_INPUT_REPORT_LIST`.
- [High] Insufficient bounds checking when parsing `device_info` structures in `HOSTIF_DM_ENUM_DEVICES`.
- [High] The inner loop handling HOSTIF_PUBLISH_INPUT_REPORT_LIST overwrites the outer loop's control variables, causing parser desynchronization.
- [High] Missing cancellation of asynchronous background works on device removal leads to Use-After-Free.
- [High] Missing buffer reallocation during hardware reset allows out-of-bounds writes if device attributes expand.
--
--- Patch [1]: [PATCH v2 1/4] HID: intel-ish-hid: fix report_list iterator pointer arithmetic ---
commit 57fdd01a4139a53de9833b822824ccfd37902302
Author: Shen Yongchao <grayhat@foxmail.com>
HID: intel-ish-hid: fix report_list iterator pointer arithmetic
This commit fixes an issue where the report iterator pointer was being
advanced by a multiple of the struct size rather than bytes. It introduces
a u8 *pos iterator to correctly compute the pointer arithmetic in bytes.
> diff --git a/drivers/hid/intel-ish-hid/ishtp-hid-client.c b/drivers/hid/intel-ish-hid/ishtp-hid-client.c
> index 6d64008f2ce05..ba52e185ce051 100644
> --- a/drivers/hid/intel-ish-hid/ishtp-hid-client.c
> +++ b/drivers/hid/intel-ish-hid/ishtp-hid-client.c
[ ... ]
> @@ -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++) {
[Severity: High]
This is a pre-existing issue, but does this loop lack boundary checks?
If the firmware sends malformed packets in HOSTIF_PUBLISH_INPUT_REPORT_LIST,
could we iterate past the end of the containing message or network buffer?
There don't appear to be bounds checks on pos and the sub-report payloads.
> + report = (struct report *)pos;
> recv_msg = container_of(&report->msg,
> struct hostif_msg, hdr);
> report_len = report->size;
[Severity: High]
This is a pre-existing issue, but can this lead to an integer underflow?
When calculating payload_len:
payload_len = report_len - sizeof(struct hostif_msg_hdr);
If a sub-report is sent with report->size less than
sizeof(struct hostif_msg_hdr), will this underflow the size_t variable to a
huge value, which is then passed to hid_input_report() and used to advance
the pos pointer?
[Severity: High]
This is a pre-existing issue, but does the inner loop overwrite the outer
loop's control variables?
The inner loop modifies payload and payload_len:
payload = recv_msg->payload;
payload_len = report_len - sizeof(struct hostif_msg_hdr);
Once this switch statement finishes, the outer loop uses payload_len to
advance cur_pos:
msg_len = payload_len + sizeof(struct hostif_msg);
if (!cur_pos && cur_pos + msg_len < total_len)
++client_data->multi_packet_cnt;
cur_pos += msg_len;
Could the corrupted payload_len (now the size of the last sub-report instead
of the aggregate list) cause parser desynchronization and out-of-bounds reads
on the next iteration?
> @@ -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:
While reviewing this, I also noticed a few other pre-existing issues in
this driver.
[Severity: High]
This is a pre-existing issue, but is there missing validation of
hid_dev_count against MAX_HID_DEVICES?
In process_recv() during HOSTIF_DM_ENUM_DEVICES:
client_data->hid_dev_count = (unsigned int)*payload;
If the firmware sends a count greater than MAX_HID_DEVICES, the driver
directly assigns this without validation. Could subsequent loops use this to
access fixed-size arrays like hid_descr and report_descr out of bounds,
corrupting memory?
[Severity: High]
This is a pre-existing issue, but does this allocation logic miss buffer
reallocation during a hardware reset?
During enumeration:
if (!client_data->hid_devices)
client_data->hid_devices = devm_kcalloc(...);
And later:
for (i = 0; i < client_data->hid_dev_count; ++i) {
If a hardware reset occurs and hid_ishtp_cl_reset_handler() retriggers
enumeration, the check bypasses reallocation. If the firmware returns a
larger hid_dev_count after reset, could the loop write device info past
the end of the existing heap buffer?
[Severity: High]
This is a pre-existing issue, but is the boundary check sufficient when
parsing device_info structures?
In the same ENUM_DEVICES loop:
if (1 + sizeof(struct device_info) * i >= data_len)
break;
This compares an offset relative to payload (which is already past the header)
against the total data_len. It also only checks the start offset of the struct
rather than the end. Could this allow memcpy to read up to
sizeof(struct device_info) + sizeof(struct hostif_msg_hdr) - 1 bytes past
the actual recv_buf?
[Severity: High]
This is a pre-existing issue, but does hid_ishtp_cl_remove() need to
cancel background works?
drivers/hid/intel-ish-hid/ishtp-hid-client.c:hid_ishtp_cl_remove() {
...
ishtp_cl_driver_unregister(&hid_ishtp_cl_driver);
...
}
This teardown function unregisters the driver but does not call
cancel_work_sync() for client_data->work or client_data->resume_work. Since
client_data is allocated with devm_kzalloc(), it is automatically freed when
remove returns. If a reset or resume work is executing or queued concurrently,
could this lead to a Use-After-Free?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260730115600.218172-1-grayhat@foxmail.com?part=1
next prev parent reply other threads:[~2026-07-30 13:17 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260730115600.218172-1-grayhat@foxmail.com>
2026-07-30 12:52 ` [PATCH v2 1/4] HID: intel-ish-hid: fix report_list iterator pointer arithmetic Shen Yongchao
2026-07-30 13:17 ` sashiko-bot [this message]
2026-07-30 12:52 ` [PATCH v2 2/4] HID: intel-ish-hid: bound report_list iteration to message size Shen Yongchao
2026-07-30 13:08 ` sashiko-bot
2026-07-30 12:52 ` [PATCH v2 3/4] HID: intel-ish-hid: prevent size_t underflow in report_list parsing Shen Yongchao
2026-07-30 13:11 ` sashiko-bot
2026-07-30 12:52 ` [PATCH v2 4/4] HID: intel-ish-hid: add full entry bounds check to " Shen Yongchao
2026-07-30 13:09 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260730131750.3D05A1F00A3D@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dmitry.torokhov@gmail.com \
--cc=grayhat@foxmail.com \
--cc=linux-input@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox