diff options
author | Oliver Neukum <oneukum@suse.de> | 2007-02-08 09:42:53 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-02-16 18:32:19 -0500 |
commit | 5b06470816fb5e658e81db2a55b530ff2ba711c9 (patch) | |
tree | f43ea87c2808916a5f9f27238d82fd4481383cf2 /drivers/usb | |
parent | 57e4f041bfffa191a318dab44eb991d79a6a9d5c (diff) |
USB: fix autosuspend race in skeleton driver
as the skeleton driver was made ready for autosuspend a race condition
was introduced. The reference to get device must be gotten before the
autosuspend counter is upped, as this operation may sleep, dropping BKL.
Dropping BKL means that the pointer to the device may become invalid.
Here's the fix.
Signed-off-by: Oliver Neukum <oneukum@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/usb-skeleton.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 296b091cf168..46929a1b6f24 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c | |||
@@ -90,13 +90,15 @@ static int skel_open(struct inode *inode, struct file *file) | |||
90 | goto exit; | 90 | goto exit; |
91 | } | 91 | } |
92 | 92 | ||
93 | /* increment our usage count for the device */ | ||
94 | kref_get(&dev->kref); | ||
95 | |||
93 | /* prevent the device from being autosuspended */ | 96 | /* prevent the device from being autosuspended */ |
94 | retval = usb_autopm_get_interface(interface); | 97 | retval = usb_autopm_get_interface(interface); |
95 | if (retval) | 98 | if (retval) { |
99 | kref_put(&dev->kref, skel_delete); | ||
96 | goto exit; | 100 | goto exit; |
97 | 101 | } | |
98 | /* increment our usage count for the device */ | ||
99 | kref_get(&dev->kref); | ||
100 | 102 | ||
101 | /* save our object in the file's private structure */ | 103 | /* save our object in the file's private structure */ |
102 | file->private_data = dev; | 104 | file->private_data = dev; |