From: Kuniyuki Iwashima <kuniyu@google.com>
To: Stanislav Fomichev <sdf.kernel@gmail.com>
Cc: Naman Gulati <namangulati@google.com>,
"David S . Miller" <davem@davemloft.net>,
Eric Dumazet <edumazet@kernel.org>,
Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
Simon Horman <horms@kernel.org>,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
syzbot+1269fe6cc2016008124e@syzkaller.appspotmail.com
Subject: Re: [PATCH net] netdev-genl: ignore NETDEV_UNREGISTER rebroadcasts
Date: Tue, 27 Oct 2026 01:47:49 +0000 [thread overview]
Message-ID: <auABpyzeuUl2S3_W@google.com> (raw)
In-Reply-To: <at_TlVBS-5KVZAkg@devvm16445.scu0.facebook.com>
On Mon, 26 Oct 2026 15:28:44 -0700, Stanislav Fomichev wrote:
> On 10/26, Naman Gulati wrote:
> > netdev_wait_allrefs_any() re-sends NETDEV_UNREGISTER every second while
> > it waits for the last references on a device to be dropped. By then
> > netdev_run_todo() has already marked the device NETREG_UNREGISTERED and
> > RTNL has been dropped at least once since the initial notification sent
> > by unregister_netdevice_many_notify().
> >
> > netdev_genl_netdevice_event() does not tell these rebroadcasts apart
> > from the initial notification and sends a NETDEV_CMD_DEV_DEL_NTF
> > multicast for each of them. At best this spams NETDEV_NLGRP_MGMT
> > listeners with duplicate notifications; at worst the pernet state of
> > the netns the device belongs to is already gone and the handler
> > dereferences a NULL pointer.
> >
> > default_device_exit_batch() only unregisters the devices still listed
> > in the exiting netns; it does not wait for in-flight unregistrations of
> > devices that were already unlisted (the barrier doing that was removed
> > by commit 8a4fc54b07d7 ("net: get rid of rtnl_lock_unregistering()")).
> > So when a device is unregistered by something other than the
> > cleanup_net() of its own netns while references on it are still held,
> > e.g. a veth whose peer in another netns gets deleted, and that netns
> > exits while the device is stuck in netdev_wait_allrefs_any(), the
> > remaining pernet exit handlers run and genl_pernet_exit() sets
> > net->genl_sock to NULL. The next rebroadcast then crashes in
> > genl_has_listeners():
> >
> > BUG: KASAN: null-ptr-deref in netlink_has_listeners+0x3d/0x3f0 net/netlink/af_netlink.c:1388
> > Read of size 8 at addr 0000000000000578 by task syz.0.0/5325
> > Call Trace:
> > <TASK>
> > netlink_has_listeners+0x3d/0x3f0 net/netlink/af_netlink.c:1388
> > genl_has_listeners include/net/genetlink.h:644 [inline]
> > netdev_genl_dev_notify+0x161/0x450 net/core/netdev-genl.c:93
> > netdev_genl_netdevice_event+0x98/0x3c0 net/core/netdev-genl.c:1491
> > notifier_call_chain+0x1a5/0x3d0 kernel/notifier.c:85
> > netdev_wait_allrefs_any net/core/dev.c:11690 [inline]
> > netdev_run_todo+0x731/0x1060 net/core/dev.c:11808
> > rtnl_unlock net/core/rtnetlink.c:157 [inline]
> > rtnl_dellink+0x68f/0x810 net/core/rtnetlink.c:3707
> >
> > syzbot hit this by moving one end of a veth pair into a short-lived
> > netns while netdevsim's deferred FIB event processing still held a
> > reference on it, and then deleting the other end (repro [1]). While the
> > source of this bug is netdevsim deferring FIB processing for and holding
> > onto the device reference for O(seconds) which is being fixed
> > separately [2], any driver may introduce such a delay and trigger the
> > null-ptr-deref.
> >
> > Skip the rebroadcasts, which are the only NETDEV_UNREGISTER events
> > delivered with reg_state == NETREG_UNREGISTERED. The notifications sent
> > by unregister_netdevice_many_notify() and, for a device leaving a netns,
> > by __dev_change_net_namespace() are issued under RTNL in the same
> > critical section that unlists the device, before its netns can be torn
> > down, and keep being handled. This mirrors what ip6_route_dev_notify()
> > already does to cope with the rebroadcasts.
> >
> > This change should not break the UAPI spec as it defines dev-del-ntf as
> > a "Notification about device disappearing." which is a single event. The
> > rebroadcast in netdev_wait_allrefs_any() exists to re-kick in-kernel
> > subsystems holding references; netdev-genl happens to be on the notifier
> > chain and forwards it.
> >
> > [1] https://gist.github.com/NamanGulati/2d1b49b8757f9a88b0bd6e55018c02ae
> > [2] https://lore.kernel.org/r/20261023191517.607834-1-kuniyu@google.com
> >
> > Fixes: d3d854fd6a1d ("netdev-genl: create a simple family for netdev stuff")
> > Reported-by: syzbot+1269fe6cc2016008124e@syzkaller.appspotmail.com
> > Closes: https://lore.kernel.org/netdev/6adf9f64.6200f071.51519.0ed1.GAE@google.com/
> > Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
> > Signed-off-by: Naman Gulati <namangulati@google.com>
> > ---
> > Note that the reproducer attached to the syzbot bug targets a different
> > bug (via devlink_port_notify() on netns teardown) that happens to share
> > the same crash title, not the one in the original reported crash report.
> > ---
> > net/core/netdev-genl.c | 6 ++++++
> > 1 file changed, 6 insertions(+)
> >
> > diff --git a/net/core/netdev-genl.c b/net/core/netdev-genl.c
> > index 33b9f4eb9565a..2032ab9a864c2 100644
> > --- a/net/core/netdev-genl.c
> > +++ b/net/core/netdev-genl.c
> > @@ -1487,6 +1487,12 @@ static int netdev_genl_netdevice_event(struct notifier_block *nb,
> > netdev_unlock_full_to_ops(netdev);
> > break;
> > case NETDEV_UNREGISTER:
> > + /* netdev_wait_allrefs_any() rebroadcasts NETDEV_UNREGISTER
> > + * while waiting for the last references to be dropped; the
> > + * netns may already be torn down by then. Notify only once.
> > + */
>
> [..]
>
> > + if (READ_ONCE(netdev->reg_state) == NETREG_UNREGISTERED)
> > + break;
>
> Same as
> https://lore.kernel.org/netdev/20261026063743.1797-1-lege.wang@jaguarmicro.com/
> ?
>
> reg_state is protected by netdev, why not do this under netdev_lock?
> Also seems like we are fixing a symptom, not the problem?
fwiw, I suggested not to take the lock since we are only interested
in NETREG_UNREGISTERED here and there is a clear ordering in the case.
The root cause is netdevsim this time, and I have a fix,
https://syzkaller.appspot.com/text?tag=Patch&x=15923c21580000
but rebroadcast itself is not-ideal-but-valid behaviour, so each
NETDEV_UNREGISTER must be idempotent unless we can completley remove
the rebroadcast mechanism itself in the future.
>
> > netdev_lock(netdev);
> > netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_DEL_NTF);
> > netdev_unlock(netdev);
next prev parent reply other threads:[~2026-10-27 1:47 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-26 22:13 [PATCH net] netdev-genl: ignore NETDEV_UNREGISTER rebroadcasts Naman Gulati
2026-10-26 22:28 ` Stanislav Fomichev
2026-10-26 23:27 ` Naman Gulati
2026-10-27 1:47 ` Kuniyuki Iwashima [this message]
2026-10-28 16:37 ` Stanislav Fomichev
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=auABpyzeuUl2S3_W@google.com \
--to=kuniyu@google.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=namangulati@google.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sdf.kernel@gmail.com \
--cc=syzbot+1269fe6cc2016008124e@syzkaller.appspotmail.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.