]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.32.3/usb-fix-bugs-in-usb_-de-authorize_device.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.32.3 / usb-fix-bugs-in-usb_-de-authorize_device.patch
CommitLineData
80e6ae8f
GKH
1From da307123c621b01cce147a4be313d8a754674f63 Mon Sep 17 00:00:00 2001
2From: Alan Stern <stern@rowland.harvard.edu>
3Date: Tue, 8 Dec 2009 15:54:44 -0500
4Subject: USB: fix bugs in usb_(de)authorize_device
5
6From: Alan Stern <stern@rowland.harvard.edu>
7
8commit da307123c621b01cce147a4be313d8a754674f63 upstream.
9
10This patch (as1315) fixes some bugs in the USB core authorization
11code:
12
13 usb_deauthorize_device() should deallocate the device strings
14 instead of leaking them, and it should invoke
15 usb_destroy_configuration() (which does proper reference
16 counting) instead of freeing the config information directly.
17
18 usb_authorize_device() shouldn't change the device strings
19 until it knows that the authorization will succeed, and it should
20 autosuspend the device at the end (having autoresumed the
21 device at the start).
22
23 Because the device strings can be changed, the sysfs routines
24 to display the strings must protect the string pointers by
25 locking the device.
26
27Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
28CC: Inaky Perez-Gonzalez <inaky@linux.intel.com>
29Acked-by: David Vrabel <david.vrabel@csr.com>
30Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
31
32---
33 drivers/usb/core/hub.c | 32 ++++++++++++++++++++------------
34 drivers/usb/core/sysfs.c | 6 +++++-
35 2 files changed, 25 insertions(+), 13 deletions(-)
36
37--- a/drivers/usb/core/hub.c
38+++ b/drivers/usb/core/hub.c
39@@ -1803,21 +1803,23 @@ fail:
40 */
41 int usb_deauthorize_device(struct usb_device *usb_dev)
42 {
43- unsigned cnt;
44 usb_lock_device(usb_dev);
45 if (usb_dev->authorized == 0)
46 goto out_unauthorized;
47+
48 usb_dev->authorized = 0;
49 usb_set_configuration(usb_dev, -1);
50+
51+ kfree(usb_dev->product);
52 usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL);
53+ kfree(usb_dev->manufacturer);
54 usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL);
55+ kfree(usb_dev->serial);
56 usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL);
57- kfree(usb_dev->config);
58- usb_dev->config = NULL;
59- for (cnt = 0; cnt < usb_dev->descriptor.bNumConfigurations; cnt++)
60- kfree(usb_dev->rawdescriptors[cnt]);
61+
62+ usb_destroy_configuration(usb_dev);
63 usb_dev->descriptor.bNumConfigurations = 0;
64- kfree(usb_dev->rawdescriptors);
65+
66 out_unauthorized:
67 usb_unlock_device(usb_dev);
68 return 0;
69@@ -1827,15 +1829,11 @@ out_unauthorized:
70 int usb_authorize_device(struct usb_device *usb_dev)
71 {
72 int result = 0, c;
73+
74 usb_lock_device(usb_dev);
75 if (usb_dev->authorized == 1)
76 goto out_authorized;
77- kfree(usb_dev->product);
78- usb_dev->product = NULL;
79- kfree(usb_dev->manufacturer);
80- usb_dev->manufacturer = NULL;
81- kfree(usb_dev->serial);
82- usb_dev->serial = NULL;
83+
84 result = usb_autoresume_device(usb_dev);
85 if (result < 0) {
86 dev_err(&usb_dev->dev,
87@@ -1848,6 +1846,14 @@ int usb_authorize_device(struct usb_devi
88 "authorization: %d\n", result);
89 goto error_device_descriptor;
90 }
91+
92+ kfree(usb_dev->product);
93+ usb_dev->product = NULL;
94+ kfree(usb_dev->manufacturer);
95+ usb_dev->manufacturer = NULL;
96+ kfree(usb_dev->serial);
97+ usb_dev->serial = NULL;
98+
99 usb_dev->authorized = 1;
100 result = usb_enumerate_device(usb_dev);
101 if (result < 0)
102@@ -1866,8 +1872,10 @@ int usb_authorize_device(struct usb_devi
103 }
104 }
105 dev_info(&usb_dev->dev, "authorized to connect\n");
106+
107 error_enumerate:
108 error_device_descriptor:
109+ usb_autosuspend_device(usb_dev);
110 error_autoresume:
111 out_authorized:
112 usb_unlock_device(usb_dev); // complements locktree
113--- a/drivers/usb/core/sysfs.c
114+++ b/drivers/usb/core/sysfs.c
115@@ -82,9 +82,13 @@ static ssize_t show_##name(struct devic
116 struct device_attribute *attr, char *buf) \
117 { \
118 struct usb_device *udev; \
119+ int retval; \
120 \
121 udev = to_usb_device(dev); \
122- return sprintf(buf, "%s\n", udev->name); \
123+ usb_lock_device(udev); \
124+ retval = sprintf(buf, "%s\n", udev->name); \
125+ usb_unlock_device(udev); \
126+ return retval; \
127 } \
128 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
129