Hi,
This is another try to fix the crashes that occur when a USB scanner
is disconnected while open and write/read/ioctl is called after the
disconnect. This time I've kept all the cleanup bur kfree(scn) in
disconnect_scanner() and only the kfree(scn) is done in close_scanner,
if the device was disconnected in the meantime.
That one (close_scanner()) looks a bit funny:
if (scn->present) {
up(&(scn->sem));
} else {
up(&(scn->sem));
kfree (scn);
}
But if I up the semaphore before the test for scn->present, I guess
that would be a race with disconnect_scanner.
Bye,
Henning
[PATCH 2.5.54] scanner.c: Avoid crashes when using read/write/ioctl on disconnected
device
Avoid crashing when read/write/ioctl is called after disconnecting the
device. Keep scn until the device is closed and check scn->present in
read/write/ioctl.
--- linux-2.5.54-interface2/drivers/usb/image/scanner.c 2003-01-08 18:33:55.000000000
+0100
+++ linux-2.5.54-present/drivers/usb/image/scanner.c 2003-01-08 22:46:33.000000000
++0100
@@ -338,6 +338,9 @@
* - Removed PV8630 ioctls. Use the standard ioctls instead.
* - Made endpoint detection more generic. Basically, only one bulk-in
* endpoint is required, everything else is optional.
+ * - Avoid crashing when read/write/ioctl is called after disconnecting the
+ * device. Keep scn until the device is closed and check scn->present in
+ * read/write/ioctl.
*
* TODO
* - Performance
@@ -499,7 +502,12 @@
file->private_data = NULL;
up(&scn_mutex);
- up(&(scn->sem));
+ if (scn->present) {
+ up(&(scn->sem));
+ } else {
+ up(&(scn->sem));
+ kfree (scn);
+ }
return 0;
}
@@ -526,6 +534,12 @@
down(&(scn->sem));
+ if (!scn->present) {
+ /* Disconnected */
+ up(&(scn->sem));
+ return -EINVAL;
+ }
+
if (!scn->bulk_out_ep) {
/* This scanner does not have a bulk-out endpoint */
up(&(scn->sem));
@@ -619,6 +633,12 @@
down(&(scn->sem));
+ if (!scn->present) {
+ /* Disconnected */
+ up(&(scn->sem));
+ return -EINVAL;
+ }
+
scn_minor = scn->scn_minor;
ibuf = scn->ibuf;
@@ -727,6 +747,12 @@
scn_minor = USB_SCN_MINOR(inode);
down(&(scn->sem));
+ if (!scn->present) {
+ /* Disconnected */
+ up(&(scn->sem));
+ return -EINVAL;
+ }
+
dev = scn->scn_dev;
switch (cmd)
@@ -1084,8 +1110,13 @@
devfs_unregister(scn->devfs);
usb_deregister_dev(1, scn->scn_minor);
usb_free_urb(scn->scn_irq);
- up (&(scn->sem));
- kfree (scn);
+ if (scn->isopen) {
+ scn->present = 0;
+ up (&(scn->sem));
+ } else {
+ up (&(scn->sem));
+ kfree (scn);
+ }
up (&scn_mutex);
}
}
-------------------------------------------------------
This SF.NET email is sponsored by:
SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See!
http://www.vasoftware.com
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel