summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2025-02-07 13:58:35 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-03-13 12:50:44 +0100
commit40d8f2f2a373b6c294ffac394d2bb814b572ead1 (patch)
treea9d3ea85c7c1cfc7b89f79785d602281ee2aac2b /net
parent44e35955237802b4b175ab1eb7bdb971a402a644 (diff)
downloadlinux-40d8f2f2a373b6c294ffac394d2bb814b572ead1.tar.gz
linux-40d8f2f2a373b6c294ffac394d2bb814b572ead1.tar.bz2
linux-40d8f2f2a373b6c294ffac394d2bb814b572ead1.zip
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>
Diffstat (limited to 'net')
-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 7fffbe042434..9549738b8184 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -3369,10 +3369,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;
@@ -3385,9 +3387,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)