Re: [PATCH] usb: hub: fix refcount leak in usb_new_device()
From: Alan Stern
Date: Thu Jun 11 2026 - 10:11:58 EST
On Thu, Jun 11, 2026 at 09:02:23PM +0800, WenTao Liang wrote:
> 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>
> ---
Reviewed-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx>
> 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)
>