| From 3864d33943b4a76c6e64616280e98d2410b1190f Mon Sep 17 00:00:00 2001 |
| From: Oliver Neukum <oneukum@suse.com> |
| Date: Thu, 9 May 2019 11:30:58 +0200 |
| Subject: USB: rio500: refuse more than one device at a time |
| |
| From: Oliver Neukum <oneukum@suse.com> |
| |
| commit 3864d33943b4a76c6e64616280e98d2410b1190f upstream. |
| |
| This driver is using a global variable. It cannot handle more than |
| one device at a time. The issue has been existing since the dawn |
| of the driver. |
| |
| Signed-off-by: Oliver Neukum <oneukum@suse.com> |
| Reported-by: syzbot+35f04d136fc975a70da4@syzkaller.appspotmail.com |
| Cc: stable <stable@vger.kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/misc/rio500.c | 24 ++++++++++++++++++------ |
| 1 file changed, 18 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/usb/misc/rio500.c |
| +++ b/drivers/usb/misc/rio500.c |
| @@ -447,15 +447,23 @@ static int probe_rio(struct usb_interfac |
| { |
| struct usb_device *dev = interface_to_usbdev(intf); |
| struct rio_usb_data *rio = &rio_instance; |
| - int retval; |
| + int retval = 0; |
| |
| - dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum); |
| + mutex_lock(&rio500_mutex); |
| + if (rio->present) { |
| + dev_info(&intf->dev, "Second USB Rio at address %d refused\n", dev->devnum); |
| + retval = -EBUSY; |
| + goto bail_out; |
| + } else { |
| + dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum); |
| + } |
| |
| retval = usb_register_dev(intf, &usb_rio_class); |
| if (retval) { |
| dev_err(&dev->dev, |
| "Not able to get a minor for this device.\n"); |
| - return -ENOMEM; |
| + retval = -ENOMEM; |
| + goto bail_out; |
| } |
| |
| rio->rio_dev = dev; |
| @@ -464,7 +472,8 @@ static int probe_rio(struct usb_interfac |
| dev_err(&dev->dev, |
| "probe_rio: Not enough memory for the output buffer\n"); |
| usb_deregister_dev(intf, &usb_rio_class); |
| - return -ENOMEM; |
| + retval = -ENOMEM; |
| + goto bail_out; |
| } |
| dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf); |
| |
| @@ -473,7 +482,8 @@ static int probe_rio(struct usb_interfac |
| "probe_rio: Not enough memory for the input buffer\n"); |
| usb_deregister_dev(intf, &usb_rio_class); |
| kfree(rio->obuf); |
| - return -ENOMEM; |
| + retval = -ENOMEM; |
| + goto bail_out; |
| } |
| dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf); |
| |
| @@ -481,8 +491,10 @@ static int probe_rio(struct usb_interfac |
| |
| usb_set_intfdata (intf, rio); |
| rio->present = 1; |
| +bail_out: |
| + mutex_unlock(&rio500_mutex); |
| |
| - return 0; |
| + return retval; |
| } |
| |
| static void disconnect_rio(struct usb_interface *intf) |