summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2019-08-08 13:34:08 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-09-03 14:18:18 -0400
commit9472aff16ca0fd9351eea7773facef364743088f (patch)
treefdf809e45c9cf817ddc1e4b97c1467449e47379a
parent95e29e9bbe28e636d2f089a2fa1cba9d0a436fe3 (diff)
USB: rio500: Fix lockdep violation
The syzbot fuzzer found a lockdep violation in the rio500 driver: ====================================================== WARNING: possible circular locking dependency detected 5.3.0-rc2+ #23 Not tainted ------------------------------------------------------ syz-executor.2/20386 is trying to acquire lock: 00000000772249c6 (rio500_mutex){+.+.}, at: open_rio+0x16/0xc0 drivers/usb/misc/rio500.c:64 but task is already holding lock: 00000000d3e8f4b9 (minor_rwsem){++++}, at: usb_open+0x23/0x270 drivers/usb/core/file.c:39 which lock already depends on the new lock. The problem is that the driver's open_rio() routine is called while the usbcore's minor_rwsem is locked for reading, and it acquires the rio500_mutex; whereas conversely, probe_rio() and disconnect_rio() first acquire the rio500_mutex and then call usb_register_dev() or usb_deregister_dev(), which lock minor_rwsem for writing. The correct ordering of acquisition should be: minor_rwsem first, then rio500_mutex (since the locking in open_rio() cannot be changed). Thus, the probe and disconnect routines should avoid holding rio500_mutex while doing their registration and deregistration. This patch adjusts the code in those two routines to do just that. It also relies on the fact that the probe and disconnect routines are protected by the device mutex, so the initial test of rio->present needs no extra locking. Reported-by: syzbot+7bbcbe9c9ff0cd49592a@syzkaller.appspotmail.com Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Fixes: d710734b0677 ("USB: rio500: simplify locking") Acked-by: Oliver Neukum <oneukum@suse.com> CC: <stable@vger.kernel.org> Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.1908081329240.1319-100000@iolanthe.rowland.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/usb/misc/rio500.c66
1 files changed, 35 insertions, 31 deletions
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
index 27e9c78a791e..30cae5e1954d 100644
--- a/drivers/usb/misc/rio500.c
+++ b/drivers/usb/misc/rio500.c
@@ -454,51 +454,55 @@ static int probe_rio(struct usb_interface *intf,
454{ 454{
455 struct usb_device *dev = interface_to_usbdev(intf); 455 struct usb_device *dev = interface_to_usbdev(intf);
456 struct rio_usb_data *rio = &rio_instance; 456 struct rio_usb_data *rio = &rio_instance;
457 int retval = 0; 457 int retval = -ENOMEM;
458 char *ibuf, *obuf;
458 459
459 mutex_lock(&rio500_mutex);
460 if (rio->present) { 460 if (rio->present) {
461 dev_info(&intf->dev, "Second USB Rio at address %d refused\n", dev->devnum); 461 dev_info(&intf->dev, "Second USB Rio at address %d refused\n", dev->devnum);
462 retval = -EBUSY; 462 return -EBUSY;
463 goto bail_out;
464 } else {
465 dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
466 }
467
468 retval = usb_register_dev(intf, &usb_rio_class);
469 if (retval) {
470 dev_err(&dev->dev,
471 "Not able to get a minor for this device.\n");
472 retval = -ENOMEM;
473 goto bail_out;
474 } 463 }
464 dev_info(&intf->dev, "USB Rio found at address %d\n", dev->devnum);
475 465
476 rio->rio_dev = dev; 466 obuf = kmalloc(OBUF_SIZE, GFP_KERNEL);
477 467 if (!obuf) {
478 if (!(rio->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) {
479 dev_err(&dev->dev, 468 dev_err(&dev->dev,
480 "probe_rio: Not enough memory for the output buffer\n"); 469 "probe_rio: Not enough memory for the output buffer\n");
481 usb_deregister_dev(intf, &usb_rio_class); 470 goto err_obuf;
482 retval = -ENOMEM;
483 goto bail_out;
484 } 471 }
485 dev_dbg(&intf->dev, "obuf address:%p\n", rio->obuf); 472 dev_dbg(&intf->dev, "obuf address: %p\n", obuf);
486 473
487 if (!(rio->ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL))) { 474 ibuf = kmalloc(IBUF_SIZE, GFP_KERNEL);
475 if (!ibuf) {
488 dev_err(&dev->dev, 476 dev_err(&dev->dev,
489 "probe_rio: Not enough memory for the input buffer\n"); 477 "probe_rio: Not enough memory for the input buffer\n");
490 usb_deregister_dev(intf, &usb_rio_class); 478 goto err_ibuf;
491 kfree(rio->obuf);
492 retval = -ENOMEM;
493 goto bail_out;
494 } 479 }
495 dev_dbg(&intf->dev, "ibuf address:%p\n", rio->ibuf); 480 dev_dbg(&intf->dev, "ibuf address: %p\n", ibuf);
496 481
497 usb_set_intfdata (intf, rio); 482 mutex_lock(&rio500_mutex);
483 rio->rio_dev = dev;
484 rio->ibuf = ibuf;
485 rio->obuf = obuf;
498 rio->present = 1; 486 rio->present = 1;
499bail_out:
500 mutex_unlock(&rio500_mutex); 487 mutex_unlock(&rio500_mutex);
501 488
489 retval = usb_register_dev(intf, &usb_rio_class);
490 if (retval) {
491 dev_err(&dev->dev,
492 "Not able to get a minor for this device.\n");
493 goto err_register;
494 }
495
496 usb_set_intfdata(intf, rio);
497 return retval;
498
499 err_register:
500 mutex_lock(&rio500_mutex);
501 rio->present = 0;
502 mutex_unlock(&rio500_mutex);
503 err_ibuf:
504 kfree(obuf);
505 err_obuf:
502 return retval; 506 return retval;
503} 507}
504 508
@@ -507,10 +511,10 @@ static void disconnect_rio(struct usb_interface *intf)
507 struct rio_usb_data *rio = usb_get_intfdata (intf); 511 struct rio_usb_data *rio = usb_get_intfdata (intf);
508 512
509 usb_set_intfdata (intf, NULL); 513 usb_set_intfdata (intf, NULL);
510 mutex_lock(&rio500_mutex);
511 if (rio) { 514 if (rio) {
512 usb_deregister_dev(intf, &usb_rio_class); 515 usb_deregister_dev(intf, &usb_rio_class);
513 516
517 mutex_lock(&rio500_mutex);
514 if (rio->isopen) { 518 if (rio->isopen) {
515 rio->isopen = 0; 519 rio->isopen = 0;
516 /* better let it finish - the release will do whats needed */ 520 /* better let it finish - the release will do whats needed */
@@ -524,8 +528,8 @@ static void disconnect_rio(struct usb_interface *intf)
524 dev_info(&intf->dev, "USB Rio disconnected.\n"); 528 dev_info(&intf->dev, "USB Rio disconnected.\n");
525 529
526 rio->present = 0; 530 rio->present = 0;
531 mutex_unlock(&rio500_mutex);
527 } 532 }
528 mutex_unlock(&rio500_mutex);
529} 533}
530 534
531static const struct usb_device_id rio_table[] = { 535static const struct usb_device_id rio_table[] = {