Skip to content
/ linux Public

Commit 469b7ae

Browse files
edumazetSasha Levin
authored andcommitted
inet: ping: check sock_net() in ping_get_port() and ping_lookup()
[ Upstream commit 59f26d8 ] We need to check socket netns before considering them in ping_get_port(). Otherwise, one malicious netns could 'consume' all ports. Add corresponding check in ping_lookup(). Fixes: c319b4d ("net: ipv4: add IPPROTO_ICMP socket kind") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: David Ahern <dsahern@kernel.org> Reviewed-by: Yue Haibing <yuehaibing@huawei.com> Link: https://patch.msgid.link/20250829153054.474201-2-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Stable-dep-of: ad5dfde ("ping: annotate data-races in ping_lookup()") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 9bd9e66 commit 469b7ae

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

net/ipv4/ping.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ static inline struct hlist_head *ping_hashslot(struct ping_table *table,
7777

7878
int ping_get_port(struct sock *sk, unsigned short ident)
7979
{
80+
struct net *net = sock_net(sk);
8081
struct inet_sock *isk, *isk2;
8182
struct hlist_head *hlist;
8283
struct sock *sk2 = NULL;
@@ -90,9 +91,10 @@ int ping_get_port(struct sock *sk, unsigned short ident)
9091
for (i = 0; i < (1L << 16); i++, result++) {
9192
if (!result)
9293
result++; /* avoid zero */
93-
hlist = ping_hashslot(&ping_table, sock_net(sk),
94-
result);
94+
hlist = ping_hashslot(&ping_table, net, result);
9595
sk_for_each(sk2, hlist) {
96+
if (!net_eq(sock_net(sk2), net))
97+
continue;
9698
isk2 = inet_sk(sk2);
9799

98100
if (isk2->inet_num == result)
@@ -108,8 +110,10 @@ int ping_get_port(struct sock *sk, unsigned short ident)
108110
if (i >= (1L << 16))
109111
goto fail;
110112
} else {
111-
hlist = ping_hashslot(&ping_table, sock_net(sk), ident);
113+
hlist = ping_hashslot(&ping_table, net, ident);
112114
sk_for_each(sk2, hlist) {
115+
if (!net_eq(sock_net(sk2), net))
116+
continue;
113117
isk2 = inet_sk(sk2);
114118

115119
/* BUG? Why is this reuse and not reuseaddr? ping.c
@@ -129,7 +133,7 @@ int ping_get_port(struct sock *sk, unsigned short ident)
129133
pr_debug("was not hashed\n");
130134
sk_add_node_rcu(sk, hlist);
131135
sock_set_flag(sk, SOCK_RCU_FREE);
132-
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
136+
sock_prot_inuse_add(net, sk->sk_prot, 1);
133137
}
134138
spin_unlock(&ping_table.lock);
135139
return 0;
@@ -188,6 +192,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
188192
}
189193

190194
sk_for_each_rcu(sk, hslot) {
195+
if (!net_eq(sock_net(sk), net))
196+
continue;
191197
isk = inet_sk(sk);
192198

193199
pr_debug("iterate\n");

0 commit comments

Comments
 (0)