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

Reply via email to