From: sashiko-bot@kernel.org
To: "Michael Zaidman" <michael.zaidman@gmail.com>
Cc: dmitry.torokhov@gmail.com, linux-input@vger.kernel.org
Subject: Re: [PATCH 08/13] HID: ft260: uart: add modem pins control via ioctl
Date: Sat, 22 Aug 2026 21:54:58 +0000 [thread overview]
Message-ID: <20260822215458.B2AC71F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260822213941.98882-9-michael.zaidman@gmail.com>
Thank you for your contribution! Sashiko AI review found 7 potential issue(s) to consider:
New issues:
- [Critical] tiocmget and tiocmset operations trigger a Use-After-Free if called after the USB device is unbound due to delayed TTY hangup.
- [High] In ft260_probe(), if ft260_get_interface_type() fails, the negative error code is discarded, causing probe to return success.
- [Medium] ft260_uart_tiocmget() fails to check the return value of ft260_gpio_get_all(), leading to corrupted TIOCM state on error.
- [Medium] ft260_uart_tiocmset() copies port->gpio outside of port->lock, creating a race condition that leads to lost GPIO updates.
- [Medium] ft260_uart_tiocmset() and ft260_uart_tiocmget() silently ignore partial modem GPIO configurations and falsely return success.
Pre-existing issues:
- [Critical] Pre-existing memory safety bugs related to tty_port refcounting cause a double-free on probe failure and a use-after-free on device removal.
- [High] Pre-existing double byteswap of baudrate corrupts UART configuration on big-endian hosts.
--
--- Patch [8]: [PATCH 08/13] HID: ft260: uart: add modem pins control via ioctl ---
commit 847b0f46ee2404b8e4d020149c5d880eb06ffe61
Author: Michael Zaidman <michael.zaidman@gmail.com>
HID: ft260: uart: add modem pins control via ioctl
This commit adds TIOCMGET/TIOCMSET support so userspace can drive DTR/RTS
when the modem pins are in GPIO mode. It also modifies the GPIO sysfs
registration to rely on chip_mode instead of USB interface number.
> diff --git a/drivers/hid/hid-ft260.c b/drivers/hid/hid-ft260.c
> index 1da42b8756d8c..554d8e3ddb6db 100644
> --- a/drivers/hid/hid-ft260.c
> +++ b/drivers/hid/hid-ft260.c
[ ... ]
> @@ -1912,6 +1942,78 @@ static void ft260_uart_set_termios(struct tty_struct *tty,
> ft260_uart_change_speed(port, &tty->termios, NULL);
> }
>
> +static int ft260_uart_tiocmget(struct tty_struct *tty)
> +{
> + struct ft260_device *port = tty->driver_data;
> + int gpios;
> +
> + /*
> + * The modem lines control via ioctl is allowed only
> + * when the related pins are in the gpio mode.
> + */
> + int mask = FT260_GPIO_UART_MODE_4_SET;
> +
> + if ((port->gpio_en & mask) != mask) {
> + ft260_dbg("Illegal gpio config %#02x != mask %#04x\n",
> + port->gpio_en, mask);
> + return 0;
> + }
[Severity: Medium]
Does this silently ignore the partial configuration by returning 0
(success) instead of an error code like -EINVAL? If userspace enables
hardware flow control, it might try to toggle DTR/DSR manually, and
it looks like this will silently return success without taking action.
> +
> + gpios = ft260_gpio_get_all(port->gc, FT260_GPIO_VALUE);
[Severity: Critical]
Is there a use-after-free risk here if the USB device is unbound
but the TTY file descriptor is still open? It appears port->gc could be
freed by devres during removal, while the asynchronous TTY hangup might
not have completed yet.
> +
> + return (((gpios & FT260_GPIO_B) ? TIOCM_RTS : 0) |
[Severity: Medium]
If ft260_gpio_get_all() returns a negative error code (e.g., due to a
USB transfer error), will the error value be directly evaluated by the
bitwise operators here instead of being propagated back to userspace?
> + ((gpios & FT260_GPIO_E) ? TIOCM_CTS : 0) |
> + ((gpios & FT260_GPIO_F) ? TIOCM_DTR : 0) |
> + ((gpios & FT260_GPIO_H) ? TIOCM_DSR : 0) |
> + ((gpios & FT260_GPIO_4) ? TIOCM_CAR : 0) |
> + ((gpios & FT260_GPIO_5) ? TIOCM_RNG : 0));
> +}
> +
> +static int ft260_uart_tiocmset(struct tty_struct *tty,
> + unsigned int set, unsigned int clear)
> +{
> + int ret;
> + struct ft260_device *port = tty->driver_data;
> + struct ft260_gpio_write_request_report rep;
> + struct hid_device *hdev = port->hdev;
> + int mask = FT260_GPIO_UART_MODE_4_SET;
> +
> + if ((port->gpio_en & mask) != mask) {
> + ft260_dbg("Illegal gpio config %#02x != mask %#04x\n",
> + port->gpio_en, mask);
> + return 0;
> + }
> + rep.report = FT260_GPIO;
> + rep.gpio = port->gpio;
> +
> + mutex_lock(&port->lock);
[Severity: Medium]
Is there a race condition with concurrent GPIO updates here? Since
port->gpio is copied into rep.gpio before acquiring port->lock, could
concurrent updates to the GPIO lines via sysfs or other ioctls be silently
overwritten when this stale copy is written back at the end of the function?
> +
> + if (set & TIOCM_RTS)
> + ft260_gpio_output_cfg(&rep.gpio, FT260_GPIO_UART_RTS, 1);
> + if (set & TIOCM_DTR)
> + ft260_gpio_output_cfg(&rep.gpio, FT260_GPIO_UART_DTR, 1);
> + if (clear & TIOCM_RTS)
> + ft260_gpio_output_cfg(&rep.gpio, FT260_GPIO_UART_RTS, 0);
> + if (clear & TIOCM_DTR)
> + ft260_gpio_output_cfg(&rep.gpio, FT260_GPIO_UART_DTR, 0);
> +
> + ft260_dbg("dirs %#02x vals %#02x ex_dirs %#02x ex_vals %#02x\n",
> + rep.gpio.dirs, rep.gpio.vals,
> + rep.gpio.ex_dirs, rep.gpio.ex_vals);
> +
> + ret = ft260_hid_feature_report_set(hdev, (u8 *)&rep, sizeof(rep));
[Severity: Critical]
Can this access a freed hdev if the USB device has been unplugged?
If the asynchronous TTY hangup work hasn't completed, a delayed
ioctl could potentially pass a destroyed hid_device pointer to
ft260_hid_feature_report_set().
> + if (unlikely(ret < 0)) {
> + hid_err(hdev, "%s: cannot set GPIO: %d\n", __func__, ret);
> + mutex_unlock(&port->lock);
> + return -EIO;
> + }
> +
> + port->gpio = rep.gpio;
> + mutex_unlock(&port->lock);
> +
> + return 0;
> +}
[ ... ]
> @@ -2199,7 +2305,8 @@ static int ft260_uart_probe(struct ft260_device *dev,
>
> cfg->uart_mode = FT260_UART_CFG_FLOW_CTRL_NONE;
>
> - if (dev->iface_id == 0) {
> + if (dev->chip_mode & FT260_MODE_UART ||
> + dev->chip_mode == FT260_MODE_ALL) {
> ret = ft260_gpio_init(dev, cfg);
[Severity: High]
This is a pre-existing issue, but in ft260_uart_change_speed() and earlier
in ft260_uart_probe(), put_unaligned_le32(cpu_to_le32(baud), ...) is used.
Since put_unaligned_le32() already performs a byte swap to little-endian,
does passing cpu_to_le32() result in a double byteswap that breaks UART
communications on big-endian hosts?
[ ... ]
> @@ -2274,11 +2381,11 @@ static int ft260_probe(struct hid_device *hdev, const struct hid_device_id *id)
> spin_lock_init(&dev->read_lock);
> init_completion(&dev->wait);
>
> - ret = ft260_get_interface_type(dev, &cfg);
> - if (ret <= FT260_IFACE_NONE)
> + dev->iface_type = ft260_get_interface_type(dev, &cfg);
> + if (dev->iface_type <= FT260_IFACE_NONE)
> goto err_hid_close;
[Severity: High]
Does this discard the negative error code by failing to update ret?
If ft260_get_interface_type() fails (for instance, during a USB control
transfer error), jumping to err_hid_close will cause the probe function
to return the previous positive value of ret, incorrectly signaling success
to the driver core.
[ ... ]
> @@ -2310,11 +2417,13 @@ static void ft260_remove(struct hid_device *hdev)
> dev->index);
> ft260_uart_port_remove(dev);
> /* dev is still needed, so we will free it in _destroy func */
> - if (dev->iface_id == 0)
> + if (dev->chip_mode & FT260_MODE_UART ||
> + dev->chip_mode == FT260_MODE_ALL)
[Severity: Critical]
This is a pre-existing issue, but does ft260_uart_port_remove() drop
the final tty kref and free dev? If so, accessing dev->chip_mode right
afterward would be a use-after-free during normal unplug. Furthermore,
in the ft260_probe() error path, does this same kref drop lead to a
double-free when the outer error handling calls kfree(dev)?
> sysfs_remove_group(&hdev->dev.kobj, &ft260_attr_group);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260822213941.98882-1-michael.zaidman@gmail.com?part=8
next prev parent reply other threads:[~2026-08-22 21:54 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
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 [this message]
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=20260822215458.B2AC71F000E9@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