usb: mdc800: fix circular locking dependency in probe/open
PATCH 1/1 usb: mdc800: fix circular locking dependency in probe/open
mdc800_usb_probe() acquired mdc800->io_lock before calling usb_register_dev(), which internally takes minor_rwsem. Meanwhile mdc800_device_open() is called through usb_open() with minor_rwsem already held, and then tries to acquire io_lock, producing an AB-BA lock inversion:
probe: io_lock -> minor_rwsem (via usb_register_dev)
open: minor_rwsem -> io_lock
Until usb_register_dev() succeeds and creates the device node, no concurrent open can happen, so io_lock provides no protection during probe before that point. Move usb_register_dev() to the end of the probe function, after all URB and state setup, and drop io_lock entirely from probe, eliminating the inversion.
Reported-by [email protected]
Signed-off-by Ivy Lopez <[email protected]>
--- drivers/usb/image/mdc800.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
drivers/usb/image/mdc800.c +5 -10
@@ -480,15 +480,6 @@ static int mdc800_usb_probe (struct usb_interface *intf,dev_info (&intf->dev,"Found Mustek MDC800 on USB.\n" ); -mutex_lock (&mdc800->io_lock); - - retval =usb_register_dev (intf, &mdc800_class); -if (retval) { -dev_err (&intf->dev,"Not able to get a minor for this device.\n" ); -mutex_unlock (&mdc800->io_lock); -return -ENODEV ; - } - mdc800->dev=dev; mdc800->open=0 ;
@@ -526,7 +517,11 @@ static int mdc800_usb_probe (struct usb_interface *intf, mdc800->state=READY ; -mutex_unlock (&mdc800->io_lock); + retval =usb_register_dev (intf, &mdc800_class); +if (retval) { +dev_err (&intf->dev,"Not able to get a minor for this device.\n" ); +return -ENODEV ; + }usb_set_intfdata (intf, mdc800);return 0 ;
Signature · 1 line
2.55.0