• Anirudh Rayabharam's avatar
    usb: gadget: dummy_hcd: fix gpf in gadget_setup · 4a5d797a
    Anirudh Rayabharam authored
    Fix a general protection fault reported by syzbot due to a race between
    gadget_setup() and gadget_unbind() in raw_gadget.
    
    The gadget core is supposed to guarantee that there won't be any more
    callbacks to the gadget driver once the driver's unbind routine is
    called. That guarantee is enforced in usb_gadget_remove_driver as
    follows:
    
            usb_gadget_disconnect(udc->gadget);
            if (udc->gadget->irq)
                    synchronize_irq(udc->gadget->irq);
            udc->driver->unbind(udc->gadget);
            usb_gadget_udc_stop(udc);
    
    usb_gadget_disconnect turns off the pullup resistor, telling the host
    that the gadget is no longer connected and preventing the transmission
    of any more USB packets. Any packets that have already been received
    are sure to processed by the UDC driver's interrupt handler by the time
    synchronize_irq returns.
    
    But this doesn't work with dummy_hcd, because dummy_hcd doesn't use
    interrupts; it uses a timer instead. It does have code to emulate the
    effect of synchronize_irq, but that code doesn't get invoked at the
    right time -- it currently runs in usb_gadget_udc_stop, after the unbind
    callback instead of before. Indeed, there's no way for
    usb_gadget_remove_driver to invoke this code before the unbind callback.
    
    To fix this, move the synchronize_irq() emulation code to dummy_pullup
    so that it runs before unbind. Also, add a comment explaining why it is
    necessary to have it there.
    
    Reported-by: syzbot+eb4674092e6cc8d9e0bd@syzkaller.appspotmail.com
    Suggested-by: default avatarAlan Stern <stern@rowland.harvard.edu>
    Acked-by: default avatarAlan Stern <stern@rowland.harvard.edu>
    Signed-off-by: default avatarAnirudh Rayabharam <mail@anirudhrb.com>
    Link: https://lore.kernel.org/r/20210419033713.3021-1-mail@anirudhrb.com
    Cc: stable <stable@vger.kernel.org>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    4a5d797a
dummy_hcd.c 72.3 KB