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