[PATCH 2/2] USB: fix bugs in usb_(de)authorize_device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch (as1315) fixes some bugs in the USB core authorization
code:

	usb_deauthorize_device() should deallocate the device strings
	instead of leaking them, and it should invoke
	usb_destroy_configuration() (which does proper reference
	counting) instead of freeing the config information directly.

	usb_authorize_device() shouldn't change the device strings
	until it knows that the authorization will succeed, and it should
	autosuspend the device at the end (having autoresumed the
	device at the start).

	Because the device strings can be changed, the sysfs routines
	to display the strings must protect the string pointers by
	locking the device.

Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
CC: Inaky Perez-Gonzalez <inaky@xxxxxxxxxxxxxxx>
CC: David Vrabel <david.vrabel@xxxxxxx>

---

Greg:

This patch has a small dependency on the 1/2 patch ("USB: rename 
usb_configure_device").  Since it is a bug fix, you might want to 
consider it for the stable trees.  If you do, either the dependency has 
to be fixed or else both patches have to go to -stable.

Alan Stern


Index: usb-2.6/drivers/usb/core/hub.c
===================================================================
--- usb-2.6.orig/drivers/usb/core/hub.c
+++ usb-2.6/drivers/usb/core/hub.c
@@ -1849,21 +1849,23 @@ fail:
  */
 int usb_deauthorize_device(struct usb_device *usb_dev)
 {
-	unsigned cnt;
 	usb_lock_device(usb_dev);
 	if (usb_dev->authorized == 0)
 		goto out_unauthorized;
+
 	usb_dev->authorized = 0;
 	usb_set_configuration(usb_dev, -1);
+
+	kfree(usb_dev->product);
 	usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
+	kfree(usb_dev->manufacturer);
 	usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
+	kfree(usb_dev->serial);
 	usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
-	kfree(usb_dev->config);
-	usb_dev->config = NULL;
-	for (cnt = 0; cnt < usb_dev->descriptor.bNumConfigurations; cnt++)
-		kfree(usb_dev->rawdescriptors[cnt]);
+
+	usb_destroy_configuration(usb_dev);
 	usb_dev->descriptor.bNumConfigurations = 0;
-	kfree(usb_dev->rawdescriptors);
+
 out_unauthorized:
 	usb_unlock_device(usb_dev);
 	return 0;
@@ -1873,15 +1875,11 @@ out_unauthorized:
 int usb_authorize_device(struct usb_device *usb_dev)
 {
 	int result = 0, c;
+
 	usb_lock_device(usb_dev);
 	if (usb_dev->authorized == 1)
 		goto out_authorized;
-	kfree(usb_dev->product);
-	usb_dev->product = NULL;
-	kfree(usb_dev->manufacturer);
-	usb_dev->manufacturer = NULL;
-	kfree(usb_dev->serial);
-	usb_dev->serial = NULL;
+
 	result = usb_autoresume_device(usb_dev);
 	if (result < 0) {
 		dev_err(&usb_dev->dev,
@@ -1894,6 +1892,14 @@ int usb_authorize_device(struct usb_devi
 			"authorization: %d\n", result);
 		goto error_device_descriptor;
 	}
+
+	kfree(usb_dev->product);
+	usb_dev->product = NULL;
+	kfree(usb_dev->manufacturer);
+	usb_dev->manufacturer = NULL;
+	kfree(usb_dev->serial);
+	usb_dev->serial = NULL;
+
 	usb_dev->authorized = 1;
 	result = usb_enumerate_device(usb_dev);
 	if (result < 0)
@@ -1912,8 +1918,10 @@ int usb_authorize_device(struct usb_devi
 		}
 	}
 	dev_info(&usb_dev->dev, "authorized to connect\n");
+
 error_enumerate:
 error_device_descriptor:
+	usb_autosuspend_device(usb_dev);
 error_autoresume:
 out_authorized:
 	usb_unlock_device(usb_dev);	// complements locktree
Index: usb-2.6/drivers/usb/core/sysfs.c
===================================================================
--- usb-2.6.orig/drivers/usb/core/sysfs.c
+++ usb-2.6/drivers/usb/core/sysfs.c
@@ -82,9 +82,13 @@ static ssize_t  show_##name(struct devic
 		struct device_attribute *attr, char *buf)		\
 {									\
 	struct usb_device *udev;					\
+	int retval;							\
 									\
 	udev = to_usb_device(dev);					\
-	return sprintf(buf, "%s\n", udev->name);			\
+	usb_lock_device(udev);						\
+	retval = sprintf(buf, "%s\n", udev->name);			\
+	usb_unlock_device(udev);					\
+	return retval;							\
 }									\
 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
 

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux