Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755028Ab0AEAwb (ORCPT ); Mon, 4 Jan 2010 19:52:31 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1754982Ab0AEAw0 (ORCPT ); Mon, 4 Jan 2010 19:52:26 -0500 Received: from kroah.org ([198.145.64.141]:34154 "EHLO coco.kroah.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754260Ab0AEAe7 (ORCPT ); Mon, 4 Jan 2010 19:34:59 -0500 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, stable@kernel.org, stable-review@kernel.org Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk, Alan Stern , Inaky Perez-Gonzalez , Greg Kroah-Hartman Subject: [PATCH 26/97] USB: fix bugs in usb_(de)authorize_device Date: Mon, 4 Jan 2010 16:32:39 -0800 Message-Id: <1262651630-7354-26-git-send-email-gregkh@suse.de> X-Mailer: git-send-email 1.6.6 In-Reply-To: <20100105003133.GA7199@kroah.com> References: <20100105003133.GA7199@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4258 Lines: 135 From: Alan Stern commit da307123c621b01cce147a4be313d8a754674f63 upstream. 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 CC: Inaky Perez-Gonzalez Acked-by: David Vrabel Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 32 ++++++++++++++++++++------------ drivers/usb/core/sysfs.c | 6 +++++- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 276fc68..8b0c235 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1803,21 +1803,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; @@ -1827,15 +1829,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, @@ -1848,6 +1846,14 @@ int usb_authorize_device(struct usb_device *usb_dev) "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) @@ -1866,8 +1872,10 @@ int usb_authorize_device(struct usb_device *usb_dev) } } 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 diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 7ec3041..8752e55 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -82,9 +82,13 @@ static ssize_t show_##name(struct device *dev, \ 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); -- 1.6.6 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/