Linux Input/HID development
 help / color / mirror / Atom feed
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

  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