linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] usb: dwc3: gadget: Fix null pointer dereference
@ 2022-05-04  7:28 Albert Wang
  2022-05-04 14:35 ` Greg KH
  0 siblings, 1 reply; 3+ messages in thread
From: Albert Wang @ 2022-05-04  7:28 UTC (permalink / raw)
  To: balbi, gregkh, quic_jackp; +Cc: badhri, linux-usb, linux-kernel, Albert Wang

There are still race conditions to hit the null pointer deference
with my previous commit. So I re-write the code to dereference the
pointer right after checking it is not null.

Fixes: 26288448120b ("usb: dwc3: gadget: Fix null pointer exception")

Signed-off-by: Albert Wang <albertccwang@google.com>
---
 drivers/usb/dwc3/gadget.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 19477f4bbf54..f2792968afd9 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -3366,15 +3366,14 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
 	struct dwc3		*dwc = dep->dwc;
 	bool			no_started_trb = true;
 
-	if (!dep->endpoint.desc)
-		return no_started_trb;
-
 	dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);
 
 	if (dep->flags & DWC3_EP_END_TRANSFER_PENDING)
 		goto out;
 
-	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
+	if (!dep->endpoint.desc)
+		return no_started_trb;
+	else if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
 		list_empty(&dep->started_list) &&
 		(list_empty(&dep->pending_list) || status == -EXDEV))
 		dwc3_stop_active_transfer(dep, true, true);
-- 
2.36.0.464.gb9c8b46e94-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] usb: dwc3: gadget: Fix null pointer dereference
  2022-05-04  7:28 [PATCH] usb: dwc3: gadget: Fix null pointer dereference Albert Wang
@ 2022-05-04 14:35 ` Greg KH
  2022-05-11 16:30   ` Jack Pham
  0 siblings, 1 reply; 3+ messages in thread
From: Greg KH @ 2022-05-04 14:35 UTC (permalink / raw)
  To: Albert Wang; +Cc: balbi, quic_jackp, badhri, linux-usb, linux-kernel

On Wed, May 04, 2022 at 03:28:02PM +0800, Albert Wang wrote:
> There are still race conditions to hit the null pointer deference
> with my previous commit. So I re-write the code to dereference the
> pointer right after checking it is not null.

What race conditions?

And just moving it is not going to solve a race condition, you need a
lock.

> 
> Fixes: 26288448120b ("usb: dwc3: gadget: Fix null pointer exception")
> 
> Signed-off-by: Albert Wang <albertccwang@google.com>
> ---
>  drivers/usb/dwc3/gadget.c | 7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 19477f4bbf54..f2792968afd9 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -3366,15 +3366,14 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
>  	struct dwc3		*dwc = dep->dwc;
>  	bool			no_started_trb = true;
>  
> -	if (!dep->endpoint.desc)
> -		return no_started_trb;
> -
>  	dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);
>  
>  	if (dep->flags & DWC3_EP_END_TRANSFER_PENDING)
>  		goto out;
>  
> -	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
> +	if (!dep->endpoint.desc)
> +		return no_started_trb;
> +	else if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&

There is no locking here, so why would this change do anything but
reduce the window?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] usb: dwc3: gadget: Fix null pointer dereference
  2022-05-04 14:35 ` Greg KH
@ 2022-05-11 16:30   ` Jack Pham
  0 siblings, 0 replies; 3+ messages in thread
From: Jack Pham @ 2022-05-11 16:30 UTC (permalink / raw)
  To: Albert Wang, Greg KH; +Cc: balbi, badhri, linux-usb, linux-kernel

On Wed, May 04, 2022 at 04:35:15PM +0200, Greg KH wrote:
> On Wed, May 04, 2022 at 03:28:02PM +0800, Albert Wang wrote:
> > There are still race conditions to hit the null pointer deference
> > with my previous commit. So I re-write the code to dereference the
> > pointer right after checking it is not null.
> 
> What race conditions?
> 
> And just moving it is not going to solve a race condition, you need a
> lock.

Hmm dwc->lock should already be held when entering this function.

 dwc3_thread_interrupt()
   spin_lock(&dwc->lock);
   -> dwc3_process_event_buf()
     -> dwc3_process_event_entry()
       -> dwc3_endpoint_interrupt()
         -> dwc3_gadget_endpoint_transfer_complete()
           -> dwc3_gadget_endpoint_trbs_complete() [this function]

> > Fixes: 26288448120b ("usb: dwc3: gadget: Fix null pointer exception")
> > 
> > Signed-off-by: Albert Wang <albertccwang@google.com>
> > ---
> >  drivers/usb/dwc3/gadget.c | 7 +++----
> >  1 file changed, 3 insertions(+), 4 deletions(-)
> > 
> > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> > index 19477f4bbf54..f2792968afd9 100644
> > --- a/drivers/usb/dwc3/gadget.c
> > +++ b/drivers/usb/dwc3/gadget.c
> > @@ -3366,15 +3366,14 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
> >  	struct dwc3		*dwc = dep->dwc;
> >  	bool			no_started_trb = true;
> >  
> > -	if (!dep->endpoint.desc)
> > -		return no_started_trb;
> > -
> >  	dwc3_gadget_ep_cleanup_completed_requests(dep, event, status);

Ok I see, this function eventually leads to dwc3_giveback() getting
called, which unlocks dwc->lock before calling each requests' callbacks
and reacquires it afterwards.

This gives an opportunity for usb_ep_disable() to come in and clear
the descriptor.

You should add an inline comment to make that clear that's what's
happening here.

> >  	if (dep->flags & DWC3_EP_END_TRANSFER_PENDING)
> >  		goto out;
> >  
> > -	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
> > +	if (!dep->endpoint.desc)
> > +		return no_started_trb;
> > +	else if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&

Drop the 'else', it isn't needed due to the return in the preceding
check.

> There is no locking here, so why would this change do anything but
> reduce the window?

After inspecting further, we do see locking is implicit, with the main
gotcha being the unlock/re-lock that happens behind the scenes, which
actually creates a window for the race to happen.  This change moves the
NULL check to be adjacent to where it's used, and more importantly after
the window is "closed" (since we now have the lock again).

Additional comments and more descriptive commit text should help make
this more clear.

Thanks,
Jack

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-05-11 16:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-05-04  7:28 [PATCH] usb: dwc3: gadget: Fix null pointer dereference Albert Wang
2022-05-04 14:35 ` Greg KH
2022-05-11 16:30   ` Jack Pham

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).