| From f4ef71028b5707e8d7acca89aaa4bf7a85b685c0 Mon Sep 17 00:00:00 2001 |
| From: Johan Hovold <johan@kernel.org> |
| Date: Tue, 31 Jan 2017 17:17:27 +0100 |
| Subject: [PATCH] USB: serial: digi_acceleport: fix OOB data sanity check |
| |
| commit 2d380889215fe20b8523345649dee0579821800c upstream. |
| |
| Make sure to check for short transfers to avoid underflow in a loop |
| condition when parsing the receive buffer. |
| |
| Also fix an off-by-one error in the incomplete sanity check which could |
| lead to invalid data being parsed. |
| |
| Fixes: 8c209e6782ca ("USB: make actual_length in struct urb field u32") |
| Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") |
| Cc: stable <stable@vger.kernel.org> # v2.6.30 |
| Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Johan Hovold <johan@kernel.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c |
| index 6a1df9e824ca..3b610f1e3f7c 100644 |
| --- a/drivers/usb/serial/digi_acceleport.c |
| +++ b/drivers/usb/serial/digi_acceleport.c |
| @@ -1482,16 +1482,20 @@ static int digi_read_oob_callback(struct urb *urb) |
| struct usb_serial *serial = port->serial; |
| struct tty_struct *tty; |
| struct digi_port *priv = usb_get_serial_port_data(port); |
| + unsigned char *buf = urb->transfer_buffer; |
| int opcode, line, status, val; |
| int i; |
| unsigned int rts; |
| |
| + if (urb->actual_length < 4) |
| + return -1; |
| + |
| /* handle each oob command */ |
| - for (i = 0; i < urb->actual_length - 3;) { |
| - opcode = ((unsigned char *)urb->transfer_buffer)[i++]; |
| - line = ((unsigned char *)urb->transfer_buffer)[i++]; |
| - status = ((unsigned char *)urb->transfer_buffer)[i++]; |
| - val = ((unsigned char *)urb->transfer_buffer)[i++]; |
| + for (i = 0; i < urb->actual_length - 4; i += 4) { |
| + opcode = buf[i]; |
| + line = buf[i + 1]; |
| + status = buf[i + 2]; |
| + val = buf[i + 3]; |
| |
| dev_dbg(&port->dev, "digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d\n", |
| opcode, line, status, val); |
| -- |
| 2.12.0 |
| |