linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* RE: Re: Re: Re: [PATCH] usb: core: fix a double free in the usb driver
       [not found] <CGME20160603142804epcas3p43ccf34c3557e95062ef54131f50d4014@epcas3p4.samsung.com>
@ 2016-06-07  4:39 ` Chung-Geol Kim
  2016-06-07 14:54   ` Alan Stern
  0 siblings, 1 reply; 2+ messages in thread
From: Chung-Geol Kim @ 2016-06-07  4:39 UTC (permalink / raw)
  To: Alan Stern
  Cc: gregkh, mathias.nyman, stefan.koch10, hkallweit1,
	sergei.shtylyov, dan.j.williams, sarah.a.sharp, chris.bainbridge,
	linux-usb, linux-kernel

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

>On Fri, 3 Jun 2016, Chung-Geol Kim wrote:
>
>> Yes, you are right, The presentational errors in order to obtain an understanding of the process.
>> Therefore, I will be happy to explain again the diagrammatic representation as shown below.
>> If using usb 3.0 storage(OTG), you can see as below.
>> 
>> ==============================================
>>     At *Insert USB(3.0) Storage
>>     sequence <1> --> <5>
>> ==============================================
>>                                 VOLD       
>> =================================|============
>>                              (uevent)
>>                            ______|___________ 
>>                           |<5>               |
>>                           |      SCSI        |
>>                           |usb_get_hcd       |
>>                           |shared_hcd(kref=3)|
>>                           |__________________|
>>    ___________________     ________|_________ 
>>   |<2>                |   |<4>               |
>>   |dwc3_otg_sm_work   |   |dwc3_otg_sm_work  |
>>   |usb_get_hcd        |   |usb_get_hcd       |
>>   |primary_hcd(kref=2)|   |shared_hcd(kref=2)|
>>   |___________________|   |__________________|
>>    _________|_________     ________|_________ 
>>   |<1>                |   |<3>               |
>>   |New USB BUS #1     |   |New USB BUS #2    |
>>   |usb_create_hcd     |   |usb_create_hcd    |
>>   |primary_hcd(kref=1)|   |shared_hcd(kref=1)|
>>   |                   |   |                  |
>>   |bandXX_mutex(alloc)|<-(Link)-bandXX_mutex |
>>   |___________________|   |__________________|
>> 
>
>When people present diagrams like this, the universal convention is to 
>show earlier times at the top and later times at the bottom.  That way 
>the order in which you read the diagram is the same as the order in 
>which the events are supposed to occur.
>
>Also, the convention is to put events next to each other if they happen 
>at the same time.  In your diagram, <1> and <3> are next to each other 
>but they don't happen at the same time.

Thank you for your kind explanation. It has been modified as shown below.
=================================================
     At *Insert USB(3.0) Storage
     sequence <1> --> <5>
=================================================
   ___________________
  |<1>                |
  |New USB BUS #1     |
  |usb_create_hcd     |
  |primary_hcd(kref=1)|
  |                   |
  |bandXX_mutex(alloc)|<--
  |___________________|  |
   _________|_________   |
  |<2>                |  |
  |dwc3_otg_sm_work   |  |
  |usb_get_hcd        |  |
  |primary_hcd(kref=2)|  |
  |___________________|  |
                         |  __________________
                         | |<3>               |
                         | |New USB BUS #2    |
                         | |usb_create_hcd    |
                         | |shared_hcd(kref=1)|
                         | |                  |
                         --(Link)-bandXX_mutex|
                           |__________________|
                            ________|_________ 
                           |<4>               |
                           |dwc3_otg_sm_work  |
                           |usb_get_hcd       |
                           |shared_hcd(kref=2)|
                           |__________________|
                            _______|__________ 
                           |<5>               |
                           |      SCSI        |
                           |usb_get_hcd       |
                           |shared_hcd(kref=3)|
                           |__________________|
                                    |
                                (uevent)
-----------------------------------|------------
                                 VOLD
=================================================


=================================================
     At *remove USB(3.0) Storage
     sequence <1> --> <5> ((Normal Case))
=================================================
                                   VOLD
------------------------------------|------------
                                (uevent)
                              ______|___________
                             |<1>               |
                             |      SCSI        |
                             |usb_put_hcd       |
                             |shared_hcd(kref=2)|
                             |__________________|
                              ________|_________ 
                             |<2>               |
                             |dwc3_otg_sm_work  |
                             |usb_put_hcd       |
                             |shared_hcd(kref=1)|
                             |__________________|
                              ________|_________ 
                             |<3>               |
                             |New USB BUS #2    |
                             |hcd_release       |
                             |shared_hcd(kref=0)|
                             |                  |
                          -X-(cut off)-bandXX_mutex|
                           | |__________________|
                           |
      ___________________  |
     |<4>                | |
     |dwc3_otg_sm_work   | |
     |usb_put_hcd        | |
     |primary_hcd(kref=1)| |
     |___________________| |
      _________|_________  |
     |<5>                | |
     |New USB BUS #1     | |
     |hcd_release        | |
     |primary_hcd(kref=0)| |
     |                   | |
     |bandXX_mutex(free) |<-
     |___________________| 

=================================================

>
>> ==============================================
>>     At *remove USB(3.0) Storage 
>>     sequence <1> --> <5> ((Normal Case))
>> ==============================================
>>                                 VOLD       
>> =================================|============
>>                              (uevent)
>>                            ______|___________ 
>>                           |<1>               |
>>                           |      SCSI        |
>>                           |usb_put_hcd       |
>>                           |shared_hcd(kref=2)|
>>                           |__________________|
>>    ___________________     ________|_________ 
>>   |<4>                |   |<2>               |
>>   |dwc3_otg_sm_work   |   |dwc3_otg_sm_work  |
>>   |usb_put_hcd        |   |usb_put_hcd       |
>>   |primary_hcd(kref=1)|   |shared_hcd(kref=1)|
>>   |___________________|   |__________________|
>>    _________|_________     ________|_________ 
>>   |<5>                |   |<3>               |
>>   |New USB BUS #1     |   |New USB BUS #2    |
>>   |hcd_release        |   |hcd_release       |
>>   |primary_hcd(kref=0)|   |shared_hcd(kref=0)|
>>   |                   |   |                  |
>>   |bandXX_mutex(free) | -X-cut off)-bandXX_mutex|
>>   |___________________|   |__________________|
>> 
>> ----------------------------------------------
>
>> >The real bug here is that the shared_hcd is released after the 
>> >primary_hcd.  That's what you need to fix.
>> 
>> NO, It 's only depend on vold(scsi) release time.
>> If the vold later released and is being released first hcd,
>> Double free happened at <5> as below.
>> 
>> ==============================================
>>     At *remove USB(3.0) Storage 
>>     sequence <1> --> <5> ((Problem Case))
>> ==============================================
>>                                 VOLD       
>> =================================|============
>>                              (uevent)
>>                            ______|___________ 
>>                           |<5>               |
>>                           |      SCSI        |
>>                           |usb_put_hcd       |
>>                           |shared_hcd(kref=0)|
>>                           |*hcd_release      |
>>                           |bandXX_mutex(free*)|<- double free
>>                           |__________________|
>>    ___________________     ________|_________ 
>>   |<3>                |   |<1>               |
>>   |dwc3_otg_sm_work   |   |dwc3_otg_sm_work  |
>>   |usb_put_hcd        |   |usb_put_hcd       |
>>   |primary_hcd(kref=1)|   |shared_hcd(kref=2)|
>>   |___________________|   |__________________|
>>    _________|_________     ________|_________ 
>>   |<4>                |   |<2>               |
>>   |New USB BUS #1     |   |New USB BUS #2    |
>>   |hcd_release        |   |                  |
>>   |primary_hcd(kref=0)|   |shared_hcd(kref=1)|
>>   |                   |   |                  |
>>   |bandXX_mutex(free) |<-(Link)-bandXX_mutex |
>>   |___________________|   |__________________|
>> 
>> ----------------------------------------------
>
>That's the same as what I said.  In your diagram, vold releases the 
>shared_hcd (in <5>) after dwc3_otg_sm_work releases the primary_hcd 
>(in <4>).
>


=================================================
     At *remove USB(3.0) Storage 
     sequence <1> --> <5> ((Problem Case))
=================================================
                                  VOLD
------------------------------------|------------
                                 (uevent)
                            ________|_________
                           |<1>               |
                           |dwc3_otg_sm_work  |
                           |usb_put_hcd       |
                           |shared_hcd(kref=2)|
                           |__________________|
                            ________|_________ 
                           |<2>               |
                           |New USB BUS #2    |
                           |                  |
                           |shared_hcd(kref=1)|
                           |                  |
                         --(Link)-bandXX_mutex|
                         | |__________________|
                         | 
    ___________________  |
   |<3>                | |
   |dwc3_otg_sm_work   | |
   |usb_put_hcd        | |
   |primary_hcd(kref=1)| |
   |___________________| |
    _________|_________  |
   |<4>                | |
   |New USB BUS #1     | |
   |hcd_release        | |
   |primary_hcd(kref=0)| |
   |                   | |
   |bandXX_mutex(free) |<-
   |___________________| 
                               (( VOLD ))
                            ______|___________
                           |<5>               |
                           |      SCSI        |
                           |usb_put_hcd       |
                           |shared_hcd(kref=0)|
                           |*hcd_release      |
                           |bandXX_mutex(free*)|<- double free
                           |__________________|

=================================================

>If you change the code so that the shared_hcd takes a reference to the 
>primary_hcd and drops that reference when the shared_hcd is released, 
>this will never occur.
>
>Alan Stern

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

* RE: Re: Re: Re: [PATCH] usb: core: fix a double free in the usb driver
  2016-06-07  4:39 ` Re: Re: Re: [PATCH] usb: core: fix a double free in the usb driver Chung-Geol Kim
@ 2016-06-07 14:54   ` Alan Stern
  0 siblings, 0 replies; 2+ messages in thread
From: Alan Stern @ 2016-06-07 14:54 UTC (permalink / raw)
  To: Chung-Geol Kim
  Cc: gregkh, mathias.nyman, stefan.koch10, hkallweit1,
	sergei.shtylyov, dan.j.williams, chris.bainbridge, linux-usb,
	linux-kernel

On Tue, 7 Jun 2016, Chung-Geol Kim wrote:

> =================================================
>      At *remove USB(3.0) Storage 
>      sequence <1> --> <5> ((Problem Case))
> =================================================
>                                   VOLD
> ------------------------------------|------------
>                                  (uevent)
>                             ________|_________
>                            |<1>               |
>                            |dwc3_otg_sm_work  |
>                            |usb_put_hcd       |
>                            |shared_hcd(kref=2)|
>                            |__________________|
>                             ________|_________ 
>                            |<2>               |
>                            |New USB BUS #2    |
>                            |                  |
>                            |shared_hcd(kref=1)|
>                            |                  |
>                          --(Link)-bandXX_mutex|
>                          | |__________________|
>                          | 
>     ___________________  |
>    |<3>                | |
>    |dwc3_otg_sm_work   | |
>    |usb_put_hcd        | |
>    |primary_hcd(kref=1)| |
>    |___________________| |
>     _________|_________  |
>    |<4>                | |
>    |New USB BUS #1     | |
>    |hcd_release        | |
>    |primary_hcd(kref=0)| |
>    |                   | |
>    |bandXX_mutex(free) |<-
>    |___________________| 
>                                (( VOLD ))
>                             ______|___________
>                            |<5>               |
>                            |      SCSI        |
>                            |usb_put_hcd       |
>                            |shared_hcd(kref=0)|
>                            |*hcd_release      |
>                            |bandXX_mutex(free*)|<- double free
>                            |__________________|
> 
> =================================================

Okay, now I understand the problem you want to solve.  What we need to
do is make sure the mutex is deallocated when the _last_ hcd is
released, which is not necessarily the same as when the _primary_ hcd
is released.

Can you please test the patch below?

By the way, a good change (if you want to do it) would be to rename the
"shared_hcd" field to "other_hcd" or "peer_hcd".  This is because it
always points to the other hcd in the peer set: In the primary
structure it points to the secondary, and in the secondary structure it
points to the primary.

Alan Stern



Index: usb-4.x/drivers/usb/core/hcd.c
===================================================================
--- usb-4.x.orig/drivers/usb/core/hcd.c
+++ usb-4.x/drivers/usb/core/hcd.c
@@ -2588,24 +2588,22 @@ EXPORT_SYMBOL_GPL(usb_create_hcd);
  * Don't deallocate the bandwidth_mutex until the last shared usb_hcd is
  * deallocated.
  *
- * Make sure to only deallocate the bandwidth_mutex when the primary HCD is
- * freed.  When hcd_release() is called for either hcd in a peer set
- * invalidate the peer's ->shared_hcd and ->primary_hcd pointers to
- * block new peering attempts
+ * Make sure to deallocate the bandwidth_mutex only when the last HCD is
+ * freed.  When hcd_release() is called for either hcd in a peer set,
+ * invalidate the peer's ->shared_hcd and ->primary_hcd pointers.
  */
 static void hcd_release(struct kref *kref)
 {
 	struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref);
 
 	mutex_lock(&usb_port_peer_mutex);
-	if (usb_hcd_is_primary_hcd(hcd))
-		kfree(hcd->bandwidth_mutex);
 	if (hcd->shared_hcd) {
 		struct usb_hcd *peer = hcd->shared_hcd;
 
 		peer->shared_hcd = NULL;
-		if (peer->primary_hcd == hcd)
-			peer->primary_hcd = NULL;
+		peer->primary_hcd = NULL;
+	} else {
+		kfree(hcd->bandwidth_mutex);
 	}
 	mutex_unlock(&usb_port_peer_mutex);
 	kfree(hcd);

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

end of thread, other threads:[~2016-06-07 14:54 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CGME20160603142804epcas3p43ccf34c3557e95062ef54131f50d4014@epcas3p4.samsung.com>
2016-06-07  4:39 ` Re: Re: Re: [PATCH] usb: core: fix a double free in the usb driver Chung-Geol Kim
2016-06-07 14:54   ` Alan Stern

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