Linux Input/HID development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Michael Zaidman" <michael.zaidman@gmail.com>
Cc: linux-input@vger.kernel.org, dmitry.torokhov@gmail.com
Subject: Re: [PATCH 04/13] HID: ft260: i2c: reduce driver module loading time
Date: Sat, 22 Aug 2026 21:51:34 +0000	[thread overview]
Message-ID: <20260822215134.D51EB1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260822213941.98882-5-michael.zaidman@gmail.com>

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

New issues:
- [High] The dynamic I2C read timeout incorrectly applies a 25ms timeout for last-chunk reads up to 180 bytes, causing spurious timeouts for chunks > 60 bytes.
- [High] Delayed USB HID reports from prematurely timed-out I2C transactions corrupt subsequent I2C transfers.

Pre-existing issues:
- [Critical] Double free of `dev` on UART probe error path.
- [High] The driver frees its private data before stopping hardware I/O, allowing asynchronous incoming HID reports to cause a use-after-free.
- [High] Race condition in teardown sequence of wakeup timer and workqueue leads to Use-After-Free on device unplug.
- [High] A malicious USB device can cause a divide-by-zero kernel panic by reporting a 0 Hz clock.
--

--- Patch [4]: [PATCH 04/13] HID: ft260: i2c: reduce driver module loading time ---
commit ce4834500e105e8a3ed2770b588049de28ffe3cf
Author: Michael Zaidman <michael.zaidman@gmail.com>

HID: ft260: i2c: reduce driver module loading time

The commit adjusts the I2C read timeout to depend on the amount of data
being read. This is intended to reduce the module loading time significantly,
lowering the lm75 address range scan time to about 200ms.

> diff --git a/drivers/hid/hid-ft260.c b/drivers/hid/hid-ft260.c
> index cc3b8f5791dea..4435a39fce239 100644
> --- a/drivers/hid/hid-ft260.c
> +++ b/drivers/hid/hid-ft260.c
[ ... ]
> @@ -732,10 +739,12 @@ static int ft260_i2c_read(struct ft260_device *dev, u8 addr, u8 *data,
>  		flag = 0;	/* no fresh START - continue current transaction */
>  	do {
>  		if (len <= rd_data_max) {
> +			timeout = FT260_RD_ONE_REPORT_TO;

[Severity: High]
Does this logic aggressively override the timeout to 25ms for the final
chunk of any transfer, even if that chunk is 180 bytes long?

If an I2C read request is made where the final chunk is between 61 and 180
bytes (e.g., a 240-byte read), the condition if (len <= rd_data_max)
correctly matches the final chunk, but erroneously assigns it the
FT260_RD_ONE_REPORT_TO (25ms) timeout instead of the required 75ms.

As noted in the commit message, a 180-byte chunk physically requires about
27ms of wire time at 60kHz. A 25ms timeout is guaranteed to expire before the
hardware finishes, which could lead to a deterministic failure (-ETIMEDOUT)
on any I2C read larger than 60 bytes.

>  			rd_len = len;
>  			if (want_stop)
>  				flag |= FT260_FLAG_STOP;
>  		} else {
> +			timeout = FT260_RD_MULTI_REPORT_TO;
>  			rd_len = rd_data_max;
>  		}
>  		rd_data_max = FT260_RD_DATA_MAX;
[ ... ]
> @@ -762,8 +771,8 @@ static int ft260_i2c_read(struct ft260_device *dev, u8 addr, u8 *data,
>  			goto ft260_i2c_read_exit;
>  		}
>  
> -		timeout = msecs_to_jiffies(5000);
> -		if (!wait_for_completion_timeout(&dev->wait, timeout)) {
> +		timeout_jiffies = msecs_to_jiffies(timeout);
> +		if (!wait_for_completion_timeout(&dev->wait, timeout_jiffies)) {

[Severity: High]
Will the drastic reduction of the timeout bounds without a concurrent
mechanism to purge the HID input queue or use sequence numbers expose the
driver to data corruption?

If a premature timeout occurs in ft260_i2c_read() due to the reduced bounds,
it causes the function to clear dev->read_buf and return. However, the USB
host controller may still receive the delayed response.

When a subsequent I2C read starts, it repopulates dev->read_buf. Since
ft260_raw_event() lacks sequence numbers, could it blindly copy the stale
delayed USB report into the new buffer and call complete(), allowing the new
transaction to complete with invalid data?

>  			ret = -ETIMEDOUT;
>  			ft260_i2c_reset(hdev);
>  			goto ft260_i2c_read_exit;

[Severity: High]
This isn't a bug introduced by this patch, but does the driver free its
private data before stopping hardware I/O, allowing asynchronous incoming HID
reports to cause a use-after-free?

In ft260_remove():

	} else {
		// ...
		kfree(dev);
	}

	hid_hw_close(hdev);
	hid_hw_stop(hdev);

During device unplug, the driver unconditionally frees its private dev
structure before calling hid_hw_stop(hdev). Because the hardware and the USB
interrupt IN endpoint remain active until hid_hw_stop() is called, an
incoming HID report during this window will be dispatched to
ft260_raw_event(), which will attempt to acquire dev->read_lock on the
already freed dev memory.

[Severity: Critical]
This isn't a bug introduced by this patch, but is there a double free of dev
on the UART probe error path?

In ft260_probe():

hid_fail:
	kfree(dev);
alloc_fail:

If ft260_uart_probe() fails, it jumps to the error path and calls
ft260_uart_port_remove(dev). This triggers tty_port_put(), which drops the
final reference and calls ft260_uart_port_destroy(), explicitly freeing dev
via kfree(port).

The function then returns a failure code to ft260_probe(), which follows its
own error path to hid_fail where it executes kfree(dev) a second time on the
same pointer.

[Severity: High]
This isn't a bug introduced by this patch, but is there a race condition in
the teardown sequence of the wakeup timer and workqueue that leads to a
use-after-free on device unplug?

In ft260_remove():

	cancel_work_sync(&dev->wakeup_work);
	tty_port_unregister_device(&dev->port, ft260_tty_driver, dev->index);
	ft260_uart_port_remove(dev);

The cancel_work_sync() is executed before timer_delete_sync() (called within
ft260_uart_port_remove()), which fails to guarantee the workqueue will remain
empty.

Because the timer can fire between these two calls, ft260_uart_start_wakeup()
can erroneously call schedule_work() to re-enqueue the work. Once unbind
completes and dev is freed via the TTY destructor, the pending work executes
and accesses freed memory.

[Severity: High]
This isn't a bug introduced by this patch, but can a malicious USB device
cause a divide-by-zero kernel panic by reporting a 0 Hz clock?

In ft260_hid_output_report_check_status():

	/* transfer time = 1 / clock(KHz) * 9 bits * bytes */
	usec = len * 9000 / dev->clock;

The unvalidated clock value read from the hardware is used directly as a
divisor. If a malicious or malfunctioning USB device responds to the
FT260_I2C_STATUS feature request in ft260_xfer_status() with a report.clock
value of 0, the driver saves this to dev->clock without validation.
Subsequent calls will divide by dev->clock to calculate delay timings,
immediately crashing the kernel.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260822213941.98882-1-michael.zaidman@gmail.com?part=4

  reply	other threads:[~2026-08-22 21:51 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-22 21:39 [PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes Michael Zaidman
2026-08-22 21:39 ` [PATCH 01/13] HID: ft260: add serial driver Michael Zaidman
2026-08-22 22:00   ` sashiko-bot
2026-08-25  7:49   ` Linus Walleij
2026-08-25  8:12   ` Linus Walleij
2026-08-27 19:16     ` Michael Zaidman
2026-08-22 21:39 ` [PATCH 02/13] HID: ft260: uart: bring-up fixes Michael Zaidman
2026-08-22 21:56   ` sashiko-bot
2026-08-22 21:39 ` [PATCH 03/13] HID: ft260: add GPIO support on top of UART Michael Zaidman
2026-08-22 21:56   ` sashiko-bot
2026-08-25  7:44   ` Linus Walleij
2026-08-27 20:39     ` Michael Zaidman
2026-08-22 21:39 ` [PATCH 04/13] HID: ft260: i2c: reduce driver module loading time Michael Zaidman
2026-08-22 21:51   ` sashiko-bot [this message]
2026-08-22 21:39 ` [PATCH 05/13] HID: ft260: i2c: silence sysfs store big-numbers Michael Zaidman
2026-08-22 21:51   ` sashiko-bot
2026-08-22 21:39 ` [PATCH 06/13] HID: ft260: i2c: reduce bus-error message severity Michael Zaidman
2026-08-22 21:52   ` sashiko-bot
2026-08-22 21:39 ` [PATCH 07/13] HID: ft260: uart: enable flow control Michael Zaidman
2026-08-22 21:52   ` sashiko-bot
2026-08-22 21:39 ` [PATCH 08/13] HID: ft260: uart: add modem pins control via ioctl Michael Zaidman
2026-08-22 21:54   ` sashiko-bot
2026-08-25  8:08   ` Linus Walleij
2026-08-27 22:08     ` Michael Zaidman
2026-08-22 21:39 ` [PATCH 09/13] HID: ft260: gpio: group sysfs attrs per HID interface Michael Zaidman
2026-08-22 21:54   ` sashiko-bot
2026-08-25  8:13   ` Linus Walleij
2026-08-27 20:50     ` Michael Zaidman
2026-08-22 21:39 ` [PATCH 10/13] HID: ft260: uart: fix active-low RTS/CTS/DTR/DSR polarity Michael Zaidman
2026-08-22 22:03   ` sashiko-bot
2026-08-25  8:16   ` Linus Walleij
2026-08-27 21:08     ` Michael Zaidman
2026-08-22 21:39 ` [PATCH 11/13] HID: ft260: i2c: fix large write transaction failure Michael Zaidman
2026-08-22 22:02   ` sashiko-bot
2026-08-22 21:39 ` [PATCH 12/13] HID: ft260: workaround for TN_189 errata endpoint STALL after enumeration Michael Zaidman
2026-08-22 22:03   ` sashiko-bot
2026-08-22 21:39 ` [PATCH 13/13] HID: ft260: i2c: abort in-flight transfers with STOP before reset Michael Zaidman
2026-08-22 22:12   ` sashiko-bot
2026-08-25  8:21 ` [PATCH 00/13] HID: ft260: add UART and GPIO support, plus I2C fixes Linus Walleij
2026-08-27 13:27   ` Lee Jones
2026-08-27 18:53     ` Michael Zaidman
2026-08-27 20:51       ` Lee Jones
2026-08-27 22:25         ` Michael Zaidman

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=20260822215134.D51EB1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=linux-input@vger.kernel.org \
    --cc=michael.zaidman@gmail.com \
    --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