[PATCH] cmd: usb: Prevent reset in usb tree/info command

Xavier Drudis Ferran xdrudis at tinet.cat
Mon Jun 5 17:20:41 CEST 2023


Add a check to avoid dommed (by null pointer dereference) recursive
call, not only for UCLASS_BLK.

When booting my Rock Pi 4B+ with a USB mass storage stick plugged
into one of the USB 2 ports (EHCI), when it is plugged before power
on, when issuing a

usb tree

or

usb info

command I get a "Synchronous Error" and a reset just after printing the
mass storage device in the usb tree or usb info. It might depend on the
contents of the USB stick too, I'm not sure.

It seems like I have two devices as children of the mass storage
device.  When there's only a UCLASS_BLK it works fine, but when there's
a UCLASS_BLK and a UCLASS_BOOTDEV, it recurses with a null udev as
first parameter and fails.

Likewise for usb_show_info().

Not sure if this should be a patch, an RFC or a bug report.  There may
be a better way to solve this, I haven't researched commit
201417d700a2ab09 ("bootstd: Add the bootdev uclass") and bootdev flow
properly, or thought about cases where udev is not null but the
recursive call might need preventing too. Feel free to think it over
before merging (or after). But this at least fixes a reset at an
innocent looking usb tree or usb info command. Maybe we can improve it
later?

Cc: Simon Glass <sjg at chromium.org>
Cc: Lukasz Majewski <lukma at denx.de>
Cc: Marek Vasut <marex at denx.de>


Signed-off-by: Xavier Drudis Ferran <xdrudis at tinet.cat>
---
 cmd/usb.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/cmd/usb.c b/cmd/usb.c
index 73addb04c4..7e6065aa51 100644
--- a/cmd/usb.c
+++ b/cmd/usb.c
@@ -421,7 +421,8 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre)
 		 * Ignore emulators and block child devices, we only want
 		 * real devices
 		 */
-		if ((device_get_uclass_id(child) != UCLASS_USB_EMUL) &&
+		if (udev &&
+		    (device_get_uclass_id(child) != UCLASS_USB_EMUL) &&
 		    (device_get_uclass_id(child) != UCLASS_BLK)) {
 			usb_show_tree_graph(udev, pre);
 			pre[index] = 0;
@@ -607,7 +608,8 @@ static void usb_show_info(struct usb_device *udev)
 		    (device_get_uclass_id(child) != UCLASS_USB_EMUL) &&
 		    (device_get_uclass_id(child) != UCLASS_BLK)) {
 			udev = dev_get_parent_priv(child);
-			usb_show_info(udev);
+			if (udev)
+				usb_show_info(udev);
 		}
 	}
 }
-- 
2.20.1




More information about the U-Boot mailing list