Thread (5 messages) flat view 5 messages, 2 authors, 20d ago

Re: [PATCH 1/1] usb: gadget: inode: fix use-after-free of struct ep_data

From: Alan Stern <stern@rowland.harvard.edu>
Date: 2026-09-04 19:27:56

On Fri, Sep 04, 2026 at 01:31:29PM -0400, Adriano Córdova wrote:
Hi Alan,

Right. But that patch makes the inode the sole lifetime owner of the ep_data
(deletes the list call to 'put_ep'), but ep_data is also linked in the list
dev->epfiles and that reference can outlive the inode (it doesn't happen now
I think, but only incidentally).
Okay, I see.
So in the patch in here I decided to go with a refcount approach, just to
be safe.
The patch description could be improved just a little...
El vie, 4 sept 2026 a las 12:50, Alan Stern ([off-list ref])
escribió:
quoted
On Fri, Sep 04, 2026 at 12:38:27PM -0400, Adriano Cordova wrote:
quoted
gadgetfs_unbind() -> destroy_ep_files() frees each struct ep_data via
put_ep(), but the inode still points at that ep_data through ->i_private
with no reference of its own.  A concurrent openat() on an endpoint file
can therefore reach ep_open() and dereference the freed ep_data (the
mutex fast path), even while the inode outlives it.
You could mention something about the inode's lifetime and what causes 
it to be released (and when).  This would make it clearer to people like 
me how a concurrent open() can race with inode destruction.  But I 
agree, you're right that the inode's pointer should be counted in the 
ep_data's refcount.
quoted
quoted
Give the inode its own reference: take get_ep() when the endpoint inode
is created and drop it again from a new gadgetfs_evict_inode(), so an
ep_data can never be freed while any inode still points at it.  This is
also safe against dcache pruning, since the inode reference keeps the
count >= 1 until the endpoint is removed from dev->epfiles.
Now it all makes sense.

Your patch doesn't handle the case where the gadgetfs_make_inode() call 
in gadgetfs_create_file() fails.  If that happens, the refcount will 
remain elevated because there is no inode to evict.  I'll leave it to 
you to figure out the best solution.

Alan Stern
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help