]> www.infradead.org Git - users/hch/misc.git/commitdiff
inet: ping: check sock_net() in ping_get_port() and ping_lookup()
authorEric Dumazet <edumazet@google.com>
Fri, 29 Aug 2025 15:30:51 +0000 (15:30 +0000)
committerJakub Kicinski <kuba@kernel.org>
Mon, 1 Sep 2025 20:15:14 +0000 (13:15 -0700)
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: c319b4d76b9e ("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>
net/ipv4/ping.c

index f119da68fc301be00719213ad33615b6754e6272..74a0beddfcc41d8ba17792a11a9d027c9d590bac 100644 (file)
@@ -77,6 +77,7 @@ static inline struct hlist_head *ping_hashslot(struct ping_table *table,
 
 int ping_get_port(struct sock *sk, unsigned short ident)
 {
+       struct net *net = sock_net(sk);
        struct inet_sock *isk, *isk2;
        struct hlist_head *hlist;
        struct sock *sk2 = NULL;
@@ -90,9 +91,10 @@ int ping_get_port(struct sock *sk, unsigned short ident)
                for (i = 0; i < (1L << 16); i++, result++) {
                        if (!result)
                                result++; /* avoid zero */
-                       hlist = ping_hashslot(&ping_table, sock_net(sk),
-                                           result);
+                       hlist = ping_hashslot(&ping_table, net, result);
                        sk_for_each(sk2, hlist) {
+                               if (!net_eq(sock_net(sk2), net))
+                                       continue;
                                isk2 = inet_sk(sk2);
 
                                if (isk2->inet_num == result)
@@ -108,8 +110,10 @@ next_port:
                if (i >= (1L << 16))
                        goto fail;
        } else {
-               hlist = ping_hashslot(&ping_table, sock_net(sk), ident);
+               hlist = ping_hashslot(&ping_table, net, ident);
                sk_for_each(sk2, hlist) {
+                       if (!net_eq(sock_net(sk2), net))
+                               continue;
                        isk2 = inet_sk(sk2);
 
                        /* BUG? Why is this reuse and not reuseaddr? ping.c
@@ -129,7 +133,7 @@ next_port:
                pr_debug("was not hashed\n");
                sk_add_node_rcu(sk, hlist);
                sock_set_flag(sk, SOCK_RCU_FREE);
-               sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
+               sock_prot_inuse_add(net, sk->sk_prot, 1);
        }
        spin_unlock(&ping_table.lock);
        return 0;
@@ -188,6 +192,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
        }
 
        sk_for_each_rcu(sk, hslot) {
+               if (!net_eq(sock_net(sk), net))
+                       continue;
                isk = inet_sk(sk);
 
                pr_debug("iterate\n");