Commit ab2a4bf
USB: don't free bandwidth_mutex too early
The USB core contains a bug that can show up when a USB-3 host
controller is removed. If the primary (USB-2) hcd structure is
released before the shared (USB-3) hcd, the core will try to do a
double-free of the common bandwidth_mutex.
The problem was described in graphical form by Chung-Geol Kim, who
first reported it:
=================================================
At *remove USB(3.0) Storage
sequence <1> --> <5> ((Problem Case))
=================================================
VOLD
------------------------------------|------------
(uevent)
________|_________
|<1> |
|dwc3_otg_sm_work |
|usb_put_hcd |
|peer_hcd(kref=2)|
|__________________|
________|_________
|<2> |
|New USB BUS #2 |
| |
|peer_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 |
|peer_hcd(kref=0) |
|*hcd_release |
|bandXX_mutex(free*)|<- double free
|__________________|
=================================================
This happens because hcd_release() frees the bandwidth_mutex whenever
it sees a primary hcd being released (which is not a very good idea
in any case), but in the course of releasing the primary hcd, it
changes the pointers in the shared hcd in such a way that the shared
hcd will appear to be primary when it gets released.
This patch fixes the problem by changing hcd_release() so that it
deallocates the bandwidth_mutex only when the _last_ hcd structure
referencing it is released. The patch also removes an unnecessary
test, so that when an hcd is released, both the shared_hcd and
primary_hcd pointers in the hcd's peer will be cleared.
Signed-off-by: Alan Stern <[email protected]>
Reported-by: Chung-Geol Kim <[email protected]>
Tested-by: Chung-Geol Kim <[email protected]>
CC: <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>1 parent 7e8b3df commit ab2a4bf
1 file changed
+7
-10
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2598 | 2598 | | |
2599 | 2599 | | |
2600 | 2600 | | |
2601 | | - | |
2602 | | - | |
2603 | | - | |
2604 | | - | |
| 2601 | + | |
| 2602 | + | |
| 2603 | + | |
2605 | 2604 | | |
2606 | 2605 | | |
2607 | 2606 | | |
2608 | 2607 | | |
2609 | 2608 | | |
2610 | 2609 | | |
2611 | | - | |
2612 | | - | |
2613 | | - | |
2614 | | - | |
2615 | 2610 | | |
2616 | 2611 | | |
2617 | 2612 | | |
2618 | 2613 | | |
2619 | | - | |
2620 | | - | |
| 2614 | + | |
| 2615 | + | |
| 2616 | + | |
| 2617 | + | |
2621 | 2618 | | |
2622 | 2619 | | |
2623 | 2620 | | |
| |||
0 commit comments