lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <b7468de2-d186-4706-8db3-594285ba264b@rowland.harvard.edu>
Date: Mon, 21 Jul 2025 23:05:50 -0400
From: Alan Stern <stern@...land.harvard.edu>
To: Marco Tormento <mtormento80@...il.com>
Cc: gregkh@...uxfoundation.org, linux-usb@...r.kernel.org,
	linux-kernel@...r.kernel.org
Subject: Re: [PATCH] USB: hub: Move typec deattach before children
 disconnections in usb_disconnect()

On Tue, Jul 22, 2025 at 01:18:25AM +0200, Marco Tormento wrote:
> On Mon, 21 Jul 2025 at 03:21, Alan Stern <stern@...land.harvard.edu> wrote:
> > I'm not a typec expert; in fact I know practically nothing about it.
> > Nevertheless, this sounds strange.  The recursive usb_disconnect() calls
> > should affect the connectors to the monitor's children and the monitor's
> > own ports, not the connector or port on the monitor's parent hub.
> 
> What you wrote makes total sense, let me add some detail though.
> When I plug the monitor to the thunderbolt port, 3 usb hubs pop up, but only 2
> are backed by XHCI Host Controllers: usb3 and usb4.

I don't know what you mean when you say "backed by".  usb3 and usb4 are 
the two root hubs of the xHCI host controller.  usb3-1 is an internal 
hub (presumably built into the monitor) attached to the usb3 root hub.

> usb 3-1 instead is using usb3 and it has 3 devices connected to it: mouse,
> keyboard and a mysterious billboard device:
> 
> xhci_hcd 0000:3c:00.0: xHCI Host Controller
> xhci_hcd 0000:3c:00.0: new USB bus registered, assigned bus number 3
> xhci_hcd 0000:3c:00.0: hcc params 0x200077c1 hci version 0x110 quirks
> 0x0000000200009810
> xhci_hcd 0000:3c:00.0: xHCI Host Controller
> xhci_hcd 0000:3c:00.0: new USB bus registered, assigned bus number 4
> xhci_hcd 0000:3c:00.0: Host supports USB 3.1 Enhanced SuperSpeed
> usb usb3: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 6.15
> usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb3: Product: xHCI Host Controller
> usb usb3: Manufacturer: Linux 6.15.7-arch1-1-mentor xhci-hcd
> usb usb3: SerialNumber: 0000:3c:00.0
> hub 3-0:1.0: USB hub found
> hub 3-0:1.0: 2 ports detected
> usb usb4: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 6.15
> usb usb4: New USB device strings: Mfr=3, Product=2, SerialNumber=1
> usb usb4: Product: xHCI Host Controller
> usb usb4: Manufacturer: Linux 6.15.7-arch1-1-mentor xhci-hcd
> usb usb4: SerialNumber: 0000:3c:00.0
> hub 4-0:1.0: USB hub found
> hub 4-0:1.0: 2 ports detected
> typec port0: bound usb3-port1 (ops connector_ops [usbcore])
> typec port0: bound usb4-port1 (ops connector_ops [usbcore])
> typec port1: bound usb3-port2 (ops connector_ops [usbcore])
> typec port1: bound usb4-port2 (ops connector_ops [usbcore])

Why are the usb3 port connectors getting bound at this point rather than 
when usb3 was registered?

> usb 3-1: new high-speed USB device number 2 using xhci_hcd
> usb 3-1: New USB device found, idVendor=0bda, idProduct=5411, bcdDevice= 1.36
> usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
> usb 3-1: Product: 4-Port USB 2.0 Hub
> usb 3-1: Manufacturer: Generic
> hub 3-1:1.0: USB hub found
> hub 3-1:1.0: 3 ports detected
> usb 3-1.3: new full-speed USB device number 3 using xhci_hcd
> usb 3-1.3: not running at top speed; connect to a high speed hub

I'm actually puzzled by this line.  Apparently the mysterious Realtek 
BillBoard Device claims that it is capable of connecting at high speed, 
but even though it was attached to a high-speed hub it only connected at 
full speed.  Things like this have shown up in other users' reports but 
I never bothered to point out the inconsistencies to anyone.

Either the device is lying about its capabilities or else it is 
malfunctioning.  Either way, I guess there isn't anything the kernel can 
do about it.

> usb 3-1.3: New USB device found, idVendor=0bda, idProduct=5400, bcdDevice= 1.07
> usb 3-1.3: New USB device strings: Mfr=17, Product=18, SerialNumber=19
> usb 3-1.3: Product: BillBoard Device
> usb 3-1.3: Manufacturer: Realtek
> usb 3-1.3: SerialNumber: 123456789ABCDEFGH
> usb 3-1.2: new full-speed USB device number 4 using xhci_hcd
> usb 3-1.2: New USB device found, idVendor=0951, idProduct=16e6, bcdDevice=21.08
> usb 3-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
> usb 3-1.2: Product: HyperX Alloy Origins Core
> usb 3-1.2: Manufacturer: Kingston
> usb 3-1.1: new full-speed USB device number 5 using xhci_hcd
> usb 3-1.1: New USB device found, idVendor=1a7c, idProduct=0197, bcdDevice= 1.06
> usb 3-1.1: New USB device strings: Mfr=1, Product=3, SerialNumber=0
> usb 3-1.1: Product: Evoluent VerticalMouse D
> usb 3-1.1: Manufacturer: Kingsis Peripherals
> 
> When I unplug the monitor though, usb 3-1 is not processed as part of
> hub_disconnect_children() of usb3 hub, as I would expect.

Are you sure about this?  How did you reach that conclusion?

> It is processed on its own (added some debugging log to some functions):
> 
> usb 3-1: [usb_disconnect] debugging
> usb 3-1: [usb_disconnect] USB disconnect, device number 2
> usb 3-1: [hub_disconnect_children] debugging hub_disconnect_children()
> usb 3-1: [hub_disconnect_children] disconnecting child 0
> usb 3-1.1: [usb_disconnect] debugging
> usb 3-1.1: [usb_disconnect] USB disconnect, device number 5
> usb 3-1.1: [hub_disconnect_children] debugging hub_disconnect_children()
> usb 3-1.1: [usb_disconnect] unregistering device
> usbhid 3-1.1:1.0: [usb_unbind_interface] debugging
> usb 3-1.1: [usb_disconnect] parent found
> usb 3-1.1: [usb_disconnect] removing port 3-1-port1 from hub 3-1:1.0: 0
> usb 3-1.1: [usb_disconnect] done with the device
> usb 3-1: [hub_disconnect_children] disconnecting child 1
> usb 3-1.2: [usb_disconnect] debugging
> usb 3-1.2: [usb_disconnect] USB disconnect, device number 4
> usb 3-1.2: [hub_disconnect_children] debugging hub_disconnect_children()
> usb 3-1.2: [usb_disconnect] unregistering device
> usbhid 3-1.2:1.0: [usb_unbind_interface] debugging
> xhci_hcd 0000:3c:00.0: remove, state 4
> usb usb4: [usb_disconnect] debugging
> usb usb4: [usb_disconnect] USB disconnect, device number 1
> usb usb4: [hub_disconnect_children] debugging hub_disconnect_children()
> usb usb4: [usb_disconnect] unregistering device
> hub 4-0:1.0: [usb_unbind_interface] debugging
> usb usb4: [hub_disconnect] debugging
> usb usb4-port2: [usb_hub_remove_port_device] debugging: port 1
> typec port1: [connector_unbind] unbinding connector from usb4-port2
> typec port1: [connector_unbind] unbinding connector from usb3-port2
> usb usb4-port1: [usb_hub_remove_port_device] debugging: port 0
> typec port0: [connector_unbind] unbinding connector from usb4-port1
> typec port0: [connector_unbind] unbinding connector from usb3-port1
> usb usb4: [usb_disconnect] done with the device
> xhci_hcd 0000:3c:00.0: USB bus 4 deregistered
> xhci_hcd 0000:3c:00.0: xHCI host controller not responding, assume dead
> xhci_hcd 0000:3c:00.0: remove, state 1
> usb usb3: [usb_disconnect] debugging
> usb usb3: [usb_disconnect] USB disconnect, device number 1
> typec port1-partner: [typec_unregister_partner] debugging
> typec port1-partner: [typec_unregister_partner] unregistering from port: port1
> usbhid 3-1.2:1.1: [usb_unbind_interface] debugging
> usbhid 3-1.2:1.2: [usb_unbind_interface] debugging
> usb 3-1.2: [usb_disconnect] parent found
> usb 3-1.2: [usb_disconnect] removing port 3-1-port2 from hub 3-1:1.0: 1
> usb 3-1.2: [usb_disconnect] done with the device
> usb 3-1: [hub_disconnect_children] disconnecting child 2
> usb 3-1.3: [usb_disconnect] debugging
> usb 3-1.3: [usb_disconnect] USB disconnect, device number 3
> usb 3-1.3: [hub_disconnect_children] debugging hub_disconnect_children()
> usb 3-1.3: [usb_disconnect] unregistering device
> usb 3-1.3: [usb_disconnect] parent found
> usb 3-1.3: [usb_disconnect] removing port 3-1-port3 from hub 3-1:1.0: 2
> usb 3-1.3: [usb_disconnect] done with the device
> usb 3-1: [usb_disconnect] unregistering device
> hub 3-1:1.0: [usb_unbind_interface] debugging
> usb 3-1: [hub_disconnect] debugging
> usb 3-1-port3: [usb_hub_remove_port_device] debugging: port 2
> usb 3-1-port2: [usb_hub_remove_port_device] debugging: port 1
> usb 3-1-port1: [usb_hub_remove_port_device] debugging: port 0
> usb 3-1: [usb_disconnect] parent found
> usb 3-1: [usb_disconnect] removing port usb3-port1 from hub 3-0:1.0: 0
> usb 3-1: [usb_disconnect] done with the device
> usb usb3: [hub_disconnect_children] debugging hub_disconnect_children()
> usb usb3: [usb_disconnect] unregistering device
> hub 3-0:1.0: [usb_unbind_interface] debugging
> usb usb3: [hub_disconnect] debugging
> usb usb3-port2: [usb_hub_remove_port_device] debugging: port 1
> usb usb3-port1: [usb_hub_remove_port_device] debugging: port 0
> usb usb3: [usb_disconnect] done with the device
> xhci_hcd 0000:3c:00.0: Host halt failed, -19
> xhci_hcd 0000:3c:00.0: Host not accessible, reset failed.
> xhci_hcd 0000:3c:00.0: USB bus 3 deregistered
> 
> As you can see typec port connectors are unbound during usb4 usb_disconnect(),
> so when usb 3-1 tries to typec_deattach() after it disconnected all its children
> the connector is not there anymore and type_partner_deattach() is not invoked.
Yes.  I would guess this happens because of the way the port connectors 
were registered in the first place (see my question above).

> Maybe usb 3-1 should be disconnected as a child of usb3, but even in that case
> we would still end up in the same situation because it's usb4 disconnection that
> is doing the unbinding.
> Since there's no dependency between usb3 and usb4 they can be
> disconnected in any order and it's just a matter of luck as it is right now.

That last sentence is totally wrong.  usb3 and usb4 are closely 
connected, since they represent logical components of the same xHCI 
controller, and they will always be unregistered in the same order.  
usb3 is the USB-2 root hub (the one connected to the physical wires 
carrying the USB-2 low/full/high-speed signals), and usb4 is the USB-3 
root hub (the one connected to the physical wires carrying the USB-3 
SuperSpeed and SuperSpeedPlus signals).

> Hope things make a little bit more sense now.

This still leaves the puzzle about why the typec things are handled this 
way.  In particular, if connector_unbind undoes the binding of the typec 
ports that happened when usb4 was registered, then what action is 
typec_unregister_partner supposed to undo, and when was it supposed to 
happen?  As a general rule, disconnection and unregistration actions 
take place in the reverse order of the corresponding connection and 
registration actions.

Questions like this are best directed at the maintainers of the 
USB-4/Thunderbolt and typec subsystems.

Alan Stern

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ