2019-01-23 18:27:08

by Matwey V. Kornilov

[permalink] [raw]
Subject: [PATCH] usb: musb: Fix potential NULL dereference

We assign "urb->hcpriv = qh;" a few lines down. The valid qh for the urb is
hep->hcpriv in this code path.

Fixes: 714bc5ef3eda ("musb: potential use after free")
Signed-off-by: Matwey V. Kornilov <[email protected]>
---
drivers/usb/musb/musb_host.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index c6118a962d37..6f267716768e 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2336,7 +2336,7 @@ static int musb_urb_enqueue(
* odd, rare, error prone, but legal.
*/
kfree(qh);
- qh = NULL;
+ qh = hep->hcpriv;
ret = 0;
} else
ret = musb_schedule(musb, qh,
--
2.16.4



2019-01-24 18:49:24

by Matwey V. Kornilov

[permalink] [raw]
Subject: Re: [PATCH] usb: musb: Fix potential NULL dereference

By the way, why do we need to store the qh in urb->hcpriv?
qh can always be accessible through urb->ep->hcpriv
Wouldn't it be better to drop entire urb->hcpriv usage?

ср, 23 янв. 2019 г. в 20:52, Matwey V. Kornilov <[email protected]>:
>
> We assign "urb->hcpriv = qh;" a few lines down. The valid qh for the urb is
> hep->hcpriv in this code path.
>
> Fixes: 714bc5ef3eda ("musb: potential use after free")
> Signed-off-by: Matwey V. Kornilov <[email protected]>
> ---
> drivers/usb/musb/musb_host.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
> index c6118a962d37..6f267716768e 100644
> --- a/drivers/usb/musb/musb_host.c
> +++ b/drivers/usb/musb/musb_host.c
> @@ -2336,7 +2336,7 @@ static int musb_urb_enqueue(
> * odd, rare, error prone, but legal.
> */
> kfree(qh);
> - qh = NULL;
> + qh = hep->hcpriv;
> ret = 0;
> } else
> ret = musb_schedule(musb, qh,
> --
> 2.16.4
>


--
With best regards,
Matwey V. Kornilov

2019-01-25 16:37:55

by Bin Liu

[permalink] [raw]
Subject: Re: [PATCH] usb: musb: Fix potential NULL dereference

On Wed, Jan 23, 2019 at 08:51:42PM +0300, Matwey V. Kornilov wrote:
> We assign "urb->hcpriv = qh;" a few lines down. The valid qh for the urb is
> hep->hcpriv in this code path.
>
> Fixes: 714bc5ef3eda ("musb: potential use after free")
> Signed-off-by: Matwey V. Kornilov <[email protected]>
> ---
> drivers/usb/musb/musb_host.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
> index c6118a962d37..6f267716768e 100644
> --- a/drivers/usb/musb/musb_host.c
> +++ b/drivers/usb/musb/musb_host.c
> @@ -2336,7 +2336,7 @@ static int musb_urb_enqueue(
> * odd, rare, error prone, but legal.
> */
> kfree(qh);
> - qh = NULL;
> + qh = hep->hcpriv;
> ret = 0;
> } else
> ret = musb_schedule(musb, qh,

Did you run into any issue? The original code seems to be correct to me.

Regards,
-Bin.

2019-01-25 16:44:51

by Bin Liu

[permalink] [raw]
Subject: Re: [PATCH] usb: musb: Fix potential NULL dereference

On Thu, Jan 24, 2019 at 09:47:02PM +0300, Matwey V. Kornilov wrote:
> By the way, why do we need to store the qh in urb->hcpriv?
> qh can always be accessible through urb->ep->hcpriv
> Wouldn't it be better to drop entire urb->hcpriv usage?

I am not sure why. The code is there since the first commit in a decade
ago. But I tend to agree with you.

In a quick search for urb->hcpriv and urb->ep->hcpriv, based on the
usage in core/hcd.c, it seems to me that urb->hcpriv should not be
changed in each controller driver, but I see both have been used in most
controller drivers. I will leave this to others to educate me.

Regards,
-Bin.

2019-01-25 21:39:48

by Alan Stern

[permalink] [raw]
Subject: Re: [PATCH] usb: musb: Fix potential NULL dereference

On Fri, 25 Jan 2019, Bin Liu wrote:

> On Thu, Jan 24, 2019 at 09:47:02PM +0300, Matwey V. Kornilov wrote:
> > By the way, why do we need to store the qh in urb->hcpriv?
> > qh can always be accessible through urb->ep->hcpriv
> > Wouldn't it be better to drop entire urb->hcpriv usage?
>
> I am not sure why. The code is there since the first commit in a decade
> ago. But I tend to agree with you.
>
> In a quick search for urb->hcpriv and urb->ep->hcpriv, based on the
> usage in core/hcd.c, it seems to me that urb->hcpriv should not be
> changed in each controller driver, but I see both have been used in most
> controller drivers. I will leave this to others to educate me.

In some of the older HCDs, urb->hcpriv != NULL is used to indicate that
urb is on an endpoint queue. Perhaps that usage was copied.

Alan Stern


2019-01-26 09:46:40

by Matwey V. Kornilov

[permalink] [raw]
Subject: Re: [PATCH] usb: musb: Fix potential NULL dereference

сб, 26 янв. 2019 г. в 00:37, Alan Stern <[email protected]>:
>
> On Fri, 25 Jan 2019, Bin Liu wrote:
>
> > On Thu, Jan 24, 2019 at 09:47:02PM +0300, Matwey V. Kornilov wrote:
> > > By the way, why do we need to store the qh in urb->hcpriv?
> > > qh can always be accessible through urb->ep->hcpriv
> > > Wouldn't it be better to drop entire urb->hcpriv usage?
> >
> > I am not sure why. The code is there since the first commit in a decade
> > ago. But I tend to agree with you.
> >
> > In a quick search for urb->hcpriv and urb->ep->hcpriv, based on the
> > usage in core/hcd.c, it seems to me that urb->hcpriv should not be
> > changed in each controller driver, but I see both have been used in most
> > controller drivers. I will leave this to others to educate me.
>
> In some of the older HCDs, urb->hcpriv != NULL is used to indicate that
> urb is on an endpoint queue. Perhaps that usage was copied.
>
> Alan Stern
>

Hi,

Thank you for the explanation. I think that It would be great to
document it somewhere. Such a purpose for variable named `hcpriv' is
not entirely obvious.
Now it is clear to me, why __usb_hcd_giveback_urb() sets urb->hcpriv to NULL.

Returning to my initial patch. I think that it is still valid, though
I admit that the commit message must be rewritten.
In this code path we successfully queued the new urb, so urb->hcpriv
should be NOT NULL indicating that the urb is queued according to Alan
explanation.

musb_urb_enqueue(), musb_host.c line 2345:

if (ret == 0) {
urb->hcpriv = qh;
/* FIXME set urb->start_frame for iso/intr, it's tested in
* musb_start_urb(), but otherwise only konicawc cares ...
*/
}

--
With best regards,
Matwey V. Kornilov