Linux Serial subsystem development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Markus Probst" <markus.probst@posteo.de>
Cc: linux-serial@vger.kernel.org, ojeda@kernel.org, gary@garyguo.net
Subject: Re: [PATCH v6 1/4] tty: serdev: Add mutex lock
Date: Thu, 12 Nov 2026 17:58:20 +0000	[thread overview]
Message-ID: <sashiko-outbox-211656@kernel.org> (raw)
In-Reply-To: <20261112-rust_serdev_probe_refactor-v6-1-3568ed56264c@posteo.de>

Thank you for your contribution! Sashiko AI review found 3 potential
issues to consider:
- [High] tty: serdev: late close in serdev_device_remove() and missed
  driver unbind
- [High] tty: serdev: returning -EALREADY in ttyport_open() breaks
  hci_mrvl probe
- [Low] tty: serdev: dev_WARN() used instead of dev_warn() in
  serdev_device_remove()
--

commit 5353012a0aab4d9161723d4449dfeeb88d3f481c
Author: Markus Probst <markus.probst@posteo.de>

tty: serdev: Add mutex lock

This commit adds mutex locking to serdev-ttyport to serialize open, close,
and receive operations, returns -EALREADY on duplicate opens, makes closing
an already-closed device a no-op, and closes the device with a warning in
serdev_device_remove() if left open.

> diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
> index 7500efcdfc218..86d9cf8215edc 100644
> --- a/drivers/tty/serdev/core.c
> +++ b/drivers/tty/serdev/core.c
> @@ -142,6 +142,13 @@ void serdev_device_remove(struct serdev_device *serdev)
>  	struct serdev_controller *ctrl = serdev->ctrl;
>  
>  	device_unregister(&serdev->dev);
> +
> +	/* Warn if driver did not close the serial device. */
> +	if (ctrl->ops->close && ctrl->ops->close(ctrl)) {

[Severity: High]
Does closing the controller after device_unregister(&serdev->dev) leave a
use-after-free window on serdev and its devres data?

When a child driver leaves the device open, SERPORT_ACTIVE remains set
while device_unregister() runs device_unbind_cleanup() (freeing devm
resources and clearing drvdata) and put_device() -> serdev_device_release()
-> kfree(serdev), before ctrl->ops->close(ctrl) clears SERPORT_ACTIVE and
ctrl->serdev is set to NULL:

CPU0                                  CPU1
serdev_device_remove()
  device_unregister(&serdev->dev)
    ...
    device_unbind_cleanup()
    kfree(serdev)
                                      ttyport_receive_buf()
                                        serdev_controller_receive_buf()
                                          serdev = ctrl->serdev;
                                          serdev->ops->receive_buf(serdev, ...)
                                            <-- use-after-free
  ctrl->ops->close(ctrl)
  ctrl->serdev = NULL

In addition, serdev_device_remove() only runs when the struct serdev_device
itself is unregistered, not when a client driver is unbound via
serdev_drv_remove() (e.g. module unload or sysfs unbind).  If a driver
leaves the port open across unbind, this fallback close never runs,
leaving SERPORT_ACTIVE set with NULL drvdata and causing any later re-probe
to fail in serdev_device_open() with -EALREADY.

> +		dev_WARN(&ctrl->dev, "Child driver did not close the serial device");
> +		pm_runtime_put(&ctrl->dev);
> +	}

[Severity: Low]
As reported by Greg Kroah-Hartman on v4 [1], this should log a normal
kernel warning rather than a WARN_ON() splat.  dev_WARN() expands to
WARN(1, ...), which still triggers a backtrace and crashes systems with
panic_on_warn; dev_warn() (with a trailing newline) logs at KERN_WARNING
without a WARN trap.

[ ... ]

> diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
> index b6638f9f40d2d..17c18d4b0cb8f 100644
> --- a/drivers/tty/serdev/serdev-ttyport.c
> +++ b/drivers/tty/serdev/serdev-ttyport.c
[ ... ]
> @@ -99,14 +103,23 @@ static int ttyport_open(struct serdev_controller *ctrl)
>  	struct ktermios ktermios;
>  	int ret;
>  
> +	mutex_lock(&serport->lock);
> +
> +	if (test_bit(SERPORT_ACTIVE, &serport->flags)) {
> +		ret = -EALREADY;
> +		goto err_flags_unlock;
> +	}

[Severity: High]
Does returning -EALREADY here break probing of Marvell serdev Bluetooth
devices in drivers/bluetooth/hci_mrvl.c?

During probe, mrvl_serdev_probe() calls hci_uart_register_device() ->
hci_uart_register_device_priv(), which opens hu->serdev and then calls
p->open(hu):

drivers/bluetooth/hci_serdev.c:hci_uart_register_device_priv() {
	...
	err = serdev_device_open(hu->serdev);
	if (err)
		goto err_rwsem;

	err = p->open(hu);
	if (err)
		goto err_open;
	...
}

mrvl_open() then calls serdev_device_open(hu->serdev) a second time:

drivers/bluetooth/hci_mrvl.c:mrvl_open() {
	...
	if (hu->serdev) {
		ret = serdev_device_open(hu->serdev);
		if (ret)
			goto err;
	}
	...
}

With ttyport_open() returning -EALREADY when SERPORT_ACTIVE is already set,
mrvl_open() and mrvl_serdev_probe() will unconditionally fail.

[1] https://lore.kernel.org/r/2026101758-confidant-comprised-e1c0@gregkh

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261112-rust_serdev_probe_refactor-v6-0-3568ed56264c@posteo.de?part=1

  reply	other threads:[~2026-11-12 17:58 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-12 17:30 [PATCH v6 0/4] rust: serdev: Refactor Markus Probst
2026-11-12 17:30 ` [PATCH v6 1/4] tty: serdev: Add mutex lock Markus Probst
2026-11-12 17:58   ` sashiko-bot [this message]
2026-11-12 17:30 ` [PATCH v6 2/4] tty: serdev: Export functions to pause receive_buf callback calls Markus Probst
2026-11-12 17:45   ` sashiko-bot
2026-11-12 17:30 ` [PATCH v6 3/4] rust: serdev: Replace `active` mutex with receive pause Markus Probst
2026-11-12 17:42   ` sashiko-bot
2026-11-12 17:30 ` [PATCH v6 4/4] rust: serdev: Simplify callbacks Markus Probst
2026-11-12 17:38   ` 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=sashiko-outbox-211656@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=gary@garyguo.net \
    --cc=linux-serial@vger.kernel.org \
    --cc=markus.probst@posteo.de \
    --cc=ojeda@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