* [PATCH] usb: gadget: u_ether: refuse to re-register a failed net_device
@ 2026-10-14 11:06 Nicholas Velten via B4 Relay
2026-10-14 11:23 ` sashiko-bot
0 siblings, 1 reply; 2+ messages in thread
From: Nicholas Velten via B4 Relay @ 2026-10-14 11:06 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-usb, linux-kernel, syzbot+85ede281798faf736677,
Nicholas Velten
From: Nicholas Velten <nicholasfvelten@gmail.com>
When register_netdevice() fails in or after netdev_register_kobject(),
it returns an error but leaves the net_device in NETREG_UNREGISTERED.
Such a device can never be registered again; the only valid thing to do
with it is free_netdev().
The configfs Ethernet functions (ECM, EEM, NCM, RNDIS and subset)
allocate their net_device once per function instance and register it
from the bind callback, retrying on every bind for as long as the device
is not registered (formerly tracked by a "bound" flag, now by
device_is_registered()). After a failed registration the next bind
therefore calls register_netdev() on an NETREG_UNREGISTERED device and
hits the BUG_ON() at the top of register_netdevice():
kernel BUG at net/core/dev.c:11440!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
RIP: 0010:register_netdevice+0xc21/0x1d00
Call Trace:
register_netdev
gether_register_netdev
ncm_bind
usb_add_function
configfs_composite_bind
gadget_bind_driver
...
gadget_dev_desc_UDC_store
syzbot hits this by binding a gadget from a memory cgroup with a tiny
limit, which makes the memcg-accounted allocations in
netdev_register_kobject() fail. That is why its bisection lands on
commit 425b9c7f51c9 ("memcg: accounting for objects allocated for new
netdevice"): that commit made the failure reachable that way, while the
retry itself is much older.
Refuse to register a net_device that is not NETREG_UNINITIALIZED in
gether_register_netdev(), which all of these functions use, so that the
bind fails with -EINVAL instead of crashing. The function instance has
to be recreated to get a usable net_device again.
Reproduced with fail-nth fault injection on the allocations of the
write() to the gadget's UDC attribute, binding again without injection
after each failed bind, using a fresh function instance per iteration:
without this change NCM, ECM and RNDIS hit the BUG_ON() at the 16th
injected allocation; with it, 400 iterations for NCM and 300 each for
ECM, EEM, RNDIS and subset complete with no BUG or KASAN report.
Fixes: 40d133d7f542 ("usb: gadget: f_ncm: convert to new function interface with backward compatibility")
Reported-by: syzbot+85ede281798faf736677@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=85ede281798faf736677
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Nicholas Velten <nicholasfvelten@gmail.com>
---
The syzbot C reproducer did not reach the gadget bind in my virtme-ng
guest (its sandbox setup appears to fail there), so I reproduced with a
small fail-nth program instead. I can post it if useful.
Not tested: architectures other than x86_64, and the legacy (non-configfs)
gadgets that also call gether_register_netdev() (g_ether, g_multi,
g_ffs); they register once from their bind path and should be unaffected.
f_phonet has the same retry pattern but a different outcome:
gphonet_register_netdev() calls free_netdev() on failure while
phonet_opts->net still points at the device and phonet_opts->bound stays
false, so the next bind uses a freed net_device. I left it out of this
patch to keep it to one change and because f_phonet is being changed by
"usb: gadget: f_phonet: fix use-after-free in pn_bind" (v3, not yet
applied); I can send a separate fix on top of that if wanted.
Also touching gether_register_netdev(), without conflict:
"usb: gadget: u_ether: Fix NULL pointer deref in debug logging".
---
drivers/usb/gadget/function/u_ether.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
index 59d85d6a8..1f4ac7078 100644
--- a/drivers/usb/gadget/function/u_ether.c
+++ b/drivers/usb/gadget/function/u_ether.c
@@ -865,6 +865,17 @@ int gether_register_netdev(struct net_device *net)
if (!net->dev.parent)
return -EINVAL;
+
+ /*
+ * A register_netdev() that failed after netdev_register_kobject()
+ * leaves the device NETREG_UNREGISTERED, and it can never be
+ * registered again. The function drivers retry on every bind while
+ * the device is not registered, so refuse instead of hitting the
+ * BUG_ON() in register_netdevice().
+ */
+ if (net->reg_state != NETREG_UNINITIALIZED)
+ return -EINVAL;
+
dev = netdev_priv(net);
g = dev->gadget;
---
base-commit: a90ee4305c4a5df72c11b31dacfdc76e00fcf78a
change-id: 20261014-fix-gadget-netdev-reregister-75cf4090afeb
Best regards,
--
Nicholas Velten <nicholasfvelten@gmail.com>
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] usb: gadget: u_ether: refuse to re-register a failed net_device
2026-10-14 11:06 [PATCH] usb: gadget: u_ether: refuse to re-register a failed net_device Nicholas Velten via B4 Relay
@ 2026-10-14 11:23 ` sashiko-bot
0 siblings, 0 replies; 2+ messages in thread
From: sashiko-bot @ 2026-10-14 11:23 UTC (permalink / raw)
To: Nicholas Velten; +Cc: linux-usb
> From: Nicholas Velten <nicholasfvelten@gmail.com>
>
> When register_netdevice() fails in or after netdev_register_kobject(),
> it returns an error but leaves the net_device in NETREG_UNREGISTERED.
> Such a device can never be registered again; the only valid thing to do
> with it is free_netdev().
>
> The configfs Ethernet functions (ECM, EEM, NCM, RNDIS and subset)
> allocate their net_device once per function instance and register it
> from the bind callback, retrying on every bind for as long as the device
> is not registered (formerly tracked by a "bound" flag, now by
> device_is_registered()). After a failed registration the next bind
> therefore calls register_netdev() on an NETREG_UNREGISTERED device and
> hits the BUG_ON() at the top of register_netdevice():
>
> [ ... ]
> Fixes: 40d133d7f542 ("usb: gadget: f_ncm: convert to new function interface with backward compatibility")
> Reported-by: syzbot+85ede281798faf736677@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=85ede281798faf736677
> Assisted-by: Claude:claude-opus-5-5
> Signed-off-by: Nicholas Velten <nicholasfvelten@gmail.com>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261014-fix-gadget-netdev-reregister-v1-1-0fb91999da06@gmail.com?part=1
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-14 11:23 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-14 11:06 [PATCH] usb: gadget: u_ether: refuse to re-register a failed net_device Nicholas Velten via B4 Relay
2026-10-14 11:23 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox