]> Git Repo - J-u-boot.git/commitdiff
usb: kbd: destroy device after console is stopped
authorAndy Shevchenko <[email protected]>
Thu, 11 Feb 2021 15:09:44 +0000 (17:09 +0200)
committerTom Rini <[email protected]>
Tue, 16 Feb 2021 16:16:08 +0000 (11:16 -0500)
In case of IOMUX enabled it assumes that console devices in the list
are available to get them stopped properly via ->stop() callback.
However, the USB keyboard driver violates this assumption and tries
to play tricks so the device get destroyed while being listed as
an active console.

Swap the order of device deregistration and IOMUX update along with
converting to use iomux_replace_device() jelper to avoid the use-after-free.

Fixes: 3cbcb2892809 ("usb: Fix usb_kbd_deregister when console-muxing is used")
Fixes: 8a8348703081 ("dm: usb: Add a remove() method for USB keyboards")
Reported-by: Nicolas Saenz Julienne <[email protected]>
Signed-off-by: Andy Shevchenko <[email protected]>
common/usb_kbd.c

index b316807844b17150c5070c70f6bc9e39502f4695..60c6027e048d5864aafecd40e5a0594cf5cc0e32 100644 (file)
@@ -617,12 +617,12 @@ int usb_kbd_deregister(int force)
        if (dev) {
                usb_kbd_dev = (struct usb_device *)dev->priv;
                data = usb_kbd_dev->privptr;
-               if (stdio_deregister_dev(dev, force) != 0)
-                       return 1;
 #if CONFIG_IS_ENABLED(CONSOLE_MUX)
-               if (iomux_doenv(stdin, env_get("stdin")) != 0)
+               if (iomux_replace_device(stdin, DEVNAME, force ? "nulldev" : ""))
                        return 1;
 #endif
+               if (stdio_deregister_dev(dev, force) != 0)
+                       return 1;
 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
                destroy_int_queue(usb_kbd_dev, data->intq);
 #endif
@@ -660,16 +660,16 @@ static int usb_kbd_remove(struct udevice *dev)
                goto err;
        }
        data = udev->privptr;
-       if (stdio_deregister_dev(sdev, true)) {
-               ret = -EPERM;
-               goto err;
-       }
 #if CONFIG_IS_ENABLED(CONSOLE_MUX)
-       if (iomux_doenv(stdin, env_get("stdin"))) {
+       if (iomux_replace_device(stdin, DEVNAME, "nulldev")) {
                ret = -ENOLINK;
                goto err;
        }
 #endif
+       if (stdio_deregister_dev(sdev, true)) {
+               ret = -EPERM;
+               goto err;
+       }
 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
        destroy_int_queue(udev, data->intq);
 #endif
This page took 0.033077 seconds and 4 git commands to generate.