Commit d979e9f9ecab04c1ecca741370e30a8a498893f5

Authored by Johan Hovold
Committed by Greg Kroah-Hartman
1 parent 039368901a

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>

Showing 1 changed file with 22 additions and 10 deletions Side-by-side Diff

drivers/usb/serial/usb-serial.c
... ... @@ -764,29 +764,39 @@
764 764 if (usb_endpoint_is_bulk_in(endpoint)) {
765 765 /* we found a bulk in endpoint */
766 766 dev_dbg(ddev, "found bulk in on endpoint %d\n", i);
767   - bulk_in_endpoint[num_bulk_in] = endpoint;
768   - ++num_bulk_in;
  767 + if (num_bulk_in < MAX_NUM_PORTS) {
  768 + bulk_in_endpoint[num_bulk_in] = endpoint;
  769 + ++num_bulk_in;
  770 + }
769 771 }
770 772  
771 773 if (usb_endpoint_is_bulk_out(endpoint)) {
772 774 /* we found a bulk out endpoint */
773 775 dev_dbg(ddev, "found bulk out on endpoint %d\n", i);
774   - bulk_out_endpoint[num_bulk_out] = endpoint;
775   - ++num_bulk_out;
  776 + if (num_bulk_out < MAX_NUM_PORTS) {
  777 + bulk_out_endpoint[num_bulk_out] = endpoint;
  778 + ++num_bulk_out;
  779 + }
776 780 }
777 781  
778 782 if (usb_endpoint_is_int_in(endpoint)) {
779 783 /* we found a interrupt in endpoint */
780 784 dev_dbg(ddev, "found interrupt in on endpoint %d\n", i);
781   - interrupt_in_endpoint[num_interrupt_in] = endpoint;
782   - ++num_interrupt_in;
  785 + if (num_interrupt_in < MAX_NUM_PORTS) {
  786 + interrupt_in_endpoint[num_interrupt_in] =
  787 + endpoint;
  788 + ++num_interrupt_in;
  789 + }
783 790 }
784 791  
785 792 if (usb_endpoint_is_int_out(endpoint)) {
786 793 /* we found an interrupt out endpoint */
787 794 dev_dbg(ddev, "found interrupt out on endpoint %d\n", i);
788   - interrupt_out_endpoint[num_interrupt_out] = endpoint;
789   - ++num_interrupt_out;
  795 + if (num_interrupt_out < MAX_NUM_PORTS) {
  796 + interrupt_out_endpoint[num_interrupt_out] =
  797 + endpoint;
  798 + ++num_interrupt_out;
  799 + }
790 800 }
791 801 }
792 802  
... ... @@ -809,8 +819,10 @@
809 819 if (usb_endpoint_is_int_in(endpoint)) {
810 820 /* we found a interrupt in endpoint */
811 821 dev_dbg(ddev, "found interrupt in for Prolific device on separate interface\n");
812   - interrupt_in_endpoint[num_interrupt_in] = endpoint;
813   - ++num_interrupt_in;
  822 + if (num_interrupt_in < MAX_NUM_PORTS) {
  823 + interrupt_in_endpoint[num_interrupt_in] = endpoint;
  824 + ++num_interrupt_in;
  825 + }
814 826 }
815 827 }
816 828 }