From: Sven Eckelmann sven@narfation.org
Trying to dump the originators or the neighbors via netlink for a meshif with an inactive primary interface is not allowed. The dump functions were checking this correctly but they didn't handle non-existing primary interfaces and existing _inactive_ interfaces differently.
(Primary) batadv_hard_ifaces hold a references to a net_device. And accessing them is only allowed when either being in a RCU/spinlock protected section or when holding a valid reference to them. The netlink dump functions use the latter.
But because the missing specific error handling for inactive primary interfaces, the reference was never dropped. This reference counting error was only detected when the interface should have been removed from the system:
unregister_netdevice: waiting for batadv_slave_0 to become free. Usage count = 2
Cc: stable@vger.kernel.org Fixes: 6ecc4fd6c2f4 ("batman-adv: netlink: reduce duplicate code by returning interfaces") Reported-by: syzbot+881d65229ca4f9ae8c84@syzkaller.appspotmail.com Reported-by: Tetsuo Handa penguin-kernel@i-love.sakura.ne.jp Signed-off-by: Sven Eckelmann sven@narfation.org Signed-off-by: Simon Wunderlich sw@simonwunderlich.de --- net/batman-adv/originator.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c index a464ff96b9291..ed89d7fd1e7f4 100644 --- a/net/batman-adv/originator.c +++ b/net/batman-adv/originator.c @@ -764,11 +764,16 @@ int batadv_hardif_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb) bat_priv = netdev_priv(mesh_iface);
primary_if = batadv_primary_if_get_selected(bat_priv); - if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { + if (!primary_if) { ret = -ENOENT; goto out_put_mesh_iface; }
+ if (primary_if->if_status != BATADV_IF_ACTIVE) { + ret = -ENOENT; + goto out_put_primary_if; + } + hard_iface = batadv_netlink_get_hardif(bat_priv, cb); if (IS_ERR(hard_iface) && PTR_ERR(hard_iface) != -ENONET) { ret = PTR_ERR(hard_iface); @@ -1333,11 +1338,16 @@ int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb) bat_priv = netdev_priv(mesh_iface);
primary_if = batadv_primary_if_get_selected(bat_priv); - if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { + if (!primary_if) { ret = -ENOENT; goto out_put_mesh_iface; }
+ if (primary_if->if_status != BATADV_IF_ACTIVE) { + ret = -ENOENT; + goto out_put_primary_if; + } + hard_iface = batadv_netlink_get_hardif(bat_priv, cb); if (IS_ERR(hard_iface) && PTR_ERR(hard_iface) != -ENONET) { ret = PTR_ERR(hard_iface);
Hello:
This patch was applied to netdev/net.git (main) by Simon Wunderlich sw@simonwunderlich.de:
On Fri, 24 Oct 2025 11:11:50 +0200 you wrote:
From: Sven Eckelmann sven@narfation.org
Trying to dump the originators or the neighbors via netlink for a meshif with an inactive primary interface is not allowed. The dump functions were checking this correctly but they didn't handle non-existing primary interfaces and existing _inactive_ interfaces differently.
[...]
Here is the summary with links: - [net,1/1] batman-adv: Release references to inactive interfaces https://git.kernel.org/netdev/net/c/f12b69d8f228
You are awesome, thank you!
linux-stable-mirror@lists.linaro.org