All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Yousef Alhouseen" <alhouseenyousef@gmail.com>
Cc: dmitry.torokhov@gmail.com, linux-input@vger.kernel.org
Subject: Re: [PATCH] HID: mcp2221: reject short input reports
Date: Sun, 28 Jun 2026 09:51:01 +0000	[thread overview]
Message-ID: <20260628095102.105A41F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260628093658.43445-1-alhouseenyousef@gmail.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Use-After-Free and kernel stack corruption due to un-cleared mcp->rxbuf on timeout.
- [Critical] Stack buffer overflow due to using uninitialized memory as I2C read length.
- [High] Delayed USB reports indiscriminately complete pending waits, causing state desynchronization.
- [High] Static retries variable underflow causes infinite loop of workqueue rescheduling.
--

commit 421d556dea19ceb8f40a640c782b6801d60f43cd
Author: Yousef Alhouseen <alhouseenyousef@gmail.com>

HID: mcp2221: reject short input reports

The MCP2221 raw-event callback reads fixed offsets from the 64-byte input
report, including data[50] and a variable payload beginning at data[4].
This rejects reports whose size does not match the protocol and completes
the pending command with -EMSGSIZE.

Closes: https://syzkaller.appspot.com/bug?extid=1018672fe70298606e5f

> diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c
> index e4ddd8e9293b6..311b51c17b4e4 100644
> --- a/drivers/hid/hid-mcp2221.c
> +++ b/drivers/hid/hid-mcp2221.c
> @@ -861,6 +861,12 @@ static int mcp2221_raw_event(struct hid_device *hdev,
>  	u8 *buf;
>  	struct mcp2221 *mcp = hid_get_drvdata(hdev);
>  
> +	if (size != sizeof(mcp->txbuf)) {
> +		mcp->status = -EMSGSIZE;
> +		complete(&mcp->wait_in_report);
> +		return 1;
> +	}
> +

[Severity: High]
This is a pre-existing issue, but does mcp2221_raw_event() indiscriminately
complete pending waits for any incoming report without matching it to the
pending request?

If a previous request times out, and a delayed USB response arrives later,
it appears it could prematurely wake up a new command's wait queue with
incorrect status and data:

drivers/hid/hid-mcp2221.c:mcp2221_raw_event() {
	...
	case MCP2221_I2C_WR_DATA:
	...
		complete(&mcp->wait_in_report);
		break;
	...
}

[Severity: Critical]
This isn't a bug introduced by this patch, but can this lead to stack
corruption if a request times out?

In mcp_i2c_smbus_read(), if mcp_send_data_req_status() fails or times out,
it returns immediately without clearing mcp->rxbuf:

drivers/hid/hid-mcp2221.c:mcp_i2c_smbus_read() {
	...
	ret = mcp_send_data_req_status(mcp, mcp->txbuf, 4);
	if (ret)
		return ret;
	...
}

Since mcp->rxbuf can point to a caller-provided stack buffer (like
union i2c_smbus_data), the stack frame is popped upon return. If a delayed
USB response arrives later, wouldn't mcp2221_raw_event() blindly write into
this dangling mcp->rxbuf pointer?

drivers/hid/hid-mcp2221.c:mcp2221_raw_event() {
	...
			if (data[2] == MCP2221_I2C_READ_COMPL ||
			    data[2] == MCP2221_I2C_READ_PARTIAL) {
				...
				buf = mcp->rxbuf;
				memcpy(&buf[mcp->rxbuf_idx], &data[4], data[3]);
	...
}

[Severity: Critical]
This is a pre-existing issue, but does mcp_smbus_xfer() use uninitialized
stack memory as the I2C read length during a block read?

drivers/hid/hid-mcp2221.c:mcp_smbus_xfer() {
	...
			ret = mcp_i2c_smbus_read(mcp, NULL,
						MCP2221_I2C_RD_RPT_START,
						addr, data->block[0] + 1,
						data->block);
	...
}

The union i2c_smbus_data provided by the caller is uninitialized stack memory
on read. This configures mcp->rxbuf_size to an arbitrarily large value. Could
this lead to a massive stack buffer overflow when mcp2221_raw_event() copies
up to this value into the statically sized 34-byte data->block stack buffer?

[Severity: High]
This is a pre-existing issue, but could the statically scoped retries variable
in mcp_init_work() cause an infinite reschedule loop?

drivers/hid/hid-mcp2221.c:mcp_init_work() {
	static int retries = 5;
	...
reschedule_task:
	...
	if (!retries--)
		return;

	/* Device is not ready to read SRAM or FLASH data, try again */
	schedule_delayed_work(&mcp->init_work, msecs_to_jiffies(100));
}

Since retries is static, when initialization fails 6 times, it reaches 0,
returns, and decrements to -1. On a subsequent failure, retries starts at -1.
Because !(-1) is false, it bypasses the return, decrements to -2, and
unconditionally schedules the delayed work every 100ms forever.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260628093658.43445-1-alhouseenyousef@gmail.com?part=1

      reply	other threads:[~2026-06-28  9:51 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-28  9:36 [PATCH] HID: mcp2221: reject short input reports Yousef Alhouseen
2026-06-28  9:51 ` sashiko-bot [this message]

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=20260628095102.105A41F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=alhouseenyousef@gmail.com \
    --cc=dmitry.torokhov@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.