Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'inet-ping-misc-changes'

Eric Dumazet says:

====================
inet: ping: misc changes

First and third patches improve security a bit.

Second patch (ping_hash removal) is a cleanup.

Fourth patch uses EXPORT_IPV6_MOD[_GPL].
====================

Link: https://patch.msgid.link/20250829153054.474201-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+32 -37
+1
include/net/netns/ipv4.h
··· 251 251 int sysctl_igmp_qrv; 252 252 253 253 struct ping_group_range ping_group_range; 254 + u16 ping_port_rover; 254 255 255 256 atomic_t dev_addr_genid; 256 257
-1
include/net/ping.h
··· 54 54 }; 55 55 56 56 int ping_get_port(struct sock *sk, unsigned short ident); 57 - int ping_hash(struct sock *sk); 58 57 void ping_unhash(struct sock *sk); 59 58 60 59 int ping_init_sock(struct sock *sk);
+31 -35
net/ipv4/ping.c
··· 56 56 57 57 static struct ping_table ping_table; 58 58 struct pingv6_ops pingv6_ops; 59 - EXPORT_SYMBOL_GPL(pingv6_ops); 60 - 61 - static u16 ping_port_rover; 59 + EXPORT_IPV6_MOD_GPL(pingv6_ops); 62 60 63 61 static inline u32 ping_hashfn(const struct net *net, u32 num, u32 mask) 64 62 { ··· 65 67 pr_debug("hash(%u) = %u\n", num, res); 66 68 return res; 67 69 } 68 - EXPORT_SYMBOL_GPL(ping_hash); 69 70 70 71 static inline struct hlist_head *ping_hashslot(struct ping_table *table, 71 72 struct net *net, unsigned int num) ··· 74 77 75 78 int ping_get_port(struct sock *sk, unsigned short ident) 76 79 { 80 + struct net *net = sock_net(sk); 77 81 struct inet_sock *isk, *isk2; 78 82 struct hlist_head *hlist; 79 83 struct sock *sk2 = NULL; ··· 82 84 isk = inet_sk(sk); 83 85 spin_lock(&ping_table.lock); 84 86 if (ident == 0) { 87 + u16 result = net->ipv4.ping_port_rover + 1; 85 88 u32 i; 86 - u16 result = ping_port_rover + 1; 87 89 88 90 for (i = 0; i < (1L << 16); i++, result++) { 89 91 if (!result) 90 - result++; /* avoid zero */ 91 - hlist = ping_hashslot(&ping_table, sock_net(sk), 92 - result); 92 + continue; /* avoid zero */ 93 + hlist = ping_hashslot(&ping_table, net, result); 93 94 sk_for_each(sk2, hlist) { 95 + if (!net_eq(sock_net(sk2), net)) 96 + continue; 94 97 isk2 = inet_sk(sk2); 95 98 96 99 if (isk2->inet_num == result) ··· 99 100 } 100 101 101 102 /* found */ 102 - ping_port_rover = ident = result; 103 + net->ipv4.ping_port_rover = ident = result; 103 104 break; 104 105 next_port: 105 106 ; ··· 107 108 if (i >= (1L << 16)) 108 109 goto fail; 109 110 } else { 110 - hlist = ping_hashslot(&ping_table, sock_net(sk), ident); 111 + hlist = ping_hashslot(&ping_table, net, ident); 111 112 sk_for_each(sk2, hlist) { 113 + if (!net_eq(sock_net(sk2), net)) 114 + continue; 112 115 isk2 = inet_sk(sk2); 113 116 114 117 /* BUG? Why is this reuse and not reuseaddr? ping.c ··· 130 129 pr_debug("was not hashed\n"); 131 130 sk_add_node_rcu(sk, hlist); 132 131 sock_set_flag(sk, SOCK_RCU_FREE); 133 - sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); 132 + sock_prot_inuse_add(net, sk->sk_prot, 1); 134 133 } 135 134 spin_unlock(&ping_table.lock); 136 135 return 0; ··· 139 138 spin_unlock(&ping_table.lock); 140 139 return -EADDRINUSE; 141 140 } 142 - EXPORT_SYMBOL_GPL(ping_get_port); 143 - 144 - int ping_hash(struct sock *sk) 145 - { 146 - pr_debug("ping_hash(sk->port=%u)\n", inet_sk(sk)->inet_num); 147 - BUG(); /* "Please do not press this button again." */ 148 - 149 - return 0; 150 - } 141 + EXPORT_IPV6_MOD_GPL(ping_get_port); 151 142 152 143 void ping_unhash(struct sock *sk) 153 144 { ··· 154 161 } 155 162 spin_unlock(&ping_table.lock); 156 163 } 157 - EXPORT_SYMBOL_GPL(ping_unhash); 164 + EXPORT_IPV6_MOD_GPL(ping_unhash); 158 165 159 166 /* Called under rcu_read_lock() */ 160 167 static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) ··· 181 188 } 182 189 183 190 sk_for_each_rcu(sk, hslot) { 191 + if (!net_eq(sock_net(sk), net)) 192 + continue; 184 193 isk = inet_sk(sk); 185 194 186 195 pr_debug("iterate\n"); ··· 274 279 put_group_info(group_info); 275 280 return ret; 276 281 } 277 - EXPORT_SYMBOL_GPL(ping_init_sock); 282 + EXPORT_IPV6_MOD_GPL(ping_init_sock); 278 283 279 284 void ping_close(struct sock *sk, long timeout) 280 285 { ··· 284 289 285 290 sk_common_release(sk); 286 291 } 287 - EXPORT_SYMBOL_GPL(ping_close); 292 + EXPORT_IPV6_MOD_GPL(ping_close); 288 293 289 294 static int ping_pre_connect(struct sock *sk, struct sockaddr *uaddr, 290 295 int addr_len) ··· 462 467 pr_debug("ping_v4_bind -> %d\n", err); 463 468 return err; 464 469 } 465 - EXPORT_SYMBOL_GPL(ping_bind); 470 + EXPORT_IPV6_MOD_GPL(ping_bind); 466 471 467 472 /* 468 473 * Is this a supported type of ICMP message? ··· 595 600 out: 596 601 return; 597 602 } 598 - EXPORT_SYMBOL_GPL(ping_err); 603 + EXPORT_IPV6_MOD_GPL(ping_err); 599 604 600 605 /* 601 606 * Copy and checksum an ICMP Echo packet from user space into a buffer ··· 625 630 626 631 return 0; 627 632 } 628 - EXPORT_SYMBOL_GPL(ping_getfrag); 633 + EXPORT_IPV6_MOD_GPL(ping_getfrag); 629 634 630 635 static int ping_v4_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh, 631 636 struct flowi4 *fl4) ··· 686 691 687 692 return 0; 688 693 } 689 - EXPORT_SYMBOL_GPL(ping_common_sendmsg); 694 + EXPORT_IPV6_MOD_GPL(ping_common_sendmsg); 690 695 691 696 static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) 692 697 { ··· 931 936 pr_debug("ping_recvmsg -> %d\n", err); 932 937 return err; 933 938 } 934 - EXPORT_SYMBOL_GPL(ping_recvmsg); 939 + EXPORT_IPV6_MOD_GPL(ping_recvmsg); 935 940 936 941 static enum skb_drop_reason __ping_queue_rcv_skb(struct sock *sk, 937 942 struct sk_buff *skb) ··· 952 957 { 953 958 return __ping_queue_rcv_skb(sk, skb) ? -1 : 0; 954 959 } 955 - EXPORT_SYMBOL_GPL(ping_queue_rcv_skb); 960 + EXPORT_IPV6_MOD_GPL(ping_queue_rcv_skb); 956 961 957 962 958 963 /* ··· 980 985 kfree_skb_reason(skb, SKB_DROP_REASON_NO_SOCKET); 981 986 return SKB_DROP_REASON_NO_SOCKET; 982 987 } 983 - EXPORT_SYMBOL_GPL(ping_rcv); 988 + EXPORT_IPV6_MOD_GPL(ping_rcv); 984 989 985 990 struct proto ping_prot = { 986 991 .name = "PING", ··· 997 1002 .bind = ping_bind, 998 1003 .backlog_rcv = ping_queue_rcv_skb, 999 1004 .release_cb = ip4_datagram_release_cb, 1000 - .hash = ping_hash, 1001 1005 .unhash = ping_unhash, 1002 1006 .get_port = ping_get_port, 1003 1007 .put_port = ping_unhash, 1004 1008 .obj_size = sizeof(struct inet_sock), 1005 1009 }; 1006 - EXPORT_SYMBOL(ping_prot); 1010 + EXPORT_IPV6_MOD(ping_prot); 1007 1011 1008 1012 #ifdef CONFIG_PROC_FS 1009 1013 ··· 1067 1073 1068 1074 return *pos ? ping_get_idx(seq, *pos-1) : SEQ_START_TOKEN; 1069 1075 } 1070 - EXPORT_SYMBOL_GPL(ping_seq_start); 1076 + EXPORT_IPV6_MOD_GPL(ping_seq_start); 1071 1077 1072 1078 static void *ping_v4_seq_start(struct seq_file *seq, loff_t *pos) 1073 1079 { ··· 1086 1092 ++*pos; 1087 1093 return sk; 1088 1094 } 1089 - EXPORT_SYMBOL_GPL(ping_seq_next); 1095 + EXPORT_IPV6_MOD_GPL(ping_seq_next); 1090 1096 1091 1097 void ping_seq_stop(struct seq_file *seq, void *v) 1092 1098 __releases(ping_table.lock) 1093 1099 { 1094 1100 spin_unlock(&ping_table.lock); 1095 1101 } 1096 - EXPORT_SYMBOL_GPL(ping_seq_stop); 1102 + EXPORT_IPV6_MOD_GPL(ping_seq_stop); 1097 1103 1098 1104 static void ping_v4_format_sock(struct sock *sp, struct seq_file *f, 1099 1105 int bucket) ··· 1144 1150 if (!proc_create_net("icmp", 0444, net->proc_net, &ping_v4_seq_ops, 1145 1151 sizeof(struct ping_iter_state))) 1146 1152 return -ENOMEM; 1153 + 1154 + net->ipv4.ping_port_rover = get_random_u16(); 1147 1155 return 0; 1148 1156 } 1149 1157
-1
net/ipv6/ping.c
··· 208 208 .recvmsg = ping_recvmsg, 209 209 .bind = ping_bind, 210 210 .backlog_rcv = ping_queue_rcv_skb, 211 - .hash = ping_hash, 212 211 .unhash = ping_unhash, 213 212 .get_port = ping_get_port, 214 213 .put_port = ping_unhash,