aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2014-08-27 11:55:18 +0200
committerBen Hutchings <ben@decadent.org.uk>2014-09-13 23:41:47 +0100
commit51140f5ce2b7e47934b277a3195cb2f1b78912fc (patch)
tree4f88346f6a5dcded35eb3f4cd9436a501945b512 /drivers/usb/serial
parentbbd4080b5f3f81d5fcedac188cf90f34b7754ebe (diff)
downloadkernel_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.c32
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;
+ }
}
}
}