[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAKzKK0oi85bnyT3Lq_TXz8YwFrmBxQd8K1q7hRDv-Oww75F_tQ@mail.gmail.com>
Date: Thu, 11 Sep 2025 14:50:15 +0800
From: Kuen-Han Tsai <khtsai@...gle.com>
To: Greg KH <gregkh@...uxfoundation.org>
Cc: zack.rusin@...adcom.com, krzysztof.kozlowski@...aro.org,
namcao@...utronix.de, linux-usb@...r.kernel.org, linux-kernel@...r.kernel.org,
stable@...nel.org
Subject: Re: [PATCH] usb: gadget: f_ncm: Fix NPE in ncm_bind error path
Hi Greg,
On Sat, Sep 6, 2025 at 8:15 PM Greg KH <gregkh@...uxfoundation.org> wrote:
>
> On Thu, Sep 04, 2025 at 07:46:13PM +0800, Kuen-Han Tsai wrote:
> > When an ncm_bind/unbind cycle occurs, the ncm->notify_req pointer is
> > left pointing to a stale address. If a subsequent call to ncm_bind()
> > fails to allocate the endpoints, the function jumps to the unified error
> > label. The cleanup code sees the stale ncm->notify_req pointer and calls
> > usb_ep_free_request().
> >
> > This results in a NPE because it attempts to access the free_request
> > function through the endpoint's operations table (ep->ops), which is
> > NULL.
> >
> > Refactor the error path to use cascading goto labels, ensuring that
> > resources are freed in reverse order of allocation. Besides, explicitly
> > set pointers to NULL after freeing them.
>
> Why must the pointers be set to NULL? What is checking and requiring
> that?
I set them to null as a standard safety measure to prevent potential
use-after-free issues. I can remove it if you prefer.
>
> And this unwinding is tailor-made for the guard() type of logic, why not
> convert this code to do that instead, which will fix all of these bugs
> automatically, right?
The __free() cleanup mechanism is unfortunately infeasible in this
case. The usb_ep_free_request(ep, req) requires two parameters, but
the automatic cleanup mechanism only needs one: the resource being
freed.
Since the struct usb_request doesn't contain the pointer to its
associated endpoint, the @free function cannot retrieve the ep pointer
it needs for the cleanup call. We would need to add an endpoint
pointer to usb_request to make it work. However, this will be a
significant change and we might also need to refactor drivers that use
the usb_ep_free_request(ep, req), usb_ep_queue(ep, req) and
usb_ep_dequeue(ep, req) as the endpoint parameter is no longer needed.
I also want to point out that this bug isn't specific to the f_ncm
driver. The f_acm, f_rndis and f_ecm are also vulnerable because their
bind paths have the same flaw. We have already observed this issue in
both f_ncm and f_acm on Android devices.
My plan was to merge this fix for f_ncm first and then apply the same
pattern to the other affected drivers. However, I am happy to have a
more thorough design discussion if you feel using __free()/guard()
automatic cleanup is the better path forward.
Regards,
Kuen-Han
Powered by blists - more mailing lists