diff options
author | Johan Hovold <johan@kernel.org> | 2014-08-27 11:55:18 +0200 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2014-09-13 23:41:47 +0100 |
commit | 51140f5ce2b7e47934b277a3195cb2f1b78912fc (patch) | |
tree | 4f88346f6a5dcded35eb3f4cd9436a501945b512 /drivers/usb/serial | |
parent | bbd4080b5f3f81d5fcedac188cf90f34b7754ebe (diff) | |
download | kernel_samsung_smdk4412-51140f5ce2b7e47934b277a3195cb2f1b78912fc.zip kernel_samsung_smdk4412-51140f5ce2b7e47934b277a3195cb2f1b78912fc.tar.gz kernel_samsung_smdk4412-51140f5ce2b7e47934b277a3195cb2f1b78912fc.tar.bz2 |
USB: serial: fix potential stack buffer overflow
commit d979e9f9ecab04c1ecca741370e30a8a498893f5 upstream.
Make sure to verify the maximum number of endpoints per type to avoid
writing beyond the end of a stack-allocated array.
The current usb-serial implementation is limited to eight ports per
interface but failed to verify that the number of endpoints of a certain
type reported by a device did not exceed this limit.
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'drivers/usb/serial')
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 8f76a2b..8a47ffd 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -791,29 +791,39 @@ int usb_serial_probe(struct usb_interface *interface, if (usb_endpoint_is_bulk_in(endpoint)) { /* we found a bulk in endpoint */ dbg("found bulk in on endpoint %d", i); - bulk_in_endpoint[num_bulk_in] = endpoint; - ++num_bulk_in; + if (num_bulk_in < MAX_NUM_PORTS) { + bulk_in_endpoint[num_bulk_in] = endpoint; + ++num_bulk_in; + } } if (usb_endpoint_is_bulk_out(endpoint)) { /* we found a bulk out endpoint */ dbg("found bulk out on endpoint %d", i); - bulk_out_endpoint[num_bulk_out] = endpoint; - ++num_bulk_out; + if (num_bulk_out < MAX_NUM_PORTS) { + bulk_out_endpoint[num_bulk_out] = endpoint; + ++num_bulk_out; + } } if (usb_endpoint_is_int_in(endpoint)) { /* we found a interrupt in endpoint */ dbg("found interrupt in on endpoint %d", i); - interrupt_in_endpoint[num_interrupt_in] = endpoint; - ++num_interrupt_in; + if (num_interrupt_in < MAX_NUM_PORTS) { + interrupt_in_endpoint[num_interrupt_in] = + endpoint; + ++num_interrupt_in; + } } if (usb_endpoint_is_int_out(endpoint)) { /* we found an interrupt out endpoint */ dbg("found interrupt out on endpoint %d", i); - interrupt_out_endpoint[num_interrupt_out] = endpoint; - ++num_interrupt_out; + if (num_interrupt_out < MAX_NUM_PORTS) { + interrupt_out_endpoint[num_interrupt_out] = + endpoint; + ++num_interrupt_out; + } } } @@ -836,8 +846,10 @@ int usb_serial_probe(struct usb_interface *interface, if (usb_endpoint_is_int_in(endpoint)) { /* we found a interrupt in endpoint */ dbg("found interrupt in for Prolific device on separate interface"); - interrupt_in_endpoint[num_interrupt_in] = endpoint; - ++num_interrupt_in; + if (num_interrupt_in < MAX_NUM_PORTS) { + interrupt_in_endpoint[num_interrupt_in] = endpoint; + ++num_interrupt_in; + } } } } |