[PATCH] usb: hub: fix refcount leak in usb_new_device()
From: WenTao Liang
Date: Thu Jun 11 2026 - 09:07:02 EST
If usb_new_device() fails after pm_runtime_get_noresume() has
been called, it does not release the corresponding reference.
In the successful path, the reference is properly dropped via
pm_runtime_put_sync_autosuspend(). However, when an error
occurs during enumeration (e.g. usb_enumerate_device() failure)
or device registration (e.g. device_add() failure), the function
jumps to the "fail" label. That error cleanup path only disables
runtime PM and marks the device as suspended, never putting the
usage count back. This results in a permanent imbalance of
power.usage_count, preventing future runtime PM state transitions
and proper device cleanup.
Fix the leak by adding a pm_runtime_put_noidle() call before
pm_runtime_disable() in the fail error path, which releases the
reference without queuing any suspend work and appropriately
matches the pm_runtime_get
Cc: stable@xxxxxxxxxxxxxxx
Fixes: 9bbdf1e0afe7 ("USB: convert to the runtime PM framework")
Signed-off-by: WenTao Liang <vulab@xxxxxxxxxxx>
---
drivers/usb/core/hub.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 24960ba9caa9..05f1a4267aec 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2731,6 +2731,7 @@ int usb_new_device(struct usb_device *udev)
device_del(&udev->dev);
fail:
usb_set_device_state(udev, USB_STATE_NOTATTACHED);
+ pm_runtime_put_noidle(&udev->dev);
pm_runtime_disable(&udev->dev);
pm_runtime_set_suspended(&udev->dev);
return err;
--
2.50.1 (Apple Git-155)