linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] usb: gadget: Fix double free of device descriptor pointers
@ 2021-04-21 19:47 Wesley Cheng
  2021-04-22 11:01 ` Felipe Balbi
  0 siblings, 1 reply; 7+ messages in thread
From: Wesley Cheng @ 2021-04-21 19:47 UTC (permalink / raw)
  To: balbi, gregkh, peter.chen
  Cc: linux-usb, linux-kernel, Hemant Kumar, stable, Wesley Cheng

From: Hemant Kumar <hemantk@codeaurora.org>

Upon driver unbind usb_free_all_descriptors() function frees all
speed descriptor pointers without setting them to NULL. In case
gadget speed changes (i.e from super speed plus to super speed)
after driver unbind only upto super speed descriptor pointers get
populated. Super speed plus desc still holds the stale (already
freed) pointer. Fix this issue by setting all descriptor pointers
to NULL after freeing them in usb_free_all_descriptors().

Fixes: f5c61225cf29 ("usb: gadget: Update function for SuperSpeedPlus")
cc: stable@vger.kernel.org
Reviewed-by: Peter Chen <peter.chen@kernel.org>
Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
Signed-off-by: Wesley Cheng <wcheng@codeaurora.org>
---
Changes in v2:
 - Add Reviewed-by and Fixes tags
 - CC'ed stable tree

 drivers/usb/gadget/config.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c
index 2d11535..8bb2577 100644
--- a/drivers/usb/gadget/config.c
+++ b/drivers/usb/gadget/config.c
@@ -194,9 +194,13 @@ EXPORT_SYMBOL_GPL(usb_assign_descriptors);
 void usb_free_all_descriptors(struct usb_function *f)
 {
 	usb_free_descriptors(f->fs_descriptors);
+	f->fs_descriptors = NULL;
 	usb_free_descriptors(f->hs_descriptors);
+	f->hs_descriptors = NULL;
 	usb_free_descriptors(f->ss_descriptors);
+	f->ss_descriptors = NULL;
 	usb_free_descriptors(f->ssp_descriptors);
+	f->ssp_descriptors = NULL;
 }
 EXPORT_SYMBOL_GPL(usb_free_all_descriptors);
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


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

* Re: [PATCH v2] usb: gadget: Fix double free of device descriptor pointers
  2021-04-21 19:47 [PATCH v2] usb: gadget: Fix double free of device descriptor pointers Wesley Cheng
@ 2021-04-22 11:01 ` Felipe Balbi
  2021-04-23 19:10   ` Wesley Cheng
  0 siblings, 1 reply; 7+ messages in thread
From: Felipe Balbi @ 2021-04-22 11:01 UTC (permalink / raw)
  To: Wesley Cheng, gregkh, peter.chen
  Cc: linux-usb, linux-kernel, Hemant Kumar, stable, Wesley Cheng

[-- Attachment #1: Type: text/plain, Size: 753 bytes --]


Hi,

Wesley Cheng <wcheng@codeaurora.org> writes:

> From: Hemant Kumar <hemantk@codeaurora.org>
>
> Upon driver unbind usb_free_all_descriptors() function frees all
> speed descriptor pointers without setting them to NULL. In case
> gadget speed changes (i.e from super speed plus to super speed)
> after driver unbind only upto super speed descriptor pointers get
> populated. Super speed plus desc still holds the stale (already
> freed) pointer. Fix this issue by setting all descriptor pointers
> to NULL after freeing them in usb_free_all_descriptors().

could you describe this a little better? How can one trigger this case?
Is the speed demotion happening after unbinding? It's not clear how to
cause this bug.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 857 bytes --]

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

* Re: [PATCH v2] usb: gadget: Fix double free of device descriptor pointers
  2021-04-22 11:01 ` Felipe Balbi
@ 2021-04-23 19:10   ` Wesley Cheng
  2021-04-24  4:16     ` Wesley Cheng
  0 siblings, 1 reply; 7+ messages in thread
From: Wesley Cheng @ 2021-04-23 19:10 UTC (permalink / raw)
  To: Felipe Balbi, gregkh, peter.chen
  Cc: linux-usb, linux-kernel, Hemant Kumar, stable



On 4/22/2021 4:01 AM, Felipe Balbi wrote:
> 
> Hi,
> 
> Wesley Cheng <wcheng@codeaurora.org> writes:
> 
>> From: Hemant Kumar <hemantk@codeaurora.org>
>>
>> Upon driver unbind usb_free_all_descriptors() function frees all
>> speed descriptor pointers without setting them to NULL. In case
>> gadget speed changes (i.e from super speed plus to super speed)
>> after driver unbind only upto super speed descriptor pointers get
>> populated. Super speed plus desc still holds the stale (already
>> freed) pointer. Fix this issue by setting all descriptor pointers
>> to NULL after freeing them in usb_free_all_descriptors().
> 
> could you describe this a little better? How can one trigger this case?
> Is the speed demotion happening after unbinding? It's not clear how to
> cause this bug.
> 
Hi Felipe,

Internally, we have a mechanism to switch the DWC3 core maximum speed
parameter dynamically for displayport use cases.  This issue happens
whenever we have a maximum speed change occur on the USB gadget, which
for DWC3 happens whenever we call gadget init.  When we switch in and
out of host mode, gadget init is being executed, leading to the change
in the USB gadget max speed parameter:

dwc->gadget->max_speed		= dwc->maximum_speed;

I know that configFS gadget has the max_speed sysfs file, which is a
similar mechanism, but I haven't tried to see if we can reproduce the
same issue with it.  Let me see if we can reproduce this with that
configfs speed setting.

Thanks
Wesley Cheng

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH v2] usb: gadget: Fix double free of device descriptor pointers
  2021-04-23 19:10   ` Wesley Cheng
@ 2021-04-24  4:16     ` Wesley Cheng
  2021-04-24  8:05       ` Felipe Balbi
  0 siblings, 1 reply; 7+ messages in thread
From: Wesley Cheng @ 2021-04-24  4:16 UTC (permalink / raw)
  To: Felipe Balbi, gregkh, peter.chen
  Cc: linux-usb, linux-kernel, Hemant Kumar, stable



On 4/23/2021 12:10 PM, Wesley Cheng wrote:
> 
> 
> On 4/22/2021 4:01 AM, Felipe Balbi wrote:
>>
>> Hi,
>>
>> Wesley Cheng <wcheng@codeaurora.org> writes:
>>
>>> From: Hemant Kumar <hemantk@codeaurora.org>
>>>
>>> Upon driver unbind usb_free_all_descriptors() function frees all
>>> speed descriptor pointers without setting them to NULL. In case
>>> gadget speed changes (i.e from super speed plus to super speed)
>>> after driver unbind only upto super speed descriptor pointers get
>>> populated. Super speed plus desc still holds the stale (already
>>> freed) pointer. Fix this issue by setting all descriptor pointers
>>> to NULL after freeing them in usb_free_all_descriptors().
>>
>> could you describe this a little better? How can one trigger this case?
>> Is the speed demotion happening after unbinding? It's not clear how to
>> cause this bug.
>>
> Hi Felipe,
> 
> Internally, we have a mechanism to switch the DWC3 core maximum speed
> parameter dynamically for displayport use cases.  This issue happens
> whenever we have a maximum speed change occur on the USB gadget, which
> for DWC3 happens whenever we call gadget init.  When we switch in and
> out of host mode, gadget init is being executed, leading to the change
> in the USB gadget max speed parameter:
> 
> dwc->gadget->max_speed		= dwc->maximum_speed;
> 
> I know that configFS gadget has the max_speed sysfs file, which is a
> similar mechanism, but I haven't tried to see if we can reproduce the
> same issue with it.  Let me see if we can reproduce this with that
> configfs speed setting.
> 
> Thanks
> Wesley Cheng
> 

Hi Felipe,

So I tried with doing it through the configFS max_speed, but it doesn't
have the same effect, as the setting done in dwc3_gadget_init() will
still be assigning the composite/UDC device's maximum speed to SSP/SS.
This is what the usb_assign_descriptor() uses to determine whether or
not to copy the SSP and SS descriptors.

So in summary, at least for a DWC3 based subsystem, the only way to
reproduce it is if there is a way to dynamically switch the DWC3 core
max speed parameter.

Thanks
Wesley Cheng

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH v2] usb: gadget: Fix double free of device descriptor pointers
  2021-04-24  4:16     ` Wesley Cheng
@ 2021-04-24  8:05       ` Felipe Balbi
  2021-04-24  8:37         ` Wesley Cheng
  0 siblings, 1 reply; 7+ messages in thread
From: Felipe Balbi @ 2021-04-24  8:05 UTC (permalink / raw)
  To: Wesley Cheng, gregkh, peter.chen
  Cc: linux-usb, linux-kernel, Hemant Kumar, stable

[-- Attachment #1: Type: text/plain, Size: 2241 bytes --]


Hi,

Wesley Cheng <wcheng@codeaurora.org> writes:
>>>> From: Hemant Kumar <hemantk@codeaurora.org>
>>>>
>>>> Upon driver unbind usb_free_all_descriptors() function frees all
>>>> speed descriptor pointers without setting them to NULL. In case
>>>> gadget speed changes (i.e from super speed plus to super speed)
>>>> after driver unbind only upto super speed descriptor pointers get
>>>> populated. Super speed plus desc still holds the stale (already
>>>> freed) pointer. Fix this issue by setting all descriptor pointers
>>>> to NULL after freeing them in usb_free_all_descriptors().
>>>
>>> could you describe this a little better? How can one trigger this case?
>>> Is the speed demotion happening after unbinding? It's not clear how to
>>> cause this bug.
>>>
>> Hi Felipe,
>> 
>> Internally, we have a mechanism to switch the DWC3 core maximum speed
>> parameter dynamically for displayport use cases.  This issue happens
>> whenever we have a maximum speed change occur on the USB gadget, which
>> for DWC3 happens whenever we call gadget init.  When we switch in and
>> out of host mode, gadget init is being executed, leading to the change
>> in the USB gadget max speed parameter:
>> 
>> dwc->gadget->max_speed		= dwc->maximum_speed;
>> 
>> I know that configFS gadget has the max_speed sysfs file, which is a
>> similar mechanism, but I haven't tried to see if we can reproduce the
>> same issue with it.  Let me see if we can reproduce this with that
>> configfs speed setting.
>> 
>> Thanks
>> Wesley Cheng
>> 
>
> Hi Felipe,
>
> So I tried with doing it through the configFS max_speed, but it doesn't
> have the same effect, as the setting done in dwc3_gadget_init() will
> still be assigning the composite/UDC device's maximum speed to SSP/SS.
> This is what the usb_assign_descriptor() uses to determine whether or
> not to copy the SSP and SS descriptors.
>
> So in summary, at least for a DWC3 based subsystem, the only way to
> reproduce it is if there is a way to dynamically switch the DWC3 core
> max speed parameter.

Could it be that you have a bug in your out-of-tree changes? Perhaps
there's some assumption which your changes aren't guaranteeing.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 857 bytes --]

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

* Re: [PATCH v2] usb: gadget: Fix double free of device descriptor pointers
  2021-04-24  8:05       ` Felipe Balbi
@ 2021-04-24  8:37         ` Wesley Cheng
  2021-04-24 13:31           ` Felipe Balbi
  0 siblings, 1 reply; 7+ messages in thread
From: Wesley Cheng @ 2021-04-24  8:37 UTC (permalink / raw)
  To: Felipe Balbi, gregkh, peter.chen
  Cc: linux-usb, linux-kernel, Hemant Kumar, stable



On 4/24/2021 1:05 AM, Felipe Balbi wrote:
> 
> Hi,
> 
> Wesley Cheng <wcheng@codeaurora.org> writes:
>>>>> From: Hemant Kumar <hemantk@codeaurora.org>
>>>>>
>>>>> Upon driver unbind usb_free_all_descriptors() function frees all
>>>>> speed descriptor pointers without setting them to NULL. In case
>>>>> gadget speed changes (i.e from super speed plus to super speed)
>>>>> after driver unbind only upto super speed descriptor pointers get
>>>>> populated. Super speed plus desc still holds the stale (already
>>>>> freed) pointer. Fix this issue by setting all descriptor pointers
>>>>> to NULL after freeing them in usb_free_all_descriptors().
>>>>
>>>> could you describe this a little better? How can one trigger this case?
>>>> Is the speed demotion happening after unbinding? It's not clear how to
>>>> cause this bug.
>>>>
>>> Hi Felipe,
>>>
>>> Internally, we have a mechanism to switch the DWC3 core maximum speed
>>> parameter dynamically for displayport use cases.  This issue happens
>>> whenever we have a maximum speed change occur on the USB gadget, which
>>> for DWC3 happens whenever we call gadget init.  When we switch in and
>>> out of host mode, gadget init is being executed, leading to the change
>>> in the USB gadget max speed parameter:
>>>
>>> dwc->gadget->max_speed		= dwc->maximum_speed;
>>>
>>> I know that configFS gadget has the max_speed sysfs file, which is a
>>> similar mechanism, but I haven't tried to see if we can reproduce the
>>> same issue with it.  Let me see if we can reproduce this with that
>>> configfs speed setting.
>>>
>>> Thanks
>>> Wesley Cheng
>>>
>>
>> Hi Felipe,
>>
>> So I tried with doing it through the configFS max_speed, but it doesn't
>> have the same effect, as the setting done in dwc3_gadget_init() will
>> still be assigning the composite/UDC device's maximum speed to SSP/SS.
>> This is what the usb_assign_descriptor() uses to determine whether or
>> not to copy the SSP and SS descriptors.
>>
>> So in summary, at least for a DWC3 based subsystem, the only way to
>> reproduce it is if there is a way to dynamically switch the DWC3 core
>> max speed parameter.
> 
> Could it be that you have a bug in your out-of-tree changes? Perhaps
> there's some assumption which your changes aren't guaranteeing.
> 
Hi Felipe,

Unless there is a limitation on how the USB gadget max speed can be
used, i.e. the USB gadget max speed MUST stay the same throughout a
device's boot period, then our out of tree changes may have the wrong
assumptions.  However, I don't see that stated anywhere, and I still
feel the current usb_assign_descriptors() and usb_free_all_descriptors()
aren't aligned with one another.  One API decides which descriptors to
copy based on a parameter, whereas the other just frees all of them
irrespective.

Thanks
Wesley Cheng


-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCH v2] usb: gadget: Fix double free of device descriptor pointers
  2021-04-24  8:37         ` Wesley Cheng
@ 2021-04-24 13:31           ` Felipe Balbi
  0 siblings, 0 replies; 7+ messages in thread
From: Felipe Balbi @ 2021-04-24 13:31 UTC (permalink / raw)
  To: Wesley Cheng, gregkh, peter.chen
  Cc: linux-usb, linux-kernel, Hemant Kumar, stable

[-- Attachment #1: Type: text/plain, Size: 3102 bytes --]


Hi,

Wesley Cheng <wcheng@codeaurora.org> writes:
> On 4/24/2021 1:05 AM, Felipe Balbi wrote:
>> 
>> Hi,
>> 
>> Wesley Cheng <wcheng@codeaurora.org> writes:
>>>>>> From: Hemant Kumar <hemantk@codeaurora.org>
>>>>>>
>>>>>> Upon driver unbind usb_free_all_descriptors() function frees all
>>>>>> speed descriptor pointers without setting them to NULL. In case
>>>>>> gadget speed changes (i.e from super speed plus to super speed)
>>>>>> after driver unbind only upto super speed descriptor pointers get
>>>>>> populated. Super speed plus desc still holds the stale (already
>>>>>> freed) pointer. Fix this issue by setting all descriptor pointers
>>>>>> to NULL after freeing them in usb_free_all_descriptors().
>>>>>
>>>>> could you describe this a little better? How can one trigger this case?
>>>>> Is the speed demotion happening after unbinding? It's not clear how to
>>>>> cause this bug.
>>>>>
>>>> Hi Felipe,
>>>>
>>>> Internally, we have a mechanism to switch the DWC3 core maximum speed
>>>> parameter dynamically for displayport use cases.  This issue happens
>>>> whenever we have a maximum speed change occur on the USB gadget, which
>>>> for DWC3 happens whenever we call gadget init.  When we switch in and
>>>> out of host mode, gadget init is being executed, leading to the change
>>>> in the USB gadget max speed parameter:
>>>>
>>>> dwc->gadget->max_speed		= dwc->maximum_speed;
>>>>
>>>> I know that configFS gadget has the max_speed sysfs file, which is a
>>>> similar mechanism, but I haven't tried to see if we can reproduce the
>>>> same issue with it.  Let me see if we can reproduce this with that
>>>> configfs speed setting.
>>>>
>>>> Thanks
>>>> Wesley Cheng
>>>>
>>>
>>> Hi Felipe,
>>>
>>> So I tried with doing it through the configFS max_speed, but it doesn't
>>> have the same effect, as the setting done in dwc3_gadget_init() will
>>> still be assigning the composite/UDC device's maximum speed to SSP/SS.
>>> This is what the usb_assign_descriptor() uses to determine whether or
>>> not to copy the SSP and SS descriptors.
>>>
>>> So in summary, at least for a DWC3 based subsystem, the only way to
>>> reproduce it is if there is a way to dynamically switch the DWC3 core
>>> max speed parameter.
>> 
>> Could it be that you have a bug in your out-of-tree changes? Perhaps
>> there's some assumption which your changes aren't guaranteeing.
>> 
> Hi Felipe,
>
> Unless there is a limitation on how the USB gadget max speed can be
> used, i.e. the USB gadget max speed MUST stay the same throughout a
> device's boot period, then our out of tree changes may have the wrong

no, not throughout boot, but it can't change while the device is
enumerated.

> assumptions.  However, I don't see that stated anywhere, and I still
> feel the current usb_assign_descriptors() and usb_free_all_descriptors()
> aren't aligned with one another.  One API decides which descriptors to
> copy based on a parameter, whereas the other just frees all of them
> irrespective.

that's a valid point.

-- 
balbi

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 857 bytes --]

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

end of thread, other threads:[~2021-04-24 13:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-21 19:47 [PATCH v2] usb: gadget: Fix double free of device descriptor pointers Wesley Cheng
2021-04-22 11:01 ` Felipe Balbi
2021-04-23 19:10   ` Wesley Cheng
2021-04-24  4:16     ` Wesley Cheng
2021-04-24  8:05       ` Felipe Balbi
2021-04-24  8:37         ` Wesley Cheng
2021-04-24 13:31           ` Felipe Balbi

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).