From: Alan Stern <stern@rowland.harvard.edu>
To: Felicitas Hetzelt <file@sect.tu-berlin.de>
Cc: linux-usb@vger.kernel.org
Subject: Re: Null ptr deref in core/hub.c
Date: Sat, 24 Apr 2021 11:57:47 -0400 [thread overview]
Message-ID: <20210424155747.GC312740@rowland.harvard.edu> (raw)
In-Reply-To: <b0ba1c36-6ebd-49a9-38da-aa42d98271c0@sect.tu-berlin.de>
On Sat, Apr 24, 2021 at 02:08:45PM +0200, Felicitas Hetzelt wrote:
> Hello,
>
> I triggered a few potential npds in core/hub.c. The bugs trigger
> reliably. Unfortunately I don't have a reproducer, though i tried my
> best to root-cause the bugs. I'm using my own emulated xhci host
> controller device and a slightly exotic kernel environment based on
> kernel version 5.10.0-rc6, so it might be that the bug is not
> trigger-able under normal conditions.
>
> I was hoping you could maybe quickly determine whether this is a valid
> issue.
>
> usb_hub_to_struct can return zero if hdev->actconfig->interface[0]->dev
> is NULL.
I'm not sure what you mean here. dev is a member of the structure that
hdev->actconfig->interface[0] points to; it isn't a pointer itself. As
such, to say that it is NULL is meaningless.
Are you saying that sometimes hdev->actconfig->interface[0] is NULL when
usb_hub_to_struct runs? How can that be? usb_hub_to_struct doesn't
even refer to that field unless hdev->maxchild is nonzero, and that
field doesn't get set unless the hub driver is bound to the interface --
which doesn't happen if there is no interface.
> https://elixir.bootlin.com/linux/v4.9/source/drivers/usb/core/hub.c#L124
>
> https://elixir.bootlin.com/linux/v4.9/source/include/linux/usb.h#L194
>
> This is the case when usb_probe_interface fails to probe the device
> driver (called via usb_set_configuration -> device_add -> ...)
>
> https://elixir.bootlin.com/linux/v4.9/source/drivers/usb/core/driver.c#L372
That line sets the interface's driver data, not interface[0]->dev.
What's wrong with having the driver data be NULL? That just means the
device isn't a hub. In this situation hdev->maxchild will be 0.
Also, you say you're using a modified version of the 5.10.0-rc6 kernel
(kind of strange to be doing development on an -rc kernel instead of a
normal release, but never mind). So why are you posting links to the
4.9 kernel source? There have been a lot of changes between 4.9 and
5.10.
> Then e.g. on a new invocation of hub_port_connect, the function tries to
> un-attach the previously attached devices (listed as port_dev->child)
> and calls recursively_mark_NOTATTACHED (via usb_set_device_state(udev,
> USB_STATE_NOTATTACHED), which in turn tries to get a pointer to the hub
> via usb_hub_to_struct_hub, which is NULL which leads to the crash.
>
> https://elixir.bootlin.com/linux/v4.9/source/drivers/usb/core/hub.c#L4742
That's the call to usb_disconnect, which isn't really important to what
you're saying. You seem to be complaining about a crash in
recursively_mark_NOTATTACHED. Why didn't you insert a URL for that
function instead?
> I feel like this should be caught in hub_port_connect (which would set
You're not making yourself clear. What should be caught in
hub_port_connect?
Are you saying that sometimes we can have udev->maxchild > 0 in
recursively_mark_NOTATTACHED even though udev isn't bound to the hub
driver? If that's not it, then what _are_ you saying?
> port_dev->child = NULL, avoiding the later invocation of
> recursively_mark_NOTATTACHED), but the return value of usb_new_device is
> always valid (in fact usb_set_configuration can only return 0 once it
> gets to the calling add_device and probe).
>
> https://elixir.bootlin.com/linux/v4.9/source/drivers/usb/core/hub.c#L4891
>
> https://elixir.bootlin.com/linux/v4.9/source/drivers/usb/core/message.c#L1931
>
> To fix this one could check whether the interface is actually properly
> setup instead of just checking status, or alternatively always check the
> return value of usb_hub_to_struct_hub on later invocations.
>
> I attached the kernel log, it is a bit messy though i marked the
> relevant parts with 'XXNOTE'.
TL;DR. You should trim logs so that only the important parts get
posted.
> Let me know if you need any further information.
Please try to give a more explicit description of what's actually going
wrong. If you need to refer to lines of code in your email, just copy
them into the message -- don't put a URL to somewhere else, forcing the
reader to do extra work and lose the mental thread of the discussion.
Alan Stern
prev parent reply other threads:[~2021-04-24 15:57 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-04-24 12:08 Null ptr deref in core/hub.c Felicitas Hetzelt
2021-04-24 12:40 ` Greg KH
2021-04-24 15:57 ` Alan Stern [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210424155747.GC312740@rowland.harvard.edu \
--to=stern@rowland.harvard.edu \
--cc=file@sect.tu-berlin.de \
--cc=linux-usb@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox