usb: gadget: Don't attempt to dequeue requests for a disabled USB endpoint on Freescale hardware

Started by Simon Haggett on Oct 19, 2012 · 10 messages from 4 authors · Last reply Oct 26, 2012

Subsystems (3)

Maintainers (3)

STALE5131d

open the first message on its own page

Message details and related content
Some gadget drivers may attempt to dequeue requests for an endpoint that has
already been disabled. For example, in the UVC gadget driver, uvc_function_set_alt()
will call usb_ep_disable() when alt setting 0 is selected. When the userspace
application subsequently issues the VIDIOC_STREAMOFF ioctl, uvc_video_enable()
invokes usb_ep_dequeue() to ensure that all requests have been cancelled.

For the Freescale High Speed Dual-Role USB controller, fsl_ep_dequeue() provides
the implementation of usb_ep_dequeue(). If this is called for a disabled endpoint,
a kernel oops will occur when the ep->ep.desc field is dereferenced (by ep_index()).
fsl_ep_disable() sets this field to NULL, as well as deleting all pending requests
for the endpoint.

This patch adds an additional check to fsl_ep_dequeue() to ensure that the
endpoint has not already been disabled before attempting to dequeue requests.

Signed-off-by: Simon Haggett <redacted>
---
 drivers/usb/gadget/fsl_udc_core.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 6ae70cb..acd513b 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -955,7 +955,10 @@ static int fsl_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
 	int ep_num, stopped, ret = 0;
 	u32 epctrl;
 
-	if (!_ep || !_req)
+	/* Ensure that the ep and request are valid, and the ep is not
+	 * disabled
+	 */
+	if (!_ep || !_req || !ep->ep.desc)
 		return -EINVAL;
 
 	spin_lock_irqsave(&ep->udc->lock, flags);
-- 
1.7.4.1
Message details and related content
Hi,

On Fri, Oct 19, 2012 at 06:19:26PM +0100, Simon Haggett wrote:
Some gadget drivers may attempt to dequeue requests for an endpoint that has
already been disabled. For example, in the UVC gadget driver, uvc_function_set_alt()
will call usb_ep_disable() when alt setting 0 is selected. When the userspace
application subsequently issues the VIDIOC_STREAMOFF ioctl, uvc_video_enable()
invokes usb_ep_dequeue() to ensure that all requests have been cancelled.
bug is on uvc gadget, then. Laurent ?

Also, fsl should be removed from the tree, I'm trying to persuade iMX
folks to use drivers/usb/chipidea instead.
quoted hunk
For the Freescale High Speed Dual-Role USB controller, fsl_ep_dequeue() provides
the implementation of usb_ep_dequeue(). If this is called for a disabled endpoint,
a kernel oops will occur when the ep->ep.desc field is dereferenced (by ep_index()).
fsl_ep_disable() sets this field to NULL, as well as deleting all pending requests
for the endpoint.

This patch adds an additional check to fsl_ep_dequeue() to ensure that the
endpoint has not already been disabled before attempting to dequeue requests.

Signed-off-by: Simon Haggett <redacted>
---
 drivers/usb/gadget/fsl_udc_core.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 6ae70cb..acd513b 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -955,7 +955,10 @@ static int fsl_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
 	int ep_num, stopped, ret = 0;
 	u32 epctrl;
 
-	if (!_ep || !_req)
+	/* Ensure that the ep and request are valid, and the ep is not
+	 * disabled
+	 */
+	if (!_ep || !_req || !ep->ep.desc)
 		return -EINVAL;
 
 	spin_lock_irqsave(&ep->udc->lock, flags);
-- 
1.7.4.1
-- 
balbi
Message details and related content
-----Original Message-----
From: Felipe Balbi [mailto:<redacted>]
Sent: Saturday, October 20, 2012 1:37 AM
To: Simon Haggett
Cc: Li Yang-R58472; Felipe Balbi; Greg Kroah-Hartman; linux-
usb@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; linux-
kernel@vger.kernel.org; Laurent Pinchart
Subject: Re: [PATCH 1/1] usb: gadget: Don't attempt to dequeue requests
for a disabled USB endpoint on Freescale hardware
=20
Hi,
=20
On Fri, Oct 19, 2012 at 06:19:26PM +0100, Simon Haggett wrote:
quoted
Some gadget drivers may attempt to dequeue requests for an endpoint
that has already been disabled. For example, in the UVC gadget driver,
uvc_function_set_alt() will call usb_ep_disable() when alt setting 0
is selected. When the userspace application subsequently issues the
VIDIOC_STREAMOFF ioctl, uvc_video_enable() invokes usb_ep_dequeue() to
ensure that all requests have been cancelled.
=20
bug is on uvc gadget, then. Laurent ?
=20
Also, fsl should be removed from the tree, I'm trying to persuade iMX
folks to use drivers/usb/chipidea instead.
Besides the iMX usage, the driver is also being used by many Freescale Powe=
rPC/Coldfire SoCs.  I agree that it's ideal to move to a common driver.  Bu=
t it is a large task to make the chipidea driver works for all the hardware=
 that fsl_udc had supported and been tested on.
=20
quoted
For the Freescale High Speed Dual-Role USB controller,
fsl_ep_dequeue() provides the implementation of usb_ep_dequeue(). If
this is called for a disabled endpoint, a kernel oops will occur when
the ep->ep.desc field is dereferenced (by ep_index()).
quoted
fsl_ep_disable() sets this field to NULL, as well as deleting all
pending requests for the endpoint.

This patch adds an additional check to fsl_ep_dequeue() to ensure that
the endpoint has not already been disabled before attempting to dequeue
requests.
quoted
Signed-off-by: Simon Haggett <redacted>
---
 drivers/usb/gadget/fsl_udc_core.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/usb/gadget/fsl_udc_core.c
b/drivers/usb/gadget/fsl_udc_core.c
index 6ae70cb..acd513b 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -955,7 +955,10 @@ static int fsl_ep_dequeue(struct usb_ep *_ep,
struct usb_request *_req)
quoted
 	int ep_num, stopped, ret =3D 0;
 	u32 epctrl;

-	if (!_ep || !_req)
+	/* Ensure that the ep and request are valid, and the ep is not
+	 * disabled
+	 */
+	if (!_ep || !_req || !ep->ep.desc)
 		return -EINVAL;

 	spin_lock_irqsave(&ep->udc->lock, flags);
--
1.7.4.1
=20
--

1 more quoted lines

Message details and related content
On Mon, Oct 22, 2012 at 03:33:19AM +0000, Li Yang-R58472 wrote:
quoted
-----Original Message-----
From: Felipe Balbi [mailto:<redacted>]
Sent: Saturday, October 20, 2012 1:37 AM
To: Simon Haggett
Cc: Li Yang-R58472; Felipe Balbi; Greg Kroah-Hartman; linux-
usb@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; linux-
kernel@vger.kernel.org; Laurent Pinchart
Subject: Re: [PATCH 1/1] usb: gadget: Don't attempt to dequeue requests
for a disabled USB endpoint on Freescale hardware

Hi,

On Fri, Oct 19, 2012 at 06:19:26PM +0100, Simon Haggett wrote:
quoted
Some gadget drivers may attempt to dequeue requests for an endpoint
that has already been disabled. For example, in the UVC gadget driver,
uvc_function_set_alt() will call usb_ep_disable() when alt setting 0
is selected. When the userspace application subsequently issues the
VIDIOC_STREAMOFF ioctl, uvc_video_enable() invokes usb_ep_dequeue() to
ensure that all requests have been cancelled.

bug is on uvc gadget, then. Laurent ?

Also, fsl should be removed from the tree, I'm trying to persuade iMX
folks to use drivers/usb/chipidea instead.
Besides the iMX usage, the driver is also being used by many Freescale
PowerPC/Coldfire SoCs.  I agree that it's ideal to move to a common
driver.  But it is a large task to make the chipidea driver works for
all the hardware that fsl_udc had supported and been tested on.
I understand that, but we just can't keep so many duplicated drivers in
mainline. chipidea udc had at least 3 different implementations. Now
it's the time to combine all of those and stick to a single driver.

Just make a plan to slowly move towards chipidea in the upcoming few
merge windows. I can continue to take in bugfixes for fsl_udc, but only
if I see that you guys are working towards merging with chipidea driver.

-- 
balbi
Message details and related content
Hi,

On Monday 22 October 2012 03:33:19 Li Yang-R58472 wrote:
On Saturday, October 20, 2012 1:37 AM Felipe Balbi wrote:
quoted
On Fri, Oct 19, 2012 at 06:19:26PM +0100, Simon Haggett wrote:
quoted
Some gadget drivers may attempt to dequeue requests for an endpoint
that has already been disabled. For example, in the UVC gadget driver,
uvc_function_set_alt() will call usb_ep_disable() when alt setting 0
is selected. When the userspace application subsequently issues the
VIDIOC_STREAMOFF ioctl, uvc_video_enable() invokes usb_ep_dequeue() to
ensure that all requests have been cancelled.

bug is on uvc gadget, then. Laurent ?
We've discussed this topic a couple of months before. I believe that's not a 
bug.

http://68.183.106.108/lists/linux-usb/msg68869.html
quoted
Also, fsl should be removed from the tree, I'm trying to persuade iMX
folks to use drivers/usb/chipidea instead.
Besides the iMX usage, the driver is also being used by many Freescale
PowerPC/Coldfire SoCs.  I agree that it's ideal to move to a common driver.
But it is a large task to make the chipidea driver works for all the
hardware that fsl_udc had supported and been tested on.
quoted
quoted
For the Freescale High Speed Dual-Role USB controller,
fsl_ep_dequeue() provides the implementation of usb_ep_dequeue(). If
this is called for a disabled endpoint, a kernel oops will occur when
the ep->ep.desc field is dereferenced (by ep_index()).
quoted
fsl_ep_disable() sets this field to NULL, as well as deleting all
pending requests for the endpoint.

This patch adds an additional check to fsl_ep_dequeue() to ensure that
the endpoint has not already been disabled before attempting to dequeue
requests.
quoted
Signed-off-by: Simon Haggett <redacted>
---

 drivers/usb/gadget/fsl_udc_core.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/usb/gadget/fsl_udc_core.c
b/drivers/usb/gadget/fsl_udc_core.c
index 6ae70cb..acd513b 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -955,7 +955,10 @@ static int fsl_ep_dequeue(struct usb_ep *_ep,
struct usb_request *_req)
quoted
 	int ep_num, stopped, ret = 0;
 	u32 epctrl;

-	if (!_ep || !_req)

5 more quoted lines

Shouldn't that last check be done with a lock taken ?
quoted
quoted
 	spin_lock_irqsave(&ep->udc->lock, flags);
-- 
Regards,

Laurent Pinchart
Message details and related content
Hi,

On Mon, Oct 22, 2012 at 12:47:21PM +0200, Laurent Pinchart wrote:
Hi,

On Monday 22 October 2012 03:33:19 Li Yang-R58472 wrote:
quoted
On Saturday, October 20, 2012 1:37 AM Felipe Balbi wrote:
quoted
On Fri, Oct 19, 2012 at 06:19:26PM +0100, Simon Haggett wrote:
quoted
Some gadget drivers may attempt to dequeue requests for an endpoint
that has already been disabled. For example, in the UVC gadget driver,
uvc_function_set_alt() will call usb_ep_disable() when alt setting 0
is selected. When the userspace application subsequently issues the
VIDIOC_STREAMOFF ioctl, uvc_video_enable() invokes usb_ep_dequeue() to
ensure that all requests have been cancelled.

bug is on uvc gadget, then. Laurent ?
We've discussed this topic a couple of months before. I believe that's not a 
bug.

http://68.183.106.108/lists/linux-usb/msg68869.html
fair enough :-)

That's a different case, however. At the link above we're discussing
dequeueing a request which is already being dequeued. $SUBJECT is trying
to fix dequeueing of a request for an endpoint which isn't even enabled.

-- 
balbi
Message details and related content
Hi

On 22/10/12 11:47, Laurent Pinchart wrote:
Hi,

On Monday 22 October 2012 03:33:19 Li Yang-R58472 wrote:
quoted
On Saturday, October 20, 2012 1:37 AM Felipe Balbi wrote:
quoted
On Fri, Oct 19, 2012 at 06:19:26PM +0100, Simon Haggett wrote:
quoted
Some gadget drivers may attempt to dequeue requests for an endpoint
that has already been disabled. For example, in the UVC gadget driver,
uvc_function_set_alt() will call usb_ep_disable() when alt setting 0
is selected. When the userspace application subsequently issues the
VIDIOC_STREAMOFF ioctl, uvc_video_enable() invokes usb_ep_dequeue() to
ensure that all requests have been cancelled.

bug is on uvc gadget, then. Laurent ?
We've discussed this topic a couple of months before. I believe that's not a
bug.

http://68.183.106.108/lists/linux-usb/msg68869.html
quoted
quoted
Also, fsl should be removed from the tree, I'm trying to persuade iMX
folks to use drivers/usb/chipidea instead.
Besides the iMX usage, the driver is also being used by many Freescale
PowerPC/Coldfire SoCs.  I agree that it's ideal to move to a common driver.
But it is a large task to make the chipidea driver works for all the
hardware that fsl_udc had supported and been tested on.
quoted
quoted
For the Freescale High Speed Dual-Role USB controller,
fsl_ep_dequeue() provides the implementation of usb_ep_dequeue(). If
this is called for a disabled endpoint, a kernel oops will occur when
the ep->ep.desc field is dereferenced (by ep_index()).
quoted
fsl_ep_disable() sets this field to NULL, as well as deleting all
pending requests for the endpoint.

This patch adds an additional check to fsl_ep_dequeue() to ensure that
the endpoint has not already been disabled before attempting to dequeue

27 more quoted lines

I had presumed a lock wasn't necessary because ep->ep.desc is only set to NULL by fsl_ep_disable() which, since it is called by usb_ep_disable(), should only be invoked when no other task is using the endpoint (according to include/linux/usb/gadget.h). Furthermore, the chipidea UDC driver does check the equivalent of this field is not NULL without taking a lock (ep_dequeue() in drivers/usb/chipidea/udc.c).

However, it is possible that I'm misunderstanding something here, so apologies if I am.
quoted
quoted
quoted
  	spin_lock_irqsave(&ep->udc->lock, flags);
Many thanks

Simon
Message details and related content
Hi Simon,

On Monday 22 October 2012 12:49:51 Simon Haggett wrote:
On 22/10/12 11:47, Laurent Pinchart wrote:
quoted
On Monday 22 October 2012 03:33:19 Li Yang-R58472 wrote:
quoted
On Saturday, October 20, 2012 1:37 AM Felipe Balbi wrote:
quoted
On Fri, Oct 19, 2012 at 06:19:26PM +0100, Simon Haggett wrote:
quoted
Some gadget drivers may attempt to dequeue requests for an endpoint
that has already been disabled. For example, in the UVC gadget driver,
uvc_function_set_alt() will call usb_ep_disable() when alt setting 0
is selected. When the userspace application subsequently issues the
VIDIOC_STREAMOFF ioctl, uvc_video_enable() invokes usb_ep_dequeue() to
ensure that all requests have been cancelled.

bug is on uvc gadget, then. Laurent ?
We've discussed this topic a couple of months before. I believe that's not
a bug.

http://68.183.106.108/lists/linux-usb/msg68869.html
quoted
quoted
Also, fsl should be removed from the tree, I'm trying to persuade iMX
folks to use drivers/usb/chipidea instead.
Besides the iMX usage, the driver is also being used by many Freescale
PowerPC/Coldfire SoCs.  I agree that it's ideal to move to a common
driver.
But it is a large task to make the chipidea driver works for all the
hardware that fsl_udc had supported and been tested on.
quoted
quoted
For the Freescale High Speed Dual-Role USB controller,
fsl_ep_dequeue() provides the implementation of usb_ep_dequeue(). If
this is called for a disabled endpoint, a kernel oops will occur when
the ep->ep.desc field is dereferenced (by ep_index()).
quoted
fsl_ep_disable() sets this field to NULL, as well as deleting all
pending requests for the endpoint.

This patch adds an additional check to fsl_ep_dequeue() to ensure that
the endpoint has not already been disabled before attempting to dequeue

39 more quoted lines

I might be wrong as well :-) I just wanted to point out something that 
appeared to me as a possible issue.
quoted
quoted
quoted
quoted
  	spin_lock_irqsave(&ep->udc->lock, flags);
-- 
Regards,

Laurent Pinchart
Message details and related content
Hi Felipe,

On Monday 22 October 2012 13:56:01 Felipe Balbi wrote:
On Mon, Oct 22, 2012 at 12:47:21PM +0200, Laurent Pinchart wrote:
quoted
On Monday 22 October 2012 03:33:19 Li Yang-R58472 wrote:
quoted
On Saturday, October 20, 2012 1:37 AM Felipe Balbi wrote:
quoted
On Fri, Oct 19, 2012 at 06:19:26PM +0100, Simon Haggett wrote:
quoted
Some gadget drivers may attempt to dequeue requests for an endpoint
that has already been disabled. For example, in the UVC gadget
driver, uvc_function_set_alt() will call usb_ep_disable() when alt
setting 0 is selected. When the userspace application subsequently
issues the VIDIOC_STREAMOFF ioctl, uvc_video_enable() invokes
usb_ep_dequeue() to ensure that all requests have been cancelled.
bug is on uvc gadget, then. Laurent ?
We've discussed this topic a couple of months before. I believe that's not
a bug.

http://68.183.106.108/lists/linux-usb/msg68869.html
fair enough :-)

That's a different case, however. At the link above we're discussing
dequeueing a request which is already being dequeued. $SUBJECT is trying
to fix dequeueing of a request for an endpoint which isn't even enabled.
You've got a point there :-) That's a different case indeed, I'm open to (at 
least evaluating) a fix in the UVC gadget driver if you think that's better.

-- 
Regards,

Laurent Pinchart
Message details and related content
Hi,

On Thu, Oct 25, 2012 at 02:36:24AM +0200, Laurent Pinchart wrote:
Hi Felipe,

On Monday 22 October 2012 13:56:01 Felipe Balbi wrote:
quoted
On Mon, Oct 22, 2012 at 12:47:21PM +0200, Laurent Pinchart wrote:
quoted
On Monday 22 October 2012 03:33:19 Li Yang-R58472 wrote:
quoted
On Saturday, October 20, 2012 1:37 AM Felipe Balbi wrote:
quoted
On Fri, Oct 19, 2012 at 06:19:26PM +0100, Simon Haggett wrote:
quoted
Some gadget drivers may attempt to dequeue requests for an endpoint
that has already been disabled. For example, in the UVC gadget
driver, uvc_function_set_alt() will call usb_ep_disable() when alt
setting 0 is selected. When the userspace application subsequently
issues the VIDIOC_STREAMOFF ioctl, uvc_video_enable() invokes
usb_ep_dequeue() to ensure that all requests have been cancelled.
bug is on uvc gadget, then. Laurent ?
We've discussed this topic a couple of months before. I believe that's not
a bug.

http://68.183.106.108/lists/linux-usb/msg68869.html
fair enough :-)

That's a different case, however. At the link above we're discussing
dequeueing a request which is already being dequeued. $SUBJECT is trying
to fix dequeueing of a request for an endpoint which isn't even enabled.
You've got a point there :-) That's a different case indeed, I'm open to (at 
least evaluating) a fix in the UVC gadget driver if you think that's better.
I _do_ think that's better. If the endpoint isn't even enabled, why are
you trying to dequeue a request ? :-)

cheers

-- 
balbi
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help