diff options
| author | Eric Dumazet <edumazet@google.com> | 2025-02-07 13:58:35 +0000 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-03-13 12:50:44 +0100 |
| commit | 40d8f2f2a373b6c294ffac394d2bb814b572ead1 (patch) | |
| tree | a9d3ea85c7c1cfc7b89f79785d602281ee2aac2b /net | |
| parent | 44e35955237802b4b175ab1eb7bdb971a402a644 (diff) | |
| download | linux-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.c | 8 |
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) |
