lkml.org 
[lkml]   [2019]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.1 14/85] media: usb: siano: Fix general protection fault in smsusb
    Date
    From: Alan Stern <stern@rowland.harvard.edu>

    commit 31e0456de5be379b10fea0fa94a681057114a96e upstream.

    The syzkaller USB fuzzer found a general-protection-fault bug in the
    smsusb part of the Siano DVB driver. The fault occurs during probe
    because the driver assumes without checking that the device has both
    IN and OUT endpoints and the IN endpoint is ep1.

    By slightly rearranging the driver's initialization code, we can make
    the appropriate checks early on and thus avoid the problem. If the
    expected endpoints aren't present, the new code safely returns -ENODEV
    from the probe routine.

    Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
    Reported-and-tested-by: syzbot+53f029db71c19a47325a@syzkaller.appspotmail.com
    CC: <stable@vger.kernel.org>
    Reviewed-by: Johan Hovold <johan@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/media/usb/siano/smsusb.c | 33 ++++++++++++++++++++-------------
    1 file changed, 20 insertions(+), 13 deletions(-)

    --- a/drivers/media/usb/siano/smsusb.c
    +++ b/drivers/media/usb/siano/smsusb.c
    @@ -400,6 +400,7 @@ static int smsusb_init_device(struct usb
    struct smsusb_device_t *dev;
    void *mdev;
    int i, rc;
    + int in_maxp;

    /* create device object */
    dev = kzalloc(sizeof(struct smsusb_device_t), GFP_KERNEL);
    @@ -411,6 +412,24 @@ static int smsusb_init_device(struct usb
    dev->udev = interface_to_usbdev(intf);
    dev->state = SMSUSB_DISCONNECTED;

    + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
    + struct usb_endpoint_descriptor *desc =
    + &intf->cur_altsetting->endpoint[i].desc;
    +
    + if (desc->bEndpointAddress & USB_DIR_IN) {
    + dev->in_ep = desc->bEndpointAddress;
    + in_maxp = usb_endpoint_maxp(desc);
    + } else {
    + dev->out_ep = desc->bEndpointAddress;
    + }
    + }
    +
    + pr_debug("in_ep = %02x, out_ep = %02x\n", dev->in_ep, dev->out_ep);
    + if (!dev->in_ep || !dev->out_ep) { /* Missing endpoints? */
    + smsusb_term_device(intf);
    + return -ENODEV;
    + }
    +
    params.device_type = sms_get_board(board_id)->type;

    switch (params.device_type) {
    @@ -425,24 +444,12 @@ static int smsusb_init_device(struct usb
    /* fall-thru */
    default:
    dev->buffer_size = USB2_BUFFER_SIZE;
    - dev->response_alignment =
    - le16_to_cpu(dev->udev->ep_in[1]->desc.wMaxPacketSize) -
    - sizeof(struct sms_msg_hdr);
    + dev->response_alignment = in_maxp - sizeof(struct sms_msg_hdr);

    params.flags |= SMS_DEVICE_FAMILY2;
    break;
    }

    - for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {
    - if (intf->cur_altsetting->endpoint[i].desc. bEndpointAddress & USB_DIR_IN)
    - dev->in_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
    - else
    - dev->out_ep = intf->cur_altsetting->endpoint[i].desc.bEndpointAddress;
    - }
    -
    - pr_debug("in_ep = %02x, out_ep = %02x\n",
    - dev->in_ep, dev->out_ep);
    -
    params.device = &dev->udev->dev;
    params.usb_device = dev->udev;
    params.buffer_size = dev->buffer_size;

    \
     
     \ /
      Last update: 2019-06-07 17:54    [W:4.215 / U:0.308 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site