[U-Boot] [U-Boot, v1] dm: usb: Prevent NULL hub in usb_device_info()
Hans de Goede
hdegoede at redhat.com
Sun Jul 3 20:21:43 CEST 2016
Hi,
On 02-07-16 23:13, Hans de Goede wrote:
> Hi,
>
> On 29-06-16 10:43, Bernhard Nortmann wrote:
>> This patch modifies the usb_device_info() function to enumerate
>> active USB hubs by iterating UCLASS_USB_HUB directly.
>>
>> The previous code used UCLASS_USB nodes instead and retrieved
>> their first child node, expecting it to be a hub. However, it
>> did not protect against retrieving (and dereferencing) a NULL
>> pointer this way.
>>
>> Depending on the available USB hardware, this might happen easily.
>> For example the USB controller on sun7i-a20 has top-level OHCI
>> nodes that won't have any children as long as no USB1-only
>> peripheral is attached. ("usb tree" will only show EHCI nodes.)
>>
>> The failure can also be demonstrated with U-Boot's sandbox
>> architecture, by simply enabling the inactive "usb_2" node in
>> test.dts. This creates a similar situation, where the existing
>> usb_device_info() implementation would crash (segfault) when
>> issuing a "usb info" command.
>>
>> Signed-off-by: Bernhard Nortmann <bernhard.nortmann at web.de>
>> Reviewed-by: Simon Glass <sjg at chromium.org>
>> ---
>>
>> cmd/usb.c | 15 +++++----------
>> 1 file changed, 5 insertions(+), 10 deletions(-)
>>
>> diff --git a/cmd/usb.c b/cmd/usb.c
>> index 58d9db2..3146f54 100644
>> --- a/cmd/usb.c
>> +++ b/cmd/usb.c
>> @@ -602,18 +602,13 @@ static void show_info(struct udevice *dev)
>>
>> static int usb_device_info(void)
>> {
>> - struct udevice *bus;
>> -
>> - for (uclass_first_device(UCLASS_USB, &bus);
>> - bus;
>> - uclass_next_device(&bus)) {
>> - struct udevice *hub;
>> + struct udevice *hub;
>>
>> - device_find_first_child(bus, &hub);
>> - if (device_get_uclass_id(hub) == UCLASS_USB_HUB &&
>> - device_active(hub)) {
>> + for (uclass_first_device(UCLASS_USB_HUB, &hub);
>
> We really want to check for bus here not hub, there are 2
> problems with checking for hubs:
>
> 1) show_info recurses into child hubs, so going over all
> hubs will cause any nested hubs to get printed twice
> (I think)
> 2) on some otg ports in host-mode there is no emulated
> root-hub in u-boot, so this will skip printing of any device
> attached to them
>
> Besides this there are several other subtleties missed here
> wrt iterating over usb-root-devs.
>
> I've spend quite some time getting this all right for "usb tree"
> but I somehow missed that "usb info" needed the same treatment.
>
> I've prepared 2 patches which re-use the "usb tree" code
> rather then re-inventing the wheel again:
>
> https://github.com/jwrdegoede/u-boot-sunxi/commit/fecf9576247c9423a20570057a1de59f1dbc2da1
> https://github.com/jwrdegoede/u-boot-sunxi/commit/d61f186f494062539418ac9da800a354258a4ad2
>
> As an added bonus these actually result in removing some code
> instead of duplicating it.
>
> Note these are only compile tested yet. I'll properly
> test them tomorrow and then submit them officially.
Ok I've just completed a battery of tests and these 2 look good,
I'll submit them upstream right after this mail.
Regards,
Hans
More information about the U-Boot
mailing list