Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5d1ceac authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman
Browse files

USB: open disconnect race in usblcd



this driver has a possible use after free due to a race when disconnect
and open handle intfdata without a lock.

Signed-off-by: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 78663ecc
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <linux/usb.h>

@@ -34,6 +35,8 @@ static struct usb_device_id id_table [] = {
};
MODULE_DEVICE_TABLE (usb, id_table);

static DEFINE_MUTEX(open_disc_mutex);


struct usb_lcd {
	struct usb_device *	udev;			/* init: probe_lcd */
@@ -79,12 +82,16 @@ static int lcd_open(struct inode *inode, struct file *file)
		return -ENODEV;
	}

	mutex_lock(&open_disc_mutex);
	dev = usb_get_intfdata(interface);
	if (!dev)
	if (!dev) {
		mutex_unlock(&open_disc_mutex);
		return -ENODEV;
	}

	/* increment our usage count for the device */
	kref_get(&dev->kref);
	mutex_unlock(&open_disc_mutex);

	/* grab a power reference */
	r = usb_autopm_get_interface(interface);
@@ -393,8 +400,10 @@ static void lcd_disconnect(struct usb_interface *interface)
	struct usb_lcd *dev;
        int minor = interface->minor;

	mutex_lock(&open_disc_mutex);
        dev = usb_get_intfdata(interface);
        usb_set_intfdata(interface, NULL);
	mutex_unlock(&open_disc_mutex);

        /* give back our minor */
        usb_deregister_dev(interface, &lcd_class);