Linux USB
 help / color / mirror / Atom feed
* [PATCH] thunderbolt: Keep the USB4 port when component_add() fails
@ 2026-11-12  9:57 Suyuan Wang via B4 Relay
  2026-11-12 10:00 ` sashiko-bot
  0 siblings, 1 reply; 2+ messages in thread
From: Suyuan Wang via B4 Relay @ 2026-11-12  9:57 UTC (permalink / raw)
  To: andreas.noever, YehezkelShB, westeri
  Cc: heikki.krogerus, linux-kernel, alok.a.tiwari, linux-usb

From: Suyuan Wang <stevewong@hust.edu.cn>

When component_add() fails, usb4_port_device_add() unregisters the
device but doesn't return:

    ret = component_add(&usb4->dev, &connector_ops);
    if (ret) {
            dev_err(&usb4->dev, "failed to add component\n");
            device_unregister(&usb4->dev);
    }

The port was registered just before, so device_unregister() normally
drops the last reference and usb4_port_device_release() frees usb4.
The function still goes on to set up runtime PM on usb4->dev and
returns usb4 to usb4_switch_add_ports(), which stores the stale pointer
in port->usb4. When the router is removed later,
usb4_switch_remove_ports() calls component_del() and
device_unregister() on that pointer again.

component_add() can fail on allocation, or when binding the aggregate
driver fails. It isn't common, but when it happens the result is a
use-after-free and a double unregister.

The USB4 port can keep working without the component link. Keep the
port registered when component_add() fails, and track whether the
component was added, so that usb4_port_device_remove() only calls
component_del() for a registered component. Otherwise component_del()
would hit its WARN_ON().

Found with a static analysis tool and checked by hand.

Fixes: 5dddb4169284 ("thunderbolt: Link USB4 ports to their USB Type-C connectors")
Reported-by: Alok Tiwari <alok.a.tiwari@oracle.com>
Closes: https://lore.kernel.org/all/20250622140455.2884518-1-alok.a.tiwari@oracle.com/
Suggested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Cc: stable@vger.kernel.org
Co-developed-by: Kaixuan Li <kaixuan.li@ntu.edu.sg>
Signed-off-by: Kaixuan Li <kaixuan.li@ntu.edu.sg>
Signed-off-by: Suyuan Wang <stevewong@hust.edu.cn>
---
Alok asked about the missing return in 2025, and a one-line return
patch was posted in May. In both threads Mika said he'd rather keep the
port, so this does that instead.

https://lore.kernel.org/all/20260517142923.80585-1-darknessshayder@gmail.com/

Compile tested only, I didn't try to force component_add() to fail.
---
 drivers/thunderbolt/tb.h        |  2 ++
 drivers/thunderbolt/usb4_port.c | 12 +++++++-----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h
index e86845762e22..8ed373e94b65 100644
--- a/drivers/thunderbolt/tb.h
+++ b/drivers/thunderbolt/tb.h
@@ -314,6 +314,7 @@ struct tb_port {
  * @can_offline: Does the port have necessary platform support to move
  *		 it into offline mode and back
  * @offline: The port is currently in offline mode
+ * @component_added: The port was added to the component framework
  * @margining: Pointer to margining structure if enabled
  */
 struct usb4_port {
@@ -321,6 +322,7 @@ struct usb4_port {
 	struct tb_port *port;
 	bool can_offline;
 	bool offline;
+	bool component_added;
 #ifdef CONFIG_USB4_DEBUGFS_MARGINING
 	struct tb_margining *margining;
 #endif
diff --git a/drivers/thunderbolt/usb4_port.c b/drivers/thunderbolt/usb4_port.c
index 890de530debc..7582acadf37c 100644
--- a/drivers/thunderbolt/usb4_port.c
+++ b/drivers/thunderbolt/usb4_port.c
@@ -320,11 +320,12 @@ struct usb4_port *usb4_port_device_add(struct tb_port *port)
 		return ERR_PTR(ret);
 	}
 
+	/* The port works fine without the component, so don't fail here */
 	ret = component_add(&usb4->dev, &connector_ops);
-	if (ret) {
-		dev_err(&usb4->dev, "failed to add component\n");
-		device_unregister(&usb4->dev);
-	}
+	if (ret)
+		dev_err(&usb4->dev, "failed to add component: %d\n", ret);
+	else
+		usb4->component_added = true;
 
 	if (!tb_is_upstream_port(port))
 		device_set_wakeup_capable(&usb4->dev, true);
@@ -348,7 +349,8 @@ struct usb4_port *usb4_port_device_add(struct tb_port *port)
  */
 void usb4_port_device_remove(struct usb4_port *usb4)
 {
-	component_del(&usb4->dev, &connector_ops);
+	if (usb4->component_added)
+		component_del(&usb4->dev, &connector_ops);
 	device_unregister(&usb4->dev);
 }
 

---
base-commit: 630059a5a632377b9b7b487baccde92b7ae1dd47
change-id: 20261112-thunderbolt-7d1eb9b68e19

Best regards,
--  
Suyuan Wang <shyckless@gmail.com>



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] thunderbolt: Keep the USB4 port when component_add() fails
  2026-11-12  9:57 [PATCH] thunderbolt: Keep the USB4 port when component_add() fails Suyuan Wang via B4 Relay
@ 2026-11-12 10:00 ` sashiko-bot
  0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-11-12 10:00 UTC (permalink / raw)
  To: Suyuan Wang; +Cc: linux-usb

> From: Suyuan Wang <stevewong@hust.edu.cn>
> 
> When component_add() fails, usb4_port_device_add() unregisters the
> device but doesn't return:
> 
>     ret = component_add(&usb4->dev, &connector_ops);
>     if (ret) {
>             dev_err(&usb4->dev, "failed to add component\n");
>             device_unregister(&usb4->dev);
>     }
> 
> The port was registered just before, so device_unregister() normally
> drops the last reference and usb4_port_device_release() frees usb4.
> The function still goes on to set up runtime PM on usb4->dev and
> returns usb4 to usb4_switch_add_ports(), which stores the stale pointer
> [ ... ]
> Suggested-by: Mika Westerberg <mika.westerberg@linux.intel.com>
> Cc: stable@vger.kernel.org
> Co-developed-by: Kaixuan Li <kaixuan.li@ntu.edu.sg>
> Signed-off-by: Kaixuan Li <kaixuan.li@ntu.edu.sg>
> Signed-off-by: Suyuan Wang <stevewong@hust.edu.cn>

Sashiko has reviewed this patch and found no issues.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261112-thunderbolt-v1-1-fc30057cb7cd@gmail.com?part=1


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-11-12 10:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-12  9:57 [PATCH] thunderbolt: Keep the USB4 port when component_add() fails Suyuan Wang via B4 Relay
2026-11-12 10:00 ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox