lkml.org 
[lkml]   [2021]   [Jan]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.10 099/145] USB: Gadget: dummy-hcd: Fix shift-out-of-bounds bug
    Date
    From: Alan Stern <stern@rowland.harvard.edu>

    commit c318840fb2a42ce25febc95c4c19357acf1ae5ca upstream.

    The dummy-hcd driver was written under the assumption that all the
    parameters in URBs sent to its root hub would be valid. With URBs
    sent from userspace via usbfs, that assumption can be violated.

    In particular, the driver doesn't fully check the port-feature values
    stored in the wValue entry of Clear-Port-Feature and Set-Port-Feature
    requests. Values that are too large can cause the driver to perform
    an invalid left shift of more than 32 bits. Ironically, two of those
    left shifts are unnecessary, because they implement Set-Port-Feature
    requests that hubs are not required to support, according to section
    11.24.2.13 of the USB-2.0 spec.

    This patch adds the appropriate checks for the port feature selector
    values and removes the unnecessary feature settings. It also rejects
    requests to set the TEST feature or to set or clear the INDICATOR and
    C_OVERCURRENT features, as none of these are relevant to dummy-hcd's
    root-hub emulation.

    CC: <stable@vger.kernel.org>
    Reported-and-tested-by: syzbot+5925509f78293baa7331@syzkaller.appspotmail.com
    Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
    Link: https://lore.kernel.org/r/20201230162044.GA727759@rowland.harvard.edu
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/usb/gadget/udc/dummy_hcd.c | 35 +++++++++++++++++++++++------------
    1 file changed, 23 insertions(+), 12 deletions(-)

    --- a/drivers/usb/gadget/udc/dummy_hcd.c
    +++ b/drivers/usb/gadget/udc/dummy_hcd.c
    @@ -2114,9 +2114,21 @@ static int dummy_hub_control(
    dum_hcd->port_status &= ~USB_PORT_STAT_POWER;
    set_link_state(dum_hcd);
    break;
    - default:
    + case USB_PORT_FEAT_ENABLE:
    + case USB_PORT_FEAT_C_ENABLE:
    + case USB_PORT_FEAT_C_SUSPEND:
    + /* Not allowed for USB-3 */
    + if (hcd->speed == HCD_USB3)
    + goto error;
    + fallthrough;
    + case USB_PORT_FEAT_C_CONNECTION:
    + case USB_PORT_FEAT_C_RESET:
    dum_hcd->port_status &= ~(1 << wValue);
    set_link_state(dum_hcd);
    + break;
    + default:
    + /* Disallow INDICATOR and C_OVER_CURRENT */
    + goto error;
    }
    break;
    case GetHubDescriptor:
    @@ -2277,18 +2289,17 @@ static int dummy_hub_control(
    */
    dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50);
    fallthrough;
    + case USB_PORT_FEAT_C_CONNECTION:
    + case USB_PORT_FEAT_C_RESET:
    + case USB_PORT_FEAT_C_ENABLE:
    + case USB_PORT_FEAT_C_SUSPEND:
    + /* Not allowed for USB-3, and ignored for USB-2 */
    + if (hcd->speed == HCD_USB3)
    + goto error;
    + break;
    default:
    - if (hcd->speed == HCD_USB3) {
    - if ((dum_hcd->port_status &
    - USB_SS_PORT_STAT_POWER) != 0) {
    - dum_hcd->port_status |= (1 << wValue);
    - }
    - } else
    - if ((dum_hcd->port_status &
    - USB_PORT_STAT_POWER) != 0) {
    - dum_hcd->port_status |= (1 << wValue);
    - }
    - set_link_state(dum_hcd);
    + /* Disallow TEST, INDICATOR, and C_OVER_CURRENT */
    + goto error;
    }
    break;
    case GetPortErrorCount:

    \
     
     \ /
      Last update: 2021-01-11 14:24    [W:4.663 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site