USB: serial: mos7840: fix control-message error handling
authorJohan Hovold <johan@kernel.org>
Thu, 12 Jan 2017 13:56:18 +0000 (14:56 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 8 Oct 2017 08:26:06 +0000 (10:26 +0200)
[ Upstream commit cd8db057e93ddaacbec025b567490555d2bca280 ]

Make sure to detect short transfers when reading a device register.

The modem-status handling had sufficient error checks in place, but move
handling of short transfers into the register accessor function itself
for consistency.

Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/serial/mos7840.c

index 5c4fc3a..6baacf6 100644 (file)
@@ -285,9 +285,15 @@ static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg,
        ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
                              MCS_RD_RTYPE, 0, reg, buf, VENDOR_READ_LENGTH,
                              MOS_WDR_TIMEOUT);
+       if (ret < VENDOR_READ_LENGTH) {
+               if (ret >= 0)
+                       ret = -EIO;
+               goto out;
+       }
+
        *val = buf[0];
        dev_dbg(&port->dev, "%s offset is %x, return val %x\n", __func__, reg, *val);
-
+out:
        kfree(buf);
        return ret;
 }
@@ -353,8 +359,13 @@ static int mos7840_get_uart_reg(struct usb_serial_port *port, __u16 reg,
        ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
                              MCS_RD_RTYPE, Wval, reg, buf, VENDOR_READ_LENGTH,
                              MOS_WDR_TIMEOUT);
+       if (ret < VENDOR_READ_LENGTH) {
+               if (ret >= 0)
+                       ret = -EIO;
+               goto out;
+       }
        *val = buf[0];
-
+out:
        kfree(buf);
        return ret;
 }
@@ -1490,10 +1501,10 @@ static int mos7840_tiocmget(struct tty_struct *tty)
                return -ENODEV;
 
        status = mos7840_get_uart_reg(port, MODEM_STATUS_REGISTER, &msr);
-       if (status != 1)
+       if (status < 0)
                return -EIO;
        status = mos7840_get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr);
-       if (status != 1)
+       if (status < 0)
                return -EIO;
        result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
            | ((mcr & MCR_RTS) ? TIOCM_RTS : 0)