If the chip reports a TX FIFO space, bigger than the driver's buffer, it runs over and destroys the struct sc16is7xx_port, its struct kworker, and very likely a lot more. For us, this lead to the immediate crash of the driver's kworker thread. Prevent a buffer overrun by adding a length check. However, the reason why the driver reads a wrong TX FIFO space is not clear. In our setup it reports 255, while the chip should have only 64 bytes. Signed-off-by: Florian Achleitner <achleitner.florian@xxxxxxxxxxx> --- Hi, we found this because whenever we wrote a bigger block on the tty, the kworker crashed. We use the chip on an imx28 system via spi (mxs-spi driver). I currently have no clue, why the TXLVL read-out yields 255, while the tx fifo should only be 64 at max. Regards , Florian drivers/tty/serial/sc16is7xx.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c index 02f37dc..97ca669 100644 --- a/drivers/tty/serial/sc16is7xx.c +++ b/drivers/tty/serial/sc16is7xx.c @@ -630,7 +630,15 @@ static void sc16is7xx_handle_tx(struct uart_port *port) if (likely(to_send)) { /* Limit to size of TX FIFO */ txlen = sc16is7xx_port_read(port, SC16IS7XX_TXLVL_REG); + /* ignore bit 7, according to datasheet */ + txlen &= 0x7f; + if (txlen > SC16IS7XX_FIFO_SIZE) + dev_err_ratelimited(port->dev, "chip reports %d free bytes in TX " + "fifo, but it only has %d, sizeof(buf) is %d", + txlen, SC16IS7XX_FIFO_SIZE, sizeof(s->buf)); to_send = (to_send > txlen) ? txlen : to_send; + /* prevent buffer overrun if reported txlen is flawed */ + to_send = (to_send > sizeof(s->buf)) ? sizeof(s->buf) : to_send; /* Add data to send */ port->icount.tx += to_send; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html