usb: iowarrior: fix deadlock on disconnect
authorOliver Neukum <oneukum@suse.com>
Thu, 8 Aug 2019 09:27:28 +0000 (11:27 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 8 Aug 2019 10:43:18 +0000 (12:43 +0200)
We have to drop the mutex before we close() upon disconnect()
as close() needs the lock. This is safe to do by dropping the
mutex as intfdata is already set to NULL, so open() will fail.

Fixes: 03f36e885fc26 ("USB: open disconnect race in iowarrior")
Reported-by: syzbot+a64a382964bf6c71a9c0@syzkaller.appspotmail.com
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Oliver Neukum <oneukum@suse.com>
Link: https://lore.kernel.org/r/20190808092728.23417-1-oneukum@suse.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/misc/iowarrior.c

index ba05dd80a020fb553752ff2b80e04a20b862c26f..f5bed9f29e5621521b4ea754ed76a5442744492d 100644 (file)
@@ -866,19 +866,20 @@ static void iowarrior_disconnect(struct usb_interface *interface)
        dev = usb_get_intfdata(interface);
        mutex_lock(&iowarrior_open_disc_lock);
        usb_set_intfdata(interface, NULL);
+       /* prevent device read, write and ioctl */
+       dev->present = 0;
 
        minor = dev->minor;
+       mutex_unlock(&iowarrior_open_disc_lock);
+       /* give back our minor - this will call close() locks need to be dropped at this point*/
 
-       /* give back our minor */
        usb_deregister_dev(interface, &iowarrior_class);
 
        mutex_lock(&dev->mutex);
 
        /* prevent device read, write and ioctl */
-       dev->present = 0;
 
        mutex_unlock(&dev->mutex);
-       mutex_unlock(&iowarrior_open_disc_lock);
 
        if (dev->opened) {
                /* There is a process that holds a filedescriptor to the device ,