aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-07-22 14:41:18 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:30 -0400
commit25118084ef03f4fc314ab33ef6a9d9271d0e616a (patch)
treeeb5be3e297ff1c3b12b555fb80d391f9706702f1
parent81e5b23cd206d46d4872d25f3d7ff67a0f355c71 (diff)
USB: check for hub driver not bound to root hub device
This patch (as1267) changes usb_kick_khubd() and hdev_to_hub() to make them more resilient against situations where a hub device isn't bound to the hub driver. The code assumes that if a root hub was successfully registered then it must be bound to the hub driver. But this assumption can fail if the user manually unbinds the hub driver, or more importantly, if the host controller dies causing usb_set_configuration to fail. To protect against these possibilities, make hdev_to_hub() check that the hub device is configured before dereferencing the active configuration, and make usb_kick_khubd() check that the pointer to the hub's private data structure isn't NULL. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/core/hub.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 69e3a966a4b7..645686a14214 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -163,8 +163,10 @@ static inline char *portspeed(int portstatus)
163} 163}
164 164
165/* Note that hdev or one of its children must be locked! */ 165/* Note that hdev or one of its children must be locked! */
166static inline struct usb_hub *hdev_to_hub(struct usb_device *hdev) 166static struct usb_hub *hdev_to_hub(struct usb_device *hdev)
167{ 167{
168 if (!hdev || !hdev->actconfig)
169 return NULL;
168 return usb_get_intfdata(hdev->actconfig->interface[0]); 170 return usb_get_intfdata(hdev->actconfig->interface[0]);
169} 171}
170 172
@@ -385,8 +387,10 @@ static void kick_khubd(struct usb_hub *hub)
385 387
386void usb_kick_khubd(struct usb_device *hdev) 388void usb_kick_khubd(struct usb_device *hdev)
387{ 389{
388 /* FIXME: What if hdev isn't bound to the hub driver? */ 390 struct usb_hub *hub = hdev_to_hub(hdev);
389 kick_khubd(hdev_to_hub(hdev)); 391
392 if (hub)
393 kick_khubd(hub);
390} 394}
391 395
392 396