diff options
author | Johan Hovold <johan@kernel.org> | 2014-08-27 05:55:18 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-08-27 16:23:52 -0400 |
commit | d979e9f9ecab04c1ecca741370e30a8a498893f5 (patch) | |
tree | 742a14ecb484009b22b6dee42db417fa2cd7ec02 | |
parent | 039368901ad0a6476c7ecf0cfe4f84d735e30135 (diff) |
USB: serial: fix potential stack buffer overflow
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.
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 02de3110fe94..eb0e8c6a8682 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -764,29 +764,39 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
764 | if (usb_endpoint_is_bulk_in(endpoint)) { | 764 | if (usb_endpoint_is_bulk_in(endpoint)) { |
765 | /* we found a bulk in endpoint */ | 765 | /* we found a bulk in endpoint */ |
766 | dev_dbg(ddev, "found bulk in on endpoint %d\n", i); | 766 | dev_dbg(ddev, "found bulk in on endpoint %d\n", i); |
767 | bulk_in_endpoint[num_bulk_in] = endpoint; | 767 | if (num_bulk_in < MAX_NUM_PORTS) { |
768 | ++num_bulk_in; | 768 | bulk_in_endpoint[num_bulk_in] = endpoint; |
769 | ++num_bulk_in; | ||
770 | } | ||
769 | } | 771 | } |
770 | 772 | ||
771 | if (usb_endpoint_is_bulk_out(endpoint)) { | 773 | if (usb_endpoint_is_bulk_out(endpoint)) { |
772 | /* we found a bulk out endpoint */ | 774 | /* we found a bulk out endpoint */ |
773 | dev_dbg(ddev, "found bulk out on endpoint %d\n", i); | 775 | dev_dbg(ddev, "found bulk out on endpoint %d\n", i); |
774 | bulk_out_endpoint[num_bulk_out] = endpoint; | 776 | if (num_bulk_out < MAX_NUM_PORTS) { |
775 | ++num_bulk_out; | 777 | bulk_out_endpoint[num_bulk_out] = endpoint; |
778 | ++num_bulk_out; | ||
779 | } | ||
776 | } | 780 | } |
777 | 781 | ||
778 | if (usb_endpoint_is_int_in(endpoint)) { | 782 | if (usb_endpoint_is_int_in(endpoint)) { |
779 | /* we found a interrupt in endpoint */ | 783 | /* we found a interrupt in endpoint */ |
780 | dev_dbg(ddev, "found interrupt in on endpoint %d\n", i); | 784 | dev_dbg(ddev, "found interrupt in on endpoint %d\n", i); |
781 | interrupt_in_endpoint[num_interrupt_in] = endpoint; | 785 | if (num_interrupt_in < MAX_NUM_PORTS) { |
782 | ++num_interrupt_in; | 786 | interrupt_in_endpoint[num_interrupt_in] = |
787 | endpoint; | ||
788 | ++num_interrupt_in; | ||
789 | } | ||
783 | } | 790 | } |
784 | 791 | ||
785 | if (usb_endpoint_is_int_out(endpoint)) { | 792 | if (usb_endpoint_is_int_out(endpoint)) { |
786 | /* we found an interrupt out endpoint */ | 793 | /* we found an interrupt out endpoint */ |
787 | dev_dbg(ddev, "found interrupt out on endpoint %d\n", i); | 794 | dev_dbg(ddev, "found interrupt out on endpoint %d\n", i); |
788 | interrupt_out_endpoint[num_interrupt_out] = endpoint; | 795 | if (num_interrupt_out < MAX_NUM_PORTS) { |
789 | ++num_interrupt_out; | 796 | interrupt_out_endpoint[num_interrupt_out] = |
797 | endpoint; | ||
798 | ++num_interrupt_out; | ||
799 | } | ||
790 | } | 800 | } |
791 | } | 801 | } |
792 | 802 | ||
@@ -809,8 +819,10 @@ static int usb_serial_probe(struct usb_interface *interface, | |||
809 | if (usb_endpoint_is_int_in(endpoint)) { | 819 | if (usb_endpoint_is_int_in(endpoint)) { |
810 | /* we found a interrupt in endpoint */ | 820 | /* we found a interrupt in endpoint */ |
811 | dev_dbg(ddev, "found interrupt in for Prolific device on separate interface\n"); | 821 | dev_dbg(ddev, "found interrupt in for Prolific device on separate interface\n"); |
812 | interrupt_in_endpoint[num_interrupt_in] = endpoint; | 822 | if (num_interrupt_in < MAX_NUM_PORTS) { |
813 | ++num_interrupt_in; | 823 | interrupt_in_endpoint[num_interrupt_in] = endpoint; |
824 | ++num_interrupt_in; | ||
825 | } | ||
814 | } | 826 | } |
815 | } | 827 | } |
816 | } | 828 | } |