summaryrefslogtreecommitdiff
path: root/net/core/rtnetlink.c
AgeCommit message (Collapse)Author
7 daysnet: add AF_PACKET multicast dumpsYuyang Huang
RTM_GETMULTICAST dumps IPv4 and IPv6 multicast group memberships, but the device multicast list (dev->mc) is only available through /proc/net/dev_mcast, so "ip maddr show" still has to parse procfs for its link-layer entries. Handle RTM_GETMULTICAST dumps with ifa_family set to AF_PACKET next to the dev->mc helpers in dev_addr_lists.c and report every entry of dev->mc in the existing ifaddrmsg format: - IFA_MULTICAST carries the raw link-layer address - IFA_MC_USERS carries the entry reference count - IFA_F_GLOBAL in IFA_FLAGS reports netdev_hw_addr::global_use, set by dev_mc_add_global() (SIOCADDMULTI) and dev_mc_add_excl() ("bridge fdb add ... self"), i.e. entries added explicitly rather than by a protocol join. This is the static column of /proc/net/dev_mcast - ifa_scope is RT_SCOPE_LINK This covers every column of /proc/net/dev_mcast. AF_PACKET is the family iproute2 already uses for link-layer addresses ("ip -0"). The default FDB dump also walks dev->mc, but only for Ethernet devices and only if the driver uses it, vxlan for example does not, and it has no users count or global_use bit. Extending it would change "bridge fdb show" output and add NDA_* attributes. Requests are always validated, there are no legacy users: prefixlen, flags and scope must be zero, ifa_index selects one device and IFA_TARGET_NETNSID is the only attribute accepted. The dump runs under RCU and netif_addr_lock_bh() without RTNL. cb->seq is set from the dev->mc generation counter and dev_base_seq before each round and checked after it, so an entry added or removed since the previous round sets NLM_F_DUMP_INTR. A round without a message skips the check and cb->seq is set once more after the round, so the NLMSG_DONE check reports a change made during the last round or before an empty one. Signed-off-by: Yuyang Huang <sigefriedhyy@gmail.com> Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Link: https://patch.msgid.link/20261012011707.3378-5-sigefriedhyy@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
8 daysrtnetlink: comment the RCU waits in unregister pathsAndrea Parri
rtnl_unregister_all() and rtnl_af_unregister() wait for RCU readers before tearing down what those readers use, but do not say which readers they are waiting for. A missing wait is then easy to overlook: rtnl_link_unregister() lacked its synchronize_rcu() until commit 3b70edea393d ("rtnetlink: wait for RCU readers in rtnl_link_unregister()"). Add a comment to both waits, naming the readers each one waits for. Suggested-by: Eric Dumazet <edumazet@kernel.org> Link: https://lore.kernel.org/CAL4WiioFMQN4troVjQjCmE6Z9kwwb95SnoEupjD=PPSK6Q5f6w@mail.gmail.com Assisted-by: LLM Signed-off-by: Andrea Parri <parri.andrea@gmail.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20261015081723.404990-1-parri.andrea@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-10-06net: Rename dev_isalive() to netif_is_alive().Kuniyuki Iwashima
The next patch needs to use dev_isalive() in xfrm. We should try to avoid using the dev_ prefix on APIs we export via include/linux/. Let's move it to include/linux/netdevice.h and rename to netif_is_alive(). Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Tested-by: Chris J Arges <carges@cloudflare.com> Link: https://patch.msgid.link/20261001204752.2572265-4-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-10-05rtnetlink: wait for RCU readers in rtnl_link_unregister()Andrea Parri
rtnl_link_ops_get() finds ops on link_ops under rcu_read_lock() and only then takes ops->srcu. rtnl_link_unregister() unlinks ops, then calls synchronize_srcu() and cleanup_srcu_struct() without first waiting for RCU readers. A reader that found ops before list_del_rcu() and has not yet taken ops->srcu is not waited for. Such a reader then locks a cleaned-up srcu_struct and keeps using ops after the module that owns it is gone. rtnl_newlink() and rtnl_dump_ifinfo() both look up ops without RTNL, the latter for any user that dumps links filtered by kind. With delays added between the lookup and srcu_read_lock() in rtnl_link_ops_get(), and before rtnl_link_ops_put() in rtnl_dump_ifinfo(), running "ip link show type dummy" alongside "rmmod dummy" on a KASAN kernel gives: BUG: KASAN: vmalloc-out-of-bounds in __srcu_read_unlock+0x57/0x70 Read of size 8 at addr ffffffffc02ff318 by task ip/147 Call Trace: __srcu_read_unlock+0x57/0x70 rtnl_dump_ifinfo.cold+0x30/0x3b rtnl_dumpit+0x7a/0x1b0 netlink_dump+0x486/0x11b0 __netlink_dump_start+0x661/0x910 rtnetlink_rcv_msg+0x611/0x9e0 netlink_rcv_skb+0x126/0x380 netlink_unicast+0x605/0x830 netlink_sendmsg+0x6d0/0xbb0 __sys_sendto+0x335/0x3a0 Call synchronize_rcu() before synchronize_srcu(), as rtnl_af_unregister() already does. This should be enough because rtnl_link_ops_get() is the only RCU walker of link_ops, and it takes ops->srcu before rcu_read_unlock(), so every reader that found ops is covered by synchronize_srcu() once the RCU grace period ends. The extra grace period only costs time at module unload. Readers and the writer were serialized by RTNL until link_ops got its own mutex, which is why the missing RCU wait did not matter before. Cc: stable+noautosel@kernel.org # needs real net-admin (non-ns) Fixes: 6b57ff21a310 ("rtnetlink: Protect link_ops by mutex.") Reviewed-by: Eric Dumazet <edumazet@kernel.org> Signed-off-by: Andrea Parri <parri.andrea@gmail.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20261001143040.28467-1-parri.andrea@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-14net: rtnetlink: add pacing_offload attribute to net_deviceWillem de Bruijn
Add a new flag to administratively control pacing offload. The feature is disabled by default. That does not cause regressions, as no driver advertises max_pacing_offload_horizon yet. Also add NLA_REJECT for max_pacing_offload_horizon, in line with other such read-only members of link-attrs. Both fields can be read with ynl --family rt-link --do getlink \ --json '{"ifname": "eth0"}' | grep pacing And pacing offload enabled with ynl --family rt-link --do setlink \ --json '{"ifname": "eth0", "pacing-offload": 1}' Signed-off-by: Willem de Bruijn <willemb@google.com> Link: https://patch.msgid.link/20260910171131.2532487-2-willemdebruijn.kernel@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-09-04net: reject oversized tx_queue_len at netlink parse timeJamal Hadi Salim
rtnl_create_link() assigns IFLA_TXQLEN directly to dev->tx_queue_len without going through netif_change_tx_queue_len(), so a device created with "ip link add ... txqueuelen 500000" bypasses the S16_MAX cap and still triggers the oversized ring allocations in pfifo_fast, tun and tap. The veth peer nest (rtnl_nla_parse_ifinfomsg()) and the RTM_NEWLINK-on-existing-device path reach the same sinks. Enforce the cap in ifla_policy instead: IFLA_TXQLEN becomes NLA_POLICY_FULL_RANGE(NLA_U32, &txqlen_range) with txqlen_range = { .min = 0, .max = S16_MAX }. All netlink consumers parse against this policy - rtnl_setlink(), rtnl_newlink() (create and change), and the veth peer nest - so every netlink path is capped at parse time and rejects the attribute with -ERANGE plus a proper "integer out of range" extack message before any device state is modified (the RTM_SETLINK half-application wart is gone with it). Document the bound in the rt-link.yaml netlink spec. Conditions to recreate the bug: - CONFIG_NET_SCHED=y, CONFIG_VETH=y, CONFIG_USER_NS=y, CONFIG_NET_NS=y. - Unprivileged user in a fresh user+net namespace (unshare -Urn): ip link add v0 txqueuelen 500000 type veth peer name v1 -> on the fixed kernel this is rejected with -ERANGE ("integer out of range" extack) instead of installing an oversized tx_queue_len that later inflates pfifo_fast/tun/tap ring allocations. - ip link set v0 txqueuelen 500000 is likewise rejected at parse time. Fixes: 38f7b870d4a6 ("[RTNETLINK]: Link creation API") Reported-by: Vega <vega@nebusec.ai> Tested-by: Victor Nogueira <victor@mojatatu.com> Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Link: https://patch.msgid.link/QDISC-2899.v2.20260901233641@mojatatu.com.2 Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-08-06rtnetlink: cap IFLA_VFINFO_LIST at a documented number of VFsArtem Lytkin
rtnl_fill_vf() emits one IFLA_VF_INFO per VF into the IFLA_VFINFO_LIST nest and closes it with nla_nest_end(), which stores the accumulated length into nla_len. That field is a u16, so a nest larger than 65535 bytes is written truncated modulo 65536. The list dates back to commit c02db8c6290b ("rtnetlink: make SR-IOV VF interface symmetric") in 2010 and has never been able to describe an arbitrary number of VFs; nothing regressed, the encoding simply cannot represent it. Nothing catches it on the way. if_nlmsg_size() adds rtnl_vfinfo_size() for every VF, so the skb really is large enough and none of the nla_put() calls fails. Userspace then walks the message with RTA_NEXT(), which advances by the stored length, so parsing resumes inside VF payload and the attributes after the nest are read out of VF data: IFLA_VF_PORTS, IFLA_XDP, IFLA_LINKINFO, IFLA_PERM_ADDRESS, IFLA_AF_SPEC. iproute2 prints "!!!Deficit" and strictly validating parsers reject the message. On CONFIG_DEBUG_NET kernels nla_nest_end() also splats, via the DEBUG_NET_WARN_ON_ONCE() added in commit ff205bf8c554 ("netlink: add one debug check in nla_nest_end()"). Where the wrap falls depends on what was asked for and on the host. A VF costs 196 bytes, 296 with statistics, 236 with GUIDs and 336 with both, and on a kernel without CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS the statistics carry a padding attribute each and cost 32 bytes more, making those two 328 and 368. The nest therefore overflows somewhere between 179 and 335 VFs, and ice allows 256 per PF (ICE_MAX_SRIOV_VFS), which reaches it. Statistics are included unless the request sets RTEXT_FILTER_SKIP_STATS, so the common case is the one that wraps first. A limit that moves with the requested attribute set and with the host's alignment requirements is not something userspace can be told, so use fixed numbers instead and document them as what the interface supports: 256 VFs, or 128 when statistics are included. Both stay well inside U16_MAX even in the largest per-VF encoding, at 60416 and 47104 bytes respectively. rtnl_vfinfo_cap() applies the cap in both places, so rtnl_vfinfo_size() does not size the skb for VFs that will not be emitted. A device with more VFs than the limit reports a shorter IFLA_VFINFO_LIST. IFLA_NUM_VF keeps carrying the real count, and everything after the nest stays parsable, which is the part that is broken today. An empty nest is already emitted for a PF with no VFs, so a list shorter than IFLA_NUM_VF is not a new encoding. Returning -EMSGSIZE instead, which is what nla_nest_end_safe() would give, is not an option here: a nest that does not fit in a u16 will not fit in a retried skb either, so it would turn a link dump on such a device into a hard failure. The other large nests in rtnl_fill_ifinfo() were audited and cannot overflow. IFLA_AF_SPEC is bounded by a handful of address families at about a kilobyte each, and IFLA_VF_PORTS would need more than 560 VFs, which no in-tree driver allows. Reported-by: Jacob Keller <jacob.e.keller@intel.com> Link: https://lore.kernel.org/netdev/16b289f6-b025-5dd3-443d-92d4c167e79c@intel.com/ Assisted-by: Claude:claude-fable-5 Signed-off-by: Artem Lytkin <iprintercanon@gmail.com> Link: https://patch.msgid.link/20260801114944.115272-1-iprintercanon@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-07-11net: Call unregister_netdevice_many() per netns.Kuniyuki Iwashima
For per-netns device unregistration, the list passed to unregister_netdevice_many() must contain devices from a single netns only (once all callers are converted). Let's move collected devices in the following functions to net->dev_unreg_head and let __rtnl_net_unlock() pass them to unregister_netdevice_many(). * default_device_exit_batch() * ops_exit_rtnl_list() * __rtnl_kill_links() This allows incremental conversion of each driver to support per-netns device unregistration without affecting the normal kernel where CONFIG_DEBUG_NET_SMALL_RTNL is disabled. Note that this change unbatches synchronize_rcu() etc in unregister_netdevice_many(), but we can later split it into multiple stages to batch them again. Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260703001009.1572444-8-kuniyu@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-07-11net: Add per-netns netdev unregistration infra.Kuniyuki Iwashima
When we need to unregister a netdev in a different netns, we will delegate its unregistration to per-netns work. There are three types of such cross-netns devices: 1. Paired devices (e.g., netkit, veth, vxcan) -> Unregistering one device also deletes its peer, which may reside in another netns. 2. Tunnel devices (e.g., bareudp, geneve, etc) -> Destroying a netns removes devices in another netns if their backend sockets reside in the dying netns 3. Stacked devices (e.g., ipvlan, macvlan, etc) -> Removing the lower device also removes multiple upper devices, each of which may reside in different namespaces. In these cases, we will use unregister_netdevice_queue_net() to queue such potential cross-netns devices for destruction. Each driver must not call both unregister_netdevice_queue_net() and unregister_netdevice_queue() for the same device. See the subsequent veth/bareudp/ipvlan patches for how they avoid double queueing. unregister_netdevice_queue_net() takes net and dev. If dev resides in the net, it simply calls unregister_netdevice_queue(). If dev_net(dev) is different from the net, it enqueues the device to dev_net(dev)->dev_unreg_head and schedules the per-netns work. When __rtnl_net_unlock() is called from the per-netns work (or another thread already holding the lock), unregister_netdevice_many_net() collects the queued devices and calls unregister_netdevice_many() to perform the actual unregistration. During netns dismantle, rtnl_net_flush_workqueue() is called at the end of default_device_exit_batch() to ensure that cross-netns devices in the other alive netns are unregistered. Once RTNL is removed, a device could be moved to another netns while being queued to net->dev_unreg_head. __dev_change_net_namespace() handles this race by acquiring net->dev_unreg_lock of both the old and new netns after dev_set_net() and moving the device between their dev_unreg_head lists. Since dev_set_net() and unregister_netdevice_queue_net() are synchronised by netdev_lock(), the device is either queued to the old netns's dev_unreg_head and then moved, or queued directly to the new netns. Note that unregister_netdevice_move_net() does not need to call rtnl_net_queue_work() because __dev_change_net_namespace() is (supposed to be) called with rtnl_net_lock(). (Not all callers hold it yet, but the race does not happen until all callers are converted and RTNL is removed.) Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260703001009.1572444-7-kuniyu@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-07-11rtnetlink: Add per-netns rtnl_work.Kuniyuki Iwashima
The biggest blocker to per-netns RTNL is netdev unregistration. It starts within a single netns (e.g., during a device lookup or netns dismantle), but it can eventually involve multiple namespaces, such as when upper ipvlan devices reside in different netns. This prevents us from acquiring multiple rtnl_net_lock()s beforehand. When we encounter such a cross-netns device, we must delegate the unregistration to the work of the netns where the device actually resides. Let's add per-netns rtnl_work to support the deferred netdev unregistration. Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260703001009.1572444-4-kuniyu@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-07-11rtnetlink: Call unregister_netdevice_many() only once in rtnl_link_unregister().Kuniyuki Iwashima
When rtnl_link_unregister() is called during module unload, it calls __rtnl_kill_links() for every netns. __rtnl_kill_links() collects all devices of the unloaded module and passes them to unregister_netdevice_many(). Let's move unregister_netdevice_many() to rtnl_link_unregister() to unregister all devices across netns in a single batch. Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260703001009.1572444-3-kuniyu@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-07-11rtnetlink: Lock sock_net(skb->sk) in rtnl_newlink().Kuniyuki Iwashima
There are a few cases where rtnl_net_lock() is not properly held in rtnl_newlink(). When either of IFLA_NET_NS_PID / IFLA_NET_NS_FD / IFLA_TARGET_NETNSID is specified but IFLA_LINK_NETNSID is not, sock_net(skb->sk) is used as link_net in rtnl_newlink_link_net(). In addition, the do_setlink() path uses sock_net(skb->sk) and one from the three netns attributes while rtnl_link_get_net_capable() returns only one of four. Let's add sock_net(skb->sk) to rtnl_nets in rtnl_newlink(). Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260703001009.1572444-2-kuniyu@google.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-07-07net: rtnetlink: take instance lock inside rtnl_configure_linkStanislav Fomichev
rtnl_configure_link calls __dev_change_flags() and __dev_notify_flags, both need the instance lock. rtnl_newlink_create grabs it but stacked devices do not. Move the lock inside rtnl_configure_link. Signed-off-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20260702224150.3730033-5-sdf@fomichev.me Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-06-17net: ip_gre: require CAP_NET_ADMIN in the device netns for changelinkMaoyi Xie
A tunnel changelink() operates on at most two netns, dev_net(dev) and the tunnel link netns t->net. They differ once the device is created in or moved to a netns other than the one the request runs in. The rtnl changelink path checks CAP_NET_ADMIN only against dev_net(dev), so a caller privileged there but not in t->net can rewrite a tunnel that lives in t->net. Add rtnl_dev_link_net_capable() next to rtnl_get_net_ns_capable() in net/core/rtnetlink.c. It requires CAP_NET_ADMIN in the link netns and is skipped when the link netns is dev_net(dev), where the rtnl path already checked it. The other patches in this series use the same helper. Gate ipgre_changelink() and erspan_changelink() with it, at the top of the op before any attribute is parsed, because the parsers update live tunnel fields first. ipgre_netlink_parms() sets t->collect_md before ip_tunnel_changelink() runs. Commit 8b484efd5cb4 ("ip6: vti: Use ip6_tnl.net in vti6_siocdevprivate().") added the same check on the ioctl path. This adds it on RTM_NEWLINK. Reported-by: Xiao Liang <shaw.leon@gmail.com> Closes: https://lore.kernel.org/netdev/CABAhCOSzP1vaThGV35_VnsRCb=87_CPjPVsTHbq905k8A+BuUg@mail.gmail.com/ Fixes: b57708add314 ("gre: add x-netns support") Cc: stable@vger.kernel.org Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260612085941.3158249-2-maoyixie.tju@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-06-04rtnetlink: use dev_isalive() in rtnl_getlink()Eric Dumazet
rtnl_getlink() uses an RCU lookup to get the netdevice pointer. When/If rtnl_lock() is used, we should check if the netdevice is not being dismantled before potentially perform illegal actions. Move dev_isalive() out of net/core/net-sysfs.c and make it available in net/core/dev.h. Return -ENODEV if rtnl_getlink() finds a device which is currently being dismantled and RTNL is requested. Fixes: e896e5c0734b ("rtnetlink: do not acquire RTNL in rtnl_getlink() with RTEXT_FILTER_NAME_ONLY") Signed-off-by: Eric Dumazet <edumazet@google.com> Suggested-by: Jakub Kicinski <kuba@kernel.org> Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev> Link: https://patch.msgid.link/20260603180831.1024716-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-26rtnetlink: add RTEXT_FILTER_NAME_ONLY support to rtnl_dump_ifinfo()Eric Dumazet
When user requests RTEXT_FILTER_NAME_ONLY flag, we limit the dump parts to: - struct nlmsghdr - IFLA_IFNAME - IFLA_PROP_LIST (alternate names) - This saves space in the dump, pushing more devices per system call. - This can be done without acquiring RTNL. I still have a medium term goal to avoid RTNL in rtnl_dump_ifinfo() regardless of RTEXT_FILTER_NAME_ONLY being used. Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260525083542.1565964-6-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-26rtnetlink: do not assume RTNL is held in link_master_filtered()Eric Dumazet
RTNL might be no longer held by the caller in the following patch. Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260525083542.1565964-5-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-26rtnetlink: do not acquire RTNL in rtnl_getlink() with RTEXT_FILTER_NAME_ONLYEric Dumazet
When RTEXT_FILTER_NAME_ONLY is requested, rtnl_fill_ifinfo() is dumping device attributes which do not need RTNL protection. Many shell scripts invoke iproute2 commands specifying a device by its name. After this patch, they will no longer add RTNL pressure. Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260525083542.1565964-4-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-26rtnetlink: use nla_nest_end_safe() in rtnl_fill_prop_list()Eric Dumazet
Avoid corrupting a netlink message and confuse user space in the very unlikely case rtnl_fill_prop_list was able to produce a very big nested element. This is extremely unlikely, because rtnl_prop_list_size() provisions nla_total_size(ALTIFNAMSIZ) per altname. Signed-off-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/20260525083542.1565964-2-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-22dpll: change dpll_netdev_pin_handle_size() to assume DPLL_A_PIN_ID will be usedEric Dumazet
We plan to no longer hold RTNL in "ip link show", and use RCU instead. Assume rtnl_fill_dpll_pin() will have to fill DPLL_A_PIN_ID. It is fine to over-estimate skb size (by 8 bytes) in if_nlmsg_size(). Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev> Link: https://patch.msgid.link/20260521171440.114956-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-22rtnetlink: do not use RTNL in rtnl_af_register() and rtnl_af_unregister()Eric Dumazet
rtnl_af_lookup() does not rely on RTNL anymoe, remove the stale ASSERT_RTNL(). Add a private spinlock (rtnl_af_ops_lock) to protect rtnl_af_ops list instead of using RTNL. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260521174038.204481-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-21Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-7.1-rc5). No conflicts, adjacent changes: drivers/net/ethernet/mellanox/mlx5/core/en_txrx.c cc199cd1b912 ("net/mlx5e: Reduce branches in napi poll") c326f9c68921 ("net/mlx5e: xsk: Fix unlocked writing to ICOSQ") drivers/net/ethernet/mellanox/mlx5/core/eswitch.c c6df9a65cbb0 ("net/mlx5: Skip disabled vports when setting max TX speed") 1fba57c91416 ("net/mlx5: Add VHCA_ID page management mode support") net/mac80211/mlme.c a6e6ccd5bd07 ("wifi: mac80211: consume only present negotiated TTLM maps") 49e62ec6eb06 ("wifi: mac80211: move frame RX handling to type files") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-21net: bridge: prevent too big nested attributes in br_fill_linkxstats()Eric Dumazet
After commit ff205bf8c554 ("netlink: add one debug check in nla_nest_end()") syzbot found that br_fill_linkxstats() can send corrupted netlink packets. Make sure the nested attribute size is bounded. Fixes: a60c090361ea ("bridge: netlink: export per-vlan stats") Reported-by: syzbot+a35f9259d08f907c06e6@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6a0b0da3.050a0220.175f0c.0000.GAE@google.com/ Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Acked-by: Nikolay Aleksandrov <razor@blackwall.org> Link: https://patch.msgid.link/20260520114207.1394241-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-14bridge: uapi: Add neigh_forward_grat netlink attributesDanielle Ratson
Add netlink attributes for controlling gratuitous ARP and unsolicited NA forwarding when neighbor suppression is enabled. Add IFLA_BRPORT_NEIGH_FORWARD_GRAT for port-level control and BRIDGE_VLANDB_ENTRY_NEIGH_FORWARD_GRAT for per-VLAN control. The new attributes provide independent control of gratuitous ARP and unsolicited NA packets. Operators can enable forwarding for those packets for fast mobility across VTEPs while keeping general neighbor suppression active. Reviewed-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Danielle Ratson <danieller@nvidia.com> Link: https://patch.msgid.link/20260511065936.4173106-2-danieller@nvidia.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-05-12rtnetlink: add RTEXT_FILTER_NAME_ONLY supportEric Dumazet
iproute2 can spend considerable amount of time in ll_init_map() or ll_link_get() to dump verbose netdev attributes, contributing to RTNL pressure. Add RTEXT_FILTER_NAME_ONLY new flag so that rtnl_fill_ifinfo() limits its output to: - struct nlmsghdr - IFLA_IFNAME - IFLA_PROP_LIST (alternate names) We can later avoid using RTNL when RTEXT_FILTER_NAME_ONLY is requested, as none of these attributes need RTNL. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260511070244.971028-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-05-01net: rtnetlink: zero ifla_vf_broadcast to avoid stack infoleak in ↵Kai Zen
rtnl_fill_vfinfo rtnl_fill_vfinfo() declares struct ifla_vf_broadcast on the stack without initialisation: struct ifla_vf_broadcast vf_broadcast; The struct contains a single fixed 32-byte field: /* include/uapi/linux/if_link.h */ struct ifla_vf_broadcast { __u8 broadcast[32]; }; The function then copies dev->broadcast into it using dev->addr_len as the length: memcpy(vf_broadcast.broadcast, dev->broadcast, dev->addr_len); On Ethernet devices (the overwhelming majority of SR-IOV NICs) dev->addr_len is 6, so only the first 6 bytes of broadcast[] are written. The remaining 26 bytes retain whatever was previously on the kernel stack. The full struct is then handed to userspace via: nla_put(skb, IFLA_VF_BROADCAST, sizeof(vf_broadcast), &vf_broadcast) leaking up to 26 bytes of uninitialised kernel stack per VF per RTM_GETLINK request, repeatable. The other vf_* structs in the same function are explicitly zeroed for exactly this reason - see the memset() calls for ivi, vf_vlan_info, node_guid and port_guid a few lines above. vf_broadcast was simply missed when it was added. Reachability: any unprivileged local process can open AF_NETLINK / NETLINK_ROUTE without capabilities and send RTM_GETLINK with an IFLA_EXT_MASK attribute carrying RTEXT_FILTER_VF. The kernel walks each VF and emits IFLA_VF_BROADCAST, leaking 26 bytes of stack per VF per request. Stack residue at this call site can include return addresses and transient sensitive data; KASAN with stack instrumentation, or KMSAN, will flag the nla_put() when reproduced. Zero the on-stack struct before the partial memcpy, matching the existing pattern used for the other vf_* structs in the same function. Fixes: 75345f888f70 ("ipoib: show VF broadcast address") Cc: stable@vger.kernel.org Signed-off-by: Kai Zen <kai.aizen.dev@gmail.com> Link: https://patch.msgid.link/3c506e8f936e52b57620269b55c348af05d413a2.1777557228.git.kai.aizen.dev@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-04-21net: introduce ndo_set_rx_mode_async and netdev_rx_mode_workStanislav Fomichev
Add ndo_set_rx_mode_async callback that drivers can implement instead of the legacy ndo_set_rx_mode. The legacy callback runs under the netif_addr_lock spinlock with BHs disabled, preventing drivers from sleeping. The async variant runs from a work queue with rtnl_lock and netdev_lock_ops held, in fully sleepable context. When __dev_set_rx_mode() sees ndo_set_rx_mode_async, it schedules netdev_rx_mode_work instead of calling the driver inline. The work function takes two snapshots of each address list (uc/mc) under the addr_lock, then drops the lock and calls the driver with the work copies. After the driver returns, it reconciles the snapshots back to the real lists under the lock. Add netif_rx_mode_sync() to opportunistically execute the pending workqueue update inline, so that rx mode changes are committed before returning to userspace: - dev_change_flags (SIOCSIFFLAGS / RTM_NEWLINK) - dev_set_promiscuity - dev_set_allmulti - dev_ifsioc SIOCADDMULTI / SIOCDELMULTI - do_setlink (RTM_SETLINK) Note that some deep hierarchies still do skip the lower updates via: - dev_uc_sync - dev_mc_sync If we do end up hitting user-visible issues, we can add more calls to netif_rx_mode_sync in specific places. But hopefully we should not, the actual user-visible lists are still synced, it's that just HW state that might be lagging. Signed-off-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20260416185712.2155425-3-sdf@fomichev.me Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2026-04-03rtnetlink: add missing netlink_ns_capable() check for peer netnsNikolaos Gkarlis
rtnl_newlink() lacks a CAP_NET_ADMIN capability check on the peer network namespace when creating paired devices (veth, vxcan, netkit). This allows an unprivileged user with a user namespace to create interfaces in arbitrary network namespaces, including init_net. Add a netlink_ns_capable() check for CAP_NET_ADMIN in the peer namespace before allowing device creation to proceed. Fixes: 81adee47dfb6 ("net: Support specifying the network namespace upon device creation.") Signed-off-by: Nikolaos Gkarlis <nickgarlis@gmail.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20260402181432.4126920-1-nickgarlis@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-03-24rtnetlink: fix leak of SRCU struct in rtnl_link_registerSabrina Dubroca
Commit 6b57ff21a310 ("rtnetlink: Protect link_ops by mutex.") swapped the EEXIST check with the init_srcu_struct, but didn't add cleanup of the SRCU struct we just allocated in case of error. Fixes: 6b57ff21a310 ("rtnetlink: Protect link_ops by mutex.") Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/e77fe499f9a58c547b33b5212b3596dad417cec6.1774025341.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-03-20rtnetlink: count IFLA_INFO_SLAVE_KIND in if_nlmsg_sizeSabrina Dubroca
rtnl_link_get_slave_info_data_size counts IFLA_INFO_SLAVE_DATA, but rtnl_link_slave_info_fill adds both IFLA_INFO_SLAVE_DATA and IFLA_INFO_SLAVE_KIND. Fixes: ba7d49b1f0f8 ("rtnetlink: provide api for getting and setting slave info") Reviewed-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/049843b532e23cde7ddba263c0bbe35ba6f0d26d.1773919462.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-03-20rtnetlink: count IFLA_PARENT_DEV_{NAME,BUS_NAME} in if_nlmsg_sizeSabrina Dubroca
Commit 00e77ed8e64d ("rtnetlink: add IFLA_PARENT_[DEV|DEV_BUS]_NAME") added those attributes to rtnl_fill_ifinfo, but forgot to extend if_nlmsg_size. Fixes: 00e77ed8e64d ("rtnetlink: add IFLA_PARENT_[DEV|DEV_BUS]_NAME") Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/0b849da95562af45487080528d60f578636aba5c.1773919462.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-02-21Convert 'alloc_obj' family to use the new default GFP_KERNEL argumentLinus Torvalds
This was done entirely with mindless brute force, using git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' | xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/' to convert the new alloc_obj() users that had a simple GFP_KERNEL argument to just drop that argument. Note that due to the extreme simplicity of the scripting, any slightly more complex cases spread over multiple lines would not be triggered: they definitely exist, but this covers the vast bulk of the cases, and the resulting diff is also then easier to check automatically. For the same reason the 'flex' versions will be done as a separate conversion. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-02-21treewide: Replace kmalloc with kmalloc_obj for non-scalar typesKees Cook
This is the result of running the Coccinelle script from scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to avoid scalar types (which need careful case-by-case checking), and instead replace kmalloc-family calls that allocate struct or union object instances: Single allocations: kmalloc(sizeof(TYPE), ...) are replaced with: kmalloc_obj(TYPE, ...) Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...) are replaced with: kmalloc_objs(TYPE, COUNT, ...) Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...) are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...) (where TYPE may also be *VAR) The resulting allocations no longer return "void *", instead returning "TYPE *". Signed-off-by: Kees Cook <kees@kernel.org>
2025-11-04rtnetlink: honor RTEXT_FILTER_SKIP_STATS in IFLA_STATSAdrian Moreno
Gathering interface statistics can be a relatively expensive operation on certain systems as it requires iterating over all the cpus. RTEXT_FILTER_SKIP_STATS was first introduced [1] to skip AF_INET6 statistics from interface dumps and it was then extended [2] to also exclude IFLA_VF_INFO. The semantics of the flag does not seem to be limited to AF_INET or VF statistics and having a way to query the interface status (e.g: carrier, address) without retrieving its statistics seems reasonable. So this patch extends the use RTEXT_FILTER_SKIP_STATS to also affect IFLA_STATS. [1] https://lore.kernel.org/all/20150911204848.GC9687@oracle.com/ [2] https://lore.kernel.org/all/20230611105108.122586-1-gal@nvidia.com/ Signed-off-by: Adrian Moreno <amorenoz@redhat.com> Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com> Reviewed-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Link: https://patch.msgid.link/20251103154006.1189707-1-amorenoz@redhat.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-10-16rtnetlink: Allow deleting FDB entries in user namespaceJohannes Wiesböck
Creating FDB entries is possible from a non-initial user namespace when having CAP_NET_ADMIN, yet, when deleting FDB entries, processes receive an EPERM because the capability is always checked against the initial user namespace. This restricts the FDB management from unprivileged containers. Drop the netlink_capable check in rtnl_fdb_del as it was originally dropped in c5c351088ae7 and reintroduced in 1690be63a27b without intention. This patch was tested using a container on GyroidOS, where it was possible to delete FDB entries from an unprivileged user namespace and private network namespace. Fixes: 1690be63a27b ("bridge: Add vlan support to static neighbors") Reviewed-by: Michael Weiß <michael.weiss@aisec.fraunhofer.de> Tested-by: Harshal Gohel <hg@simonwunderlich.de> Signed-off-by: Johannes Wiesböck <johannes.wiesboeck@aisec.fraunhofer.de> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org> Link: https://patch.msgid.link/20251015201548.319871-1-johannes.wiesboeck@aisec.fraunhofer.de Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-09-29net: rtnetlink: fix typo in rtnl_unregister_all() commentAlok Tiwari
Corrected "rtnl_unregster()" -> "rtnl_unregister()" in the documentation comment of "rtnl_unregister_all()" Signed-off-by: Alok Tiwari <alok.a.tiwari@oracle.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20250929085418.49200-1-alok.a.tiwari@oracle.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-09-19rtnetlink: add needed_{head,tail}room attributesAlasdair McWilliam
Various network interface types make use of needed_{head,tail}room values to efficiently reserve buffer space for additional encapsulation headers, such as VXLAN, Geneve, IPSec, etc. However, it is not currently possible to query these values in a generic way. Introduce ability to query the needed_{head,tail}room values of a network device via rtnetlink, such that applications that may wish to use these values can do so. For example, Cilium agent iterates over present devices based on user config (direct routing, vxlan, geneve, wireguard etc.) and in future will configure netkit in order to expose the needed_{head,tail}room into K8s pods. See b9ed315d3c4c ("netkit: Allow for configuring needed_{head,tail}room"). Suggested-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Alasdair McWilliam <alasdair@mcwilliam.dev> Reviewed-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://patch.msgid.link/20250917095543.14039-1-alasdair@mcwilliam.dev Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-07-18net: s/dev_get_flags/netif_get_flags/Stanislav Fomichev
Commit cc34acd577f1 ("docs: net: document new locking reality") introduced netif_ vs dev_ function semantics: the former expects locked netdev, the latter takes care of the locking. We don't strictly follow this semantics on either side, but there are more dev_xxx handlers now that don't fit. Rename them to netif_xxx where appropriate. Signed-off-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20250717172333.1288349-6-sdf@fomichev.me Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-07-18net: s/dev_get_port_parent_id/netif_get_port_parent_id/Stanislav Fomichev
Commit cc34acd577f1 ("docs: net: document new locking reality") introduced netif_ vs dev_ function semantics: the former expects locked netdev, the latter takes care of the locking. We don't strictly follow this semantics on either side, but there are more dev_xxx handlers now that don't fit. Rename them to netif_xxx where appropriate. Signed-off-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20250717172333.1288349-2-sdf@fomichev.me Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-07-02net: dst: annotate data-races around dst->lastuseEric Dumazet
(dst_entry)->lastuse is read and written locklessly, add corresponding annotations. Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com> Link: https://patch.msgid.link/20250630121934.3399505-4-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-06-05net: prevent a NULL deref in rtnl_create_link()Eric Dumazet
At the time rtnl_create_link() is running, dev->netdev_ops is NULL, we must not use netdev_lock_ops() or risk a NULL deref if CONFIG_NET_SHAPER is defined. Use netif_set_group() instead of dev_set_group(). RIP: 0010:netdev_need_ops_lock include/net/netdev_lock.h:33 [inline] RIP: 0010:netdev_lock_ops include/net/netdev_lock.h:41 [inline] RIP: 0010:dev_set_group+0xc0/0x230 net/core/dev_api.c:82 Call Trace: <TASK> rtnl_create_link+0x748/0xd10 net/core/rtnetlink.c:3674 rtnl_newlink_create+0x25c/0xb00 net/core/rtnetlink.c:3813 __rtnl_newlink net/core/rtnetlink.c:3940 [inline] rtnl_newlink+0x16d6/0x1c70 net/core/rtnetlink.c:4055 rtnetlink_rcv_msg+0x7cf/0xb70 net/core/rtnetlink.c:6944 netlink_rcv_skb+0x208/0x470 net/netlink/af_netlink.c:2534 netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline] netlink_unicast+0x75b/0x8d0 net/netlink/af_netlink.c:1339 netlink_sendmsg+0x805/0xb30 net/netlink/af_netlink.c:1883 sock_sendmsg_nosec net/socket.c:712 [inline] Reported-by: syzbot+9fc858ba0312b42b577e@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6840265f.a00a0220.d4325.0009.GAE@google.com/T/#u Signed-off-by: Eric Dumazet <edumazet@google.com> Fixes: 7e4d784f5810 ("net: hold netdev instance lock during rtnetlink operations") Acked-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20250604105815.1516973-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-05-27rtnetlink: do_setlink: Use struct sockaddr_storageKees Cook
Instead of a heap allocating a variably sized struct sockaddr and lying about the type in the call to netif_set_mac_address(), use a stack allocated struct sockaddr_storage. This lets us drop the cast and avoid the allocation. Putting "ss" on the stack means it will get a reused stack slot since it is the same size (128B) as other existing single-scope stack variables, like the vfinfo array (128B), so no additional stack space is used by this function. Acked-by: Gustavo A. R. Silva <gustavoars@kernel.org> Signed-off-by: Kees Cook <kees@kernel.org> Link: https://patch.msgid.link/20250521204619.2301870-7-kees@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2025-05-27net: core: Switch netif_set_mac_address() to struct sockaddr_storageKees Cook
In order to avoid passing around struct sockaddr that has a size the compiler cannot reason about (nor track at runtime), convert netif_set_mac_address() to take struct sockaddr_storage. This is just a cast conversion, so there is are no binary changes. Following patches will make actual allocation changes. Acked-by: Gustavo A. R. Silva <gustavoars@kernel.org> Signed-off-by: Kees Cook <kees@kernel.org> Link: https://patch.msgid.link/20250521204619.2301870-2-kees@kernel.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2025-04-21net: Use nlmsg_payload in rtnetlink fileBreno Leitao
Leverage the new nlmsg_payload() helper to avoid checking for message size and then reading the nlmsg data. Signed-off-by: Breno Leitao <leitao@debian.org> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://patch.msgid.link/20250417-nlmsg_v3-v1-2-9b09d9d7e61d@debian.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-04-17Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/netJakub Kicinski
Cross-merge networking fixes after downstream PR (net-6.15-rc3). No conflicts. Adjacent changes: tools/net/ynl/pyynl/ynl_gen_c.py 4d07bbf2d456 ("tools: ynl-gen: don't declare loop iterator in place") 7e8ba0c7de2b ("tools: ynl: don't use genlmsghdr in classic netlink") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-04-16net: don't try to ops lock uninitialized devsJakub Kicinski
We need to be careful when operating on dev while in rtnl_create_link(). Some devices (vxlan) initialize netdev_ops in ->newlink, so later on. Avoid using netdev_lock_ops(), the device isn't registered so we cannot legally call its ops or generate any notifications for it. netdev_ops_assert_locked_or_invisible() is safe to use, it checks registration status first. Reported-by: syzbot+de1c7d68a10e3f123bdd@syzkaller.appspotmail.com Fixes: 04efcee6ef8d ("net: hold instance lock during NETDEV_CHANGE") Acked-by: Stanislav Fomichev <sdf@fomichev.me> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://patch.msgid.link/20250415151552.768373-1-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-04-15rtnetlink: Use nlmsg_payload in valid_fdb_dump_strictBreno Leitao
Leverage the new nlmsg_payload() helper to avoid checking for message size and then reading the nlmsg data. Signed-off-by: Breno Leitao <leitao@debian.org> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://patch.msgid.link/20250414-nlmsg-v2-4-3d90cb42c6af@debian.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-04-14net: convert dev->rtnl_link_state to a boolJakub Kicinski
netdevice reg_state was split into two 16 bit enums back in 2010 in commit a2835763e130 ("rtnetlink: handle rtnl_link netlink notifications manually"). Since the split the fields have been moved apart, and last year we converted reg_state to a normal u8 in commit 4d42b37def70 ("net: convert dev->reg_state to u8"). rtnl_link_state being a 16 bitfield makes no sense. Convert it to a single bool, it seems very unlikely after 15 years that we'll need more values in it. We could drop dev->rtnl_link_ops from the conditions but feels like having it there more clearly points at the reason for this hack. Acked-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20250410014246.780885-1-kuba@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-04-08rtnetlink: Fix bad unlock balance in do_setlink().Kuniyuki Iwashima
When validate_linkmsg() fails in do_setlink(), we jump to the errout label and calls netdev_unlock_ops() even though we have not called netdev_lock_ops() as reported by syzbot. [0] Let's return an error directly in such a case. [0] WARNING: bad unlock balance detected! 6.14.0-syzkaller-12504-g8bc251e5d874 #0 Not tainted syz-executor814/5834 is trying to release lock (&dev_instance_lock_key) at: [<ffffffff89f41f56>] netdev_unlock include/linux/netdevice.h:2756 [inline] [<ffffffff89f41f56>] netdev_unlock_ops include/net/netdev_lock.h:48 [inline] [<ffffffff89f41f56>] do_setlink+0xc26/0x43a0 net/core/rtnetlink.c:3406 but there are no more locks to release! other info that might help us debug this: 1 lock held by syz-executor814/5834: #0: ffffffff900fc408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_lock net/core/rtnetlink.c:80 [inline] #0: ffffffff900fc408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_nets_lock net/core/rtnetlink.c:341 [inline] #0: ffffffff900fc408 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0xd68/0x1fe0 net/core/rtnetlink.c:4064 stack backtrace: CPU: 0 UID: 0 PID: 5834 Comm: syz-executor814 Not tainted 6.14.0-syzkaller-12504-g8bc251e5d874 #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 02/12/2025 Call Trace: <TASK> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120 print_unlock_imbalance_bug+0x185/0x1a0 kernel/locking/lockdep.c:5296 __lock_release kernel/locking/lockdep.c:5535 [inline] lock_release+0x1ed/0x3e0 kernel/locking/lockdep.c:5887 __mutex_unlock_slowpath+0xee/0x800 kernel/locking/mutex.c:907 netdev_unlock include/linux/netdevice.h:2756 [inline] netdev_unlock_ops include/net/netdev_lock.h:48 [inline] do_setlink+0xc26/0x43a0 net/core/rtnetlink.c:3406 rtnl_group_changelink net/core/rtnetlink.c:3783 [inline] __rtnl_newlink net/core/rtnetlink.c:3937 [inline] rtnl_newlink+0x1619/0x1fe0 net/core/rtnetlink.c:4065 rtnetlink_rcv_msg+0x80f/0xd70 net/core/rtnetlink.c:6955 netlink_rcv_skb+0x208/0x480 net/netlink/af_netlink.c:2534 netlink_unicast_kernel net/netlink/af_netlink.c:1313 [inline] netlink_unicast+0x7f8/0x9a0 net/netlink/af_netlink.c:1339 netlink_sendmsg+0x8c3/0xcd0 net/netlink/af_netlink.c:1883 sock_sendmsg_nosec net/socket.c:712 [inline] __sock_sendmsg+0x221/0x270 net/socket.c:727 ____sys_sendmsg+0x523/0x860 net/socket.c:2566 ___sys_sendmsg net/socket.c:2620 [inline] __sys_sendmsg+0x271/0x360 net/socket.c:2652 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xf3/0x230 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f8427b614a9 Code: 48 83 c4 28 c3 e8 37 17 00 00 0f 1f 80 00 00 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fff9b59f3a8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 00007fff9b59f578 RCX: 00007f8427b614a9 RDX: 0000000000000000 RSI: 0000200000000300 RDI: 0000000000000004 RBP: 00007f8427bd4610 R08: 000000000000000c R09: 00007fff9b59f578 R10: 000000000000001b R11: 0000000000000246 R12: 0000000000000001 R13: Fixes: 4c975fd70002 ("net: hold instance lock during NETDEV_REGISTER/UP") Reported-by: syzbot+45016fe295243a7882d3@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=45016fe295243a7882d3 Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> Acked-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20250407164229.24414-1-kuniyu@amazon.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2025-04-07net: hold instance lock during NETDEV_CHANGEStanislav Fomichev
Cosmin reports an issue with ipv6_add_dev being called from NETDEV_CHANGE notifier: [ 3455.008776] ? ipv6_add_dev+0x370/0x620 [ 3455.010097] ipv6_find_idev+0x96/0xe0 [ 3455.010725] addrconf_add_dev+0x1e/0xa0 [ 3455.011382] addrconf_init_auto_addrs+0xb0/0x720 [ 3455.013537] addrconf_notify+0x35f/0x8d0 [ 3455.014214] notifier_call_chain+0x38/0xf0 [ 3455.014903] netdev_state_change+0x65/0x90 [ 3455.015586] linkwatch_do_dev+0x5a/0x70 [ 3455.016238] rtnl_getlink+0x241/0x3e0 [ 3455.019046] rtnetlink_rcv_msg+0x177/0x5e0 Similarly, linkwatch might get to ipv6_add_dev without ops lock: [ 3456.656261] ? ipv6_add_dev+0x370/0x620 [ 3456.660039] ipv6_find_idev+0x96/0xe0 [ 3456.660445] addrconf_add_dev+0x1e/0xa0 [ 3456.660861] addrconf_init_auto_addrs+0xb0/0x720 [ 3456.661803] addrconf_notify+0x35f/0x8d0 [ 3456.662236] notifier_call_chain+0x38/0xf0 [ 3456.662676] netdev_state_change+0x65/0x90 [ 3456.663112] linkwatch_do_dev+0x5a/0x70 [ 3456.663529] __linkwatch_run_queue+0xeb/0x200 [ 3456.663990] linkwatch_event+0x21/0x30 [ 3456.664399] process_one_work+0x211/0x610 [ 3456.664828] worker_thread+0x1cc/0x380 [ 3456.665691] kthread+0xf4/0x210 Reclassify NETDEV_CHANGE as a notifier that consistently runs under the instance lock. Link: https://lore.kernel.org/netdev/aac073de8beec3e531c86c101b274d434741c28e.camel@nvidia.com/ Reported-by: Cosmin Ratiu <cratiu@nvidia.com> Tested-by: Cosmin Ratiu <cratiu@nvidia.com> Fixes: ad7c7b2172c3 ("net: hold netdev instance lock during sysfs operations") Signed-off-by: Stanislav Fomichev <sdf@fomichev.me> Link: https://patch.msgid.link/20250404161122.3907628-1-sdf@fomichev.me Signed-off-by: Jakub Kicinski <kuba@kernel.org>