USB: serial: iuu_phoenix: fix DMA from stack
authorJohan Hovold <johan@kernel.org>
Mon, 4 Jan 2021 14:50:07 +0000 (15:50 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 12 Jan 2021 19:18:20 +0000 (20:18 +0100)
commit 54d0a3ab80f49f19ee916def62fe067596833403 upstream.

Stack-allocated buffers cannot be used for DMA (on all architectures) so
allocate the flush command buffer using kmalloc().

Fixes: 60a8fc017103 ("USB: add iuu_phoenix driver")
Cc: stable <stable@vger.kernel.org> # 2.6.25
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/serial/iuu_phoenix.c

index b4ba791..c142051 100644 (file)
@@ -532,23 +532,29 @@ static int iuu_uart_flush(struct usb_serial_port *port)
        struct device *dev = &port->dev;
        int i;
        int status;
-       u8 rxcmd = IUU_UART_RX;
+       u8 *rxcmd;
        struct iuu_private *priv = usb_get_serial_port_data(port);
 
        if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0)
                return -EIO;
 
+       rxcmd = kmalloc(1, GFP_KERNEL);
+       if (!rxcmd)
+               return -ENOMEM;
+
+       rxcmd[0] = IUU_UART_RX;
+
        for (i = 0; i < 2; i++) {
-               status = bulk_immediate(port, &rxcmd, 1);
+               status = bulk_immediate(port, rxcmd, 1);
                if (status != IUU_OPERATION_OK) {
                        dev_dbg(dev, "%s - uart_flush_write error\n", __func__);
-                       return status;
+                       goto out_free;
                }
 
                status = read_immediate(port, &priv->len, 1);
                if (status != IUU_OPERATION_OK) {
                        dev_dbg(dev, "%s - uart_flush_read error\n", __func__);
-                       return status;
+                       goto out_free;
                }
 
                if (priv->len > 0) {
@@ -556,12 +562,16 @@ static int iuu_uart_flush(struct usb_serial_port *port)
                        status = read_immediate(port, priv->buf, priv->len);
                        if (status != IUU_OPERATION_OK) {
                                dev_dbg(dev, "%s - uart_flush_read error\n", __func__);
-                               return status;
+                               goto out_free;
                        }
                }
        }
        dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__);
        iuu_led(port, 0, 0xF000, 0, 0xFF);
+
+out_free:
+       kfree(rxcmd);
+
        return status;
 }