[PATCH v2 05/12] USB: serial: io_edgeport: fix potential fifo corruption

From: Johan Hovold

Date: Fri Oct 23 2026 - 08:23:30 EST


The device buffer size is determined during open() and the driver
allocates a TX FIFO of corresponding size.

Add the missing sanity check to prevent memory corruption in case a
malicious device sends a second open response with a different buffer
size.

This issue was flagged by Sashiko when reviewing a related fix.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@xxxxxxxxxxxxxxx
Link: https://sashiko.dev/#/patchset/20260714101316.823942-1-shpark061104%40gmail.com?part=1
Signed-off-by: Johan Hovold <johan@xxxxxxxxxx>
---
drivers/usb/serial/io_edgeport.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index cdcff02c435b..b8fbcc8908d1 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -877,13 +877,17 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
}

/* initialize our port settings */
+ spin_lock_irq(&edge_port->ep_lock);
edge_port->txCredits = 0; /* Can't send any data yet */
+ edge_port->maxTxCredits = 0;
+ edge_port->openPending = true;
+ spin_unlock_irq(&edge_port->ep_lock);
+
/* Must always set this bit to enable ints! */
edge_port->shadowMCR = MCR_MASTER_IE;
edge_port->chaseResponsePending = false;

/* send a open port command */
- edge_port->openPending = true;
response = send_iosp_ext_cmd(edge_port, IOSP_CMD_OPEN_PORT, 0);
if (response < 0) {
dev_err(dev, "%s - error sending open port command\n", __func__);
@@ -1736,6 +1740,7 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial,
struct edgeport_port *edge_port;
struct device *dev;
__u8 code = edge_serial->rxStatusCode;
+ unsigned long flags;

/* switch the port pointer to the one being currently talked about */
if (edge_serial->rxPort >= edge_serial->serial->num_ports)
@@ -1779,6 +1784,12 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial,
}

if (code == IOSP_STATUS_OPEN_RSP) {
+ spin_lock_irqsave(&edge_port->ep_lock, flags);
+ /* reject stray open responses to avoid FIFO corruption */
+ if (!edge_port->openPending) {
+ spin_unlock_irqrestore(&edge_port->ep_lock, flags);
+ return;
+ }
edge_port->txCredits = GET_TX_BUFFER_SIZE(byte3);
edge_port->maxTxCredits = edge_port->txCredits;
dev_dbg(dev, "%s - Port %u Open Response Initial MSR = %02x TxBufferSize = %d\n",
@@ -1787,6 +1798,8 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial,

/* we have completed the open */
edge_port->openPending = false;
+ spin_unlock_irqrestore(&edge_port->ep_lock, flags);
+
wake_up(&edge_port->wait_open);
return;
}
--
2.55.0