From: sashiko-bot@kernel.org
To: "Johan Hovold" <johan@kernel.org>
Cc: linux-usb@vger.kernel.org
Subject: Re: [PATCH 03/11] USB: serial: io_edgeport: fix potential close() use-after-free
Date: Wed, 21 Oct 2026 14:37:49 +0000 [thread overview]
Message-ID: <sashiko-outbox-180389@kernel.org> (raw)
In-Reply-To: <20261021141154.2324793-4-johan@kernel.org>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] usb: serial: io_edgeport: race between edge_close() and edge_write()
--
commit 611925474c1210ae646660fb9dfc233968cca260
Author: Johan Hovold <johan@kernel.org>
USB: serial: io_edgeport: fix potential close() use-after-free
This commit adds spinlock protection around clearing edge_port->open in
edge_close() so that a racing interrupt completion handler does not submit
more data while the port's write_urb and txfifo are being freed.
Link: https://sashiko.dev/#/patchset/20260714101316.823942-1-shpark061104%40gmail.com?part=1
> diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
> index 0cc4f41299e03..a2410c063ffe8 100644
> --- a/drivers/usb/serial/io_edgeport.c
> +++ b/drivers/usb/serial/io_edgeport.c
> @@ -1089,7 +1089,9 @@ static void edge_close(struct usb_serial_port *port)
>
> /* port->close = true; */
> edge_port->closePending = false;
> + spin_lock_irq(&edge_port->ep_lock);
> edge_port->open = false;
> + spin_unlock_irq(&edge_port->ep_lock);
> edge_port->openPending = false;
>
> usb_kill_urb(edge_port->write_urb);
[Severity: High]
While holding ep_lock around setting edge_port->open = false prevents
send_more_port_data() from racing with the deallocation of write_urb and
txfifo.fifo in edge_close(), could edge_write() still race with this
cleanup and dereference edge_port->txfifo.fifo while or after it is freed?
In drivers/usb/serial/io_edgeport.c, edge_close() does not zero
edge_port->txCredits (which was replenished during
block_until_chase_response()) and frees edge_port->txfifo.fifo outside
ep_lock:
spin_lock_irq(&edge_port->ep_lock);
edge_port->open = false;
spin_unlock_irq(&edge_port->ep_lock);
edge_port->openPending = false;
usb_kill_urb(edge_port->write_urb);
...
kfree(edge_port->txfifo.fifo);
edge_port->txfifo.fifo = NULL;
Meanwhile, edge_write() acquires ep_lock without checking edge_port->open
and copies data into fifo->fifo whenever edge_port->txCredits > fifo->count:
spin_lock_irqsave(&edge_port->ep_lock, flags);
/* calculate number of bytes to put in fifo */
copySize = min_t(unsigned int, count,
(edge_port->txCredits - fifo->count));
...
if (copySize == 0) {
dev_dbg(&port->dev, "%s - copySize = Zero\n", __func__);
goto finish_write;
}
...
memcpy(&fifo->fifo[fifo->head], data, firsthalf);
During tty_port_close() -> tty_port_shutdown() -> edge_close(), before the
line discipline and flip-buffer workqueue are flushed or closed, concurrent
calls to edge_write() can still occur in two ways:
1. edge_interrupt_callback() checks edge_port->open outside ep_lock and
calls tty_port_tty_wakeup() -> tty_wakeup() -> ld->ops->write_wakeup(),
which in framing line disciplines (such as n_hdlc, ppp_async, slip,
n_gsm, or hci_ldisc) synchronously invokes tty->ops->write() ->
serial_write() -> edge_write().
2. Incoming receive data pushed via process_rcvd_data() -> edge_tty_recv() ->
tty_flip_buffer_push() before edge_port->open becomes false is processed
asynchronously by the flush_to_ldisc() workqueue during edge_close(). In
n_tty, this can call edge_write() via n_tty_check_throttle() ->
tty_throttle_safe() -> serial_throttle() -> edge_throttle() when ixoff
is enabled (especially once the follow-up commit "usb: serial:
io_edgeport: drop redundant open sanity checks" removes the unlocked
!edge_port->open check from edge_throttle() and edge_unthrottle()), or
via n_tty_receive_char_closing() -> process_echoes() -> tty_put_char()
when ixon is enabled with pending echoes.
Should edge_write() also check edge_port->open under ep_lock (or should
edge_close() zero txCredits / free txfifo.fifo under ep_lock) to avoid a
use-after-free write or null pointer dereference on fifo->fifo?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261021141154.2324793-1-johan@kernel.org?part=3
next prev parent reply other threads:[~2026-10-21 14:37 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 14:11 [PATCH 00/11] USB: serial: io_edgeport: fixes and sync commands Johan Hovold
2026-10-21 14:11 ` [PATCH 01/11] USB: serial: io_edgeport: fix NULL-deref on early status Johan Hovold
2026-10-21 14:20 ` sashiko-bot
2026-10-21 14:11 ` [PATCH 02/11] USB: serial: io_edgeport: fix potential fifo corruption Johan Hovold
2026-10-21 14:31 ` sashiko-bot
2026-10-21 14:11 ` [PATCH 03/11] USB: serial: io_edgeport: fix potential close() use-after-free Johan Hovold
2026-10-21 14:37 ` sashiko-bot [this message]
2026-10-21 14:11 ` [PATCH 04/11] USB: serial: io_edgeport: fix potential NULL-deref at open Johan Hovold
2026-10-21 14:28 ` sashiko-bot
2026-10-21 14:11 ` [PATCH 05/11] USB: serial: io_edgeport: serialise MCR accesses Johan Hovold
2026-10-21 14:26 ` sashiko-bot
2026-10-21 15:27 ` Johan Hovold
2026-10-21 14:11 ` [PATCH 06/11] USB: serial: io_edgeport: drop redundant sanity checks Johan Hovold
2026-10-21 14:24 ` sashiko-bot
2026-10-21 14:11 ` [PATCH 07/11] USB: serial: io_edgeport: drop redundant open " Johan Hovold
2026-10-21 14:42 ` sashiko-bot
2026-10-21 14:11 ` [PATCH 08/11] USB: serial: io_edgeport: move initial termios update to open() Johan Hovold
2026-10-21 14:25 ` sashiko-bot
2026-10-21 14:11 ` [PATCH 09/11] USB: serial: io_edgeport: deassert DTR/RTS on close() and B0 Johan Hovold
2026-10-21 14:22 ` sashiko-bot
2026-10-21 14:11 ` [PATCH 10/11] USB: serial: io_edgeport: replace atomic command allocations Johan Hovold
2026-10-21 14:19 ` sashiko-bot
2026-10-21 14:11 ` [PATCH 11/11] USB: serial: io_edgeport: switch to synchronous commands Johan Hovold
2026-10-21 14:23 ` sashiko-bot
2026-10-21 15:43 ` Johan Hovold
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-180389@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=johan@kernel.org \
--cc=linux-usb@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.