usb_remove_device() logs the removal after unregister_device() has run.
That is too late: unregister_device() starts with bobject_del(), which
frees the device name, and ends with free_device_res(), which frees
unique_name. dev_printf() then reads both back via dev_name() to build
the message prefix, so both the success and the error message are
use-after-free reads.

Print before unregistering instead. While at it, drop the error branch:
unregister_device() returns 0 unconditionally, so it never ran.

This is not observable today because nothing ever calls
usb_remove_device(), but that is about to change.

Signed-off-by: Sascha Hauer <[email protected]>
Assisted-by: Claude:claude-opus-5
---
 drivers/usb/core/usb.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 3f379197dc..3daa6b1d1d 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -625,10 +625,13 @@ void usb_remove_device(struct usb_device *usbdev)
        list_del(&usbdev->list);
        dev_count--;
 
-       if (unregister_device(&usbdev->dev))
-               dev_err(&usbdev->dev, "failed to unregister\n");
-       else
-               dev_info(&usbdev->dev, "removed\n");
+       /*
+        * unregister_device() frees the device name, so there is nothing
+        * left to print afterwards.
+        */
+       dev_info(&usbdev->dev, "removed\n");
+
+       unregister_device(&usbdev->dev);
 
        usb_free_device(usbdev);
 }

-- 
2.47.3


Reply via email to