Re: [PATCH] xhci: Fix NULL pointer dereference at endpoint zero reset.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Mathias,

Missatge de Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx> del dia dv.,
2 d’ag. 2019 a les 16:59:
>
> Usb core will reset the default control endpoint "ep0" before resetting
> a device. if the endpoint has a valid pointer back to the usb device
> then the xhci driver reset callback will try to clear the toggle for
> the endpoint.
>
> ep0 didn't use to have this pointer set as ep0 was always allocated
> by default together with a xhci slot for the usb device. Other endpoints
> got their usb device pointer set in xhci_add_endpoint()
>
> This changed with commit ef513be0a905 ("usb: xhci: Add Clear_TT_Buffer")
> which sets the pointer for any endpoint on a FS/LS device behind a
> HS hub that halts, including ep0.
>
> If xHC controller needs to be reset at resume, then all the xhci slots
> will be lost. Slots will be reenabled and reallocated at device reset,
> but unlike other endpoints the ep0 is reset before device reset, while
> the xhci slot may still be invalid, causing NULL pointer dereference.
>
> Fix it by checking that the endpoint has both a usb device pointer and
> valid xhci slot before trying to clear the toggle.
>
> This issue was not seen earlier as ep0 didn't use to have a valid usb
> device pointer, and other endpoints were only reset after device reset
> when xhci slots were properly reenabled.
>
> Reported-by: Bob Gleitsmann <rjgleits@xxxxxxxxxxxxx>
> Reported-by: Enric Balletbo Serra <eballetbo@xxxxxxxxx>
> Fixes: ef513be0a905 ("usb: xhci: Add Clear_TT_Buffer")
> Signed-off-by: Mathias Nyman <mathias.nyman@xxxxxxxxxxxxxxx>

Thanks for spending time looking at this issue and for the clear
explanation. The patch fixes the issue for me, so

Tested-by: Enric Balletbo i Serra <enric.balletbo@xxxxxxxxxxxxx>

> ---
>  drivers/usb/host/xhci.c | 10 ++++++++++
>  1 file changed, 10 insertions(+)
>
> diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
> index 248cd7a..03d1e55 100644
> --- a/drivers/usb/host/xhci.c
> +++ b/drivers/usb/host/xhci.c
> @@ -3089,8 +3089,18 @@ static void xhci_endpoint_reset(struct usb_hcd *hcd,
>                 return;
>         udev = (struct usb_device *) host_ep->hcpriv;
>         vdev = xhci->devs[udev->slot_id];
> +
> +       /*
> +        * vdev may be lost due to xHC restore error and re-initialization
> +        * during S3/S4 resume. A new vdev will be allocated later by
> +        * xhci_discover_or_reset_device()
> +        */
> +       if (!udev->slot_id || !vdev)
> +               return;
>         ep_index = xhci_get_endpoint_index(&host_ep->desc);
>         ep = &vdev->eps[ep_index];
> +       if (!ep)
> +               return;
>
>         /* Bail out if toggle is already being cleared by a endpoint reset */
>         if (ep->ep_state & EP_HARD_CLEAR_TOGGLE) {
> --
> 2.7.4
>




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux