OSDN Git Service

media: igorplugusb: break cyclical race on disconnect
authorOliver Neukum <oneukum@suse.com>
Thu, 12 May 2022 12:38:48 +0000 (13:38 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Mon, 20 Jun 2022 09:30:33 +0000 (10:30 +0100)
The driver uses a timer, that may submit the URB and
the URB may start the timer. No simple order of killing
can break te cycle. Poison the URB before killing
the timer.

Signed-off-by: Oliver Neukum <oneukum@suse.com>
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
drivers/media/rc/igorplugusb.c

index 1afba95..b224584 100644 (file)
@@ -126,7 +126,7 @@ static void igorplugusb_cmd(struct igorplugusb *ir, int cmd)
        ir->request.bRequest = cmd;
        ir->urb->transfer_flags = 0;
        ret = usb_submit_urb(ir->urb, GFP_ATOMIC);
-       if (ret)
+       if (ret && ret != -EPERM)
                dev_err(ir->dev, "submit urb failed: %d", ret);
 }
 
@@ -223,7 +223,9 @@ static int igorplugusb_probe(struct usb_interface *intf,
 
        return 0;
 fail:
+       usb_poison_urb(ir->urb);
        del_timer(&ir->timer);
+       usb_unpoison_urb(ir->urb);
        usb_free_urb(ir->urb);
        rc_free_device(ir->rc);
        kfree(ir->buf_in);
@@ -236,9 +238,10 @@ static void igorplugusb_disconnect(struct usb_interface *intf)
        struct igorplugusb *ir = usb_get_intfdata(intf);
 
        rc_unregister_device(ir->rc);
+       usb_poison_urb(ir->urb);
        del_timer_sync(&ir->timer);
        usb_set_intfdata(intf, NULL);
-       usb_kill_urb(ir->urb);
+       usb_unpoison_urb(ir->urb);
        usb_free_urb(ir->urb);
        kfree(ir->buf_in);
 }