summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2025-02-07 13:58:35 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-02-21 14:01:43 +0100
commitcdd5c2a12ddad8a77ce1838ff9f29aa587de82df (patch)
treeb61d3b6cd5cc627418c2b885b67cf45be4ca69e7
parentbbec88e4108e8d6fb468d3817fa652140a44ff28 (diff)
neighbour: use RCU protection in __neigh_notify()
[ Upstream commit becbd5850c03ed33b232083dd66c6e38c0c0e569 ] __neigh_notify() can be called without RTNL or RCU protection. Use RCU protection to avoid potential UAF. Fixes: 426b5303eb43 ("[NETNS]: Modify the neighbour table code so it handles multiple network namespaces") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com> Link: https://patch.msgid.link/20250207135841.1948589-4-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--net/core/neighbour.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index cc58315a40a79..c7f7ea61b524a 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -3513,10 +3513,12 @@ static const struct seq_operations neigh_stat_seq_ops = {
static void __neigh_notify(struct neighbour *n, int type, int flags,
u32 pid)
{
- struct net *net = dev_net(n->dev);
struct sk_buff *skb;
int err = -ENOBUFS;
+ struct net *net;
+ rcu_read_lock();
+ net = dev_net_rcu(n->dev);
skb = nlmsg_new(neigh_nlmsg_size(), GFP_ATOMIC);
if (skb == NULL)
goto errout;
@@ -3529,9 +3531,11 @@ static void __neigh_notify(struct neighbour *n, int type, int flags,
goto errout;
}
rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
- return;
+ goto out;
errout:
rtnl_set_sk_err(net, RTNLGRP_NEIGH, err);
+out:
+ rcu_read_unlock();
}
void neigh_app_ns(struct neighbour *n)