Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * INET An implementation of the TCP/IP protocol suite for the LINUX
4 : * operating system. INET is implemented using the BSD Socket
5 : * interface as the means of communication with the user level.
6 : *
7 : * "Ping" sockets
8 : *
9 : * Based on ipv4/udp.c code.
10 : *
11 : * Authors: Vasiliy Kulikov / Openwall (for Linux 2.6),
12 : * Pavel Kankovsky (for Linux 2.4.32)
13 : *
14 : * Pavel gave all rights to bugs to Vasiliy,
15 : * none of the bugs are Pavel's now.
16 : */
17 :
18 : #include <linux/uaccess.h>
19 : #include <linux/types.h>
20 : #include <linux/fcntl.h>
21 : #include <linux/socket.h>
22 : #include <linux/sockios.h>
23 : #include <linux/in.h>
24 : #include <linux/errno.h>
25 : #include <linux/timer.h>
26 : #include <linux/mm.h>
27 : #include <linux/inet.h>
28 : #include <linux/netdevice.h>
29 : #include <net/snmp.h>
30 : #include <net/ip.h>
31 : #include <net/icmp.h>
32 : #include <net/protocol.h>
33 : #include <linux/skbuff.h>
34 : #include <linux/proc_fs.h>
35 : #include <linux/export.h>
36 : #include <net/sock.h>
37 : #include <net/ping.h>
38 : #include <net/udp.h>
39 : #include <net/route.h>
40 : #include <net/inet_common.h>
41 : #include <net/checksum.h>
42 :
43 : #if IS_ENABLED(CONFIG_IPV6)
44 : #include <linux/in6.h>
45 : #include <linux/icmpv6.h>
46 : #include <net/addrconf.h>
47 : #include <net/ipv6.h>
48 : #include <net/transp_v6.h>
49 : #endif
50 :
51 : struct ping_table {
52 : struct hlist_nulls_head hash[PING_HTABLE_SIZE];
53 : rwlock_t lock;
54 : };
55 :
56 : static struct ping_table ping_table;
57 : struct pingv6_ops pingv6_ops;
58 : EXPORT_SYMBOL_GPL(pingv6_ops);
59 :
60 : static u16 ping_port_rover;
61 :
62 0 : static inline u32 ping_hashfn(const struct net *net, u32 num, u32 mask)
63 : {
64 0 : u32 res = (num + net_hash_mix(net)) & mask;
65 :
66 0 : pr_debug("hash(%u) = %u\n", num, res);
67 0 : return res;
68 : }
69 : EXPORT_SYMBOL_GPL(ping_hash);
70 :
71 0 : static inline struct hlist_nulls_head *ping_hashslot(struct ping_table *table,
72 : struct net *net, unsigned int num)
73 : {
74 0 : return &table->hash[ping_hashfn(net, num, PING_HTABLE_MASK)];
75 : }
76 :
77 0 : int ping_get_port(struct sock *sk, unsigned short ident)
78 : {
79 0 : struct hlist_nulls_node *node;
80 0 : struct hlist_nulls_head *hlist;
81 0 : struct inet_sock *isk, *isk2;
82 0 : struct sock *sk2 = NULL;
83 :
84 0 : isk = inet_sk(sk);
85 0 : write_lock_bh(&ping_table.lock);
86 0 : if (ident == 0) {
87 0 : u32 i;
88 0 : u16 result = ping_port_rover + 1;
89 :
90 0 : for (i = 0; i < (1L << 16); i++, result++) {
91 0 : if (!result)
92 : result++; /* avoid zero */
93 0 : hlist = ping_hashslot(&ping_table, sock_net(sk),
94 : result);
95 0 : ping_portaddr_for_each_entry(sk2, node, hlist) {
96 0 : isk2 = inet_sk(sk2);
97 :
98 0 : if (isk2->inet_num == result)
99 0 : goto next_port;
100 : }
101 :
102 : /* found */
103 0 : ping_port_rover = ident = result;
104 0 : break;
105 0 : next_port:
106 0 : ;
107 : }
108 0 : if (i >= (1L << 16))
109 0 : goto fail;
110 : } else {
111 0 : hlist = ping_hashslot(&ping_table, sock_net(sk), ident);
112 0 : ping_portaddr_for_each_entry(sk2, node, hlist) {
113 0 : isk2 = inet_sk(sk2);
114 :
115 : /* BUG? Why is this reuse and not reuseaddr? ping.c
116 : * doesn't turn off SO_REUSEADDR, and it doesn't expect
117 : * that other ping processes can steal its packets.
118 : */
119 0 : if ((isk2->inet_num == ident) &&
120 0 : (sk2 != sk) &&
121 0 : (!sk2->sk_reuse || !sk->sk_reuse))
122 0 : goto fail;
123 : }
124 : }
125 :
126 0 : pr_debug("found port/ident = %d\n", ident);
127 0 : isk->inet_num = ident;
128 0 : if (sk_unhashed(sk)) {
129 0 : pr_debug("was not hashed\n");
130 0 : sock_hold(sk);
131 0 : hlist_nulls_add_head(&sk->sk_nulls_node, hlist);
132 0 : sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
133 : }
134 0 : write_unlock_bh(&ping_table.lock);
135 0 : return 0;
136 :
137 0 : fail:
138 0 : write_unlock_bh(&ping_table.lock);
139 0 : return 1;
140 : }
141 : EXPORT_SYMBOL_GPL(ping_get_port);
142 :
143 0 : int ping_hash(struct sock *sk)
144 : {
145 0 : pr_debug("ping_hash(sk->port=%u)\n", inet_sk(sk)->inet_num);
146 0 : BUG(); /* "Please do not press this button again." */
147 :
148 : return 0;
149 : }
150 :
151 0 : void ping_unhash(struct sock *sk)
152 : {
153 0 : struct inet_sock *isk = inet_sk(sk);
154 :
155 0 : pr_debug("ping_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
156 0 : write_lock_bh(&ping_table.lock);
157 0 : if (sk_hashed(sk)) {
158 0 : hlist_nulls_del(&sk->sk_nulls_node);
159 0 : sk_nulls_node_init(&sk->sk_nulls_node);
160 0 : sock_put(sk);
161 0 : isk->inet_num = 0;
162 0 : isk->inet_sport = 0;
163 0 : sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
164 : }
165 0 : write_unlock_bh(&ping_table.lock);
166 0 : }
167 : EXPORT_SYMBOL_GPL(ping_unhash);
168 :
169 0 : static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
170 : {
171 0 : struct hlist_nulls_head *hslot = ping_hashslot(&ping_table, net, ident);
172 0 : struct sock *sk = NULL;
173 0 : struct inet_sock *isk;
174 0 : struct hlist_nulls_node *hnode;
175 0 : int dif = skb->dev->ifindex;
176 :
177 0 : if (skb->protocol == htons(ETH_P_IP)) {
178 : pr_debug("try to find: num = %d, daddr = %pI4, dif = %d\n",
179 : (int)ident, &ip_hdr(skb)->daddr, dif);
180 : #if IS_ENABLED(CONFIG_IPV6)
181 : } else if (skb->protocol == htons(ETH_P_IPV6)) {
182 : pr_debug("try to find: num = %d, daddr = %pI6c, dif = %d\n",
183 : (int)ident, &ipv6_hdr(skb)->daddr, dif);
184 : #endif
185 : }
186 :
187 0 : read_lock_bh(&ping_table.lock);
188 :
189 0 : ping_portaddr_for_each_entry(sk, hnode, hslot) {
190 0 : isk = inet_sk(sk);
191 :
192 0 : pr_debug("iterate\n");
193 0 : if (isk->inet_num != ident)
194 0 : continue;
195 :
196 0 : if (skb->protocol == htons(ETH_P_IP) &&
197 0 : sk->sk_family == AF_INET) {
198 0 : pr_debug("found: %p: num=%d, daddr=%pI4, dif=%d\n", sk,
199 : (int) isk->inet_num, &isk->inet_rcv_saddr,
200 : sk->sk_bound_dev_if);
201 :
202 0 : if (isk->inet_rcv_saddr &&
203 0 : isk->inet_rcv_saddr != ip_hdr(skb)->daddr)
204 0 : continue;
205 : #if IS_ENABLED(CONFIG_IPV6)
206 : } else if (skb->protocol == htons(ETH_P_IPV6) &&
207 : sk->sk_family == AF_INET6) {
208 :
209 : pr_debug("found: %p: num=%d, daddr=%pI6c, dif=%d\n", sk,
210 : (int) isk->inet_num,
211 : &sk->sk_v6_rcv_saddr,
212 : sk->sk_bound_dev_if);
213 :
214 : if (!ipv6_addr_any(&sk->sk_v6_rcv_saddr) &&
215 : !ipv6_addr_equal(&sk->sk_v6_rcv_saddr,
216 : &ipv6_hdr(skb)->daddr))
217 : continue;
218 : #endif
219 : } else {
220 0 : continue;
221 : }
222 :
223 0 : if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif)
224 0 : continue;
225 :
226 0 : sock_hold(sk);
227 0 : goto exit;
228 : }
229 :
230 : sk = NULL;
231 0 : exit:
232 0 : read_unlock_bh(&ping_table.lock);
233 :
234 0 : return sk;
235 : }
236 :
237 0 : static void inet_get_ping_group_range_net(struct net *net, kgid_t *low,
238 : kgid_t *high)
239 : {
240 0 : kgid_t *data = net->ipv4.ping_group_range.range;
241 0 : unsigned int seq;
242 :
243 0 : do {
244 0 : seq = read_seqbegin(&net->ipv4.ping_group_range.lock);
245 :
246 0 : *low = data[0];
247 0 : *high = data[1];
248 0 : } while (read_seqretry(&net->ipv4.ping_group_range.lock, seq));
249 0 : }
250 :
251 :
252 0 : int ping_init_sock(struct sock *sk)
253 : {
254 0 : struct net *net = sock_net(sk);
255 0 : kgid_t group = current_egid();
256 0 : struct group_info *group_info;
257 0 : int i;
258 0 : kgid_t low, high;
259 0 : int ret = 0;
260 :
261 0 : if (sk->sk_family == AF_INET6)
262 0 : sk->sk_ipv6only = 1;
263 :
264 0 : inet_get_ping_group_range_net(net, &low, &high);
265 0 : if (gid_lte(low, group) && gid_lte(group, high))
266 : return 0;
267 :
268 0 : group_info = get_current_groups();
269 0 : for (i = 0; i < group_info->ngroups; i++) {
270 0 : kgid_t gid = group_info->gid[i];
271 :
272 0 : if (gid_lte(low, gid) && gid_lte(gid, high))
273 0 : goto out_release_group;
274 : }
275 :
276 : ret = -EACCES;
277 :
278 0 : out_release_group:
279 0 : put_group_info(group_info);
280 : return ret;
281 : }
282 : EXPORT_SYMBOL_GPL(ping_init_sock);
283 :
284 0 : void ping_close(struct sock *sk, long timeout)
285 : {
286 0 : pr_debug("ping_close(sk=%p,sk->num=%u)\n",
287 : inet_sk(sk), inet_sk(sk)->inet_num);
288 0 : pr_debug("isk->refcnt = %d\n", refcount_read(&sk->sk_refcnt));
289 :
290 0 : sk_common_release(sk);
291 0 : }
292 : EXPORT_SYMBOL_GPL(ping_close);
293 :
294 : /* Checks the bind address and possibly modifies sk->sk_bound_dev_if. */
295 0 : static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk,
296 : struct sockaddr *uaddr, int addr_len)
297 : {
298 0 : struct net *net = sock_net(sk);
299 0 : if (sk->sk_family == AF_INET) {
300 0 : struct sockaddr_in *addr = (struct sockaddr_in *) uaddr;
301 0 : int chk_addr_ret;
302 :
303 0 : if (addr_len < sizeof(*addr))
304 : return -EINVAL;
305 :
306 0 : if (addr->sin_family != AF_INET &&
307 0 : !(addr->sin_family == AF_UNSPEC &&
308 0 : addr->sin_addr.s_addr == htonl(INADDR_ANY)))
309 : return -EAFNOSUPPORT;
310 :
311 0 : pr_debug("ping_check_bind_addr(sk=%p,addr=%pI4,port=%d)\n",
312 : sk, &addr->sin_addr.s_addr, ntohs(addr->sin_port));
313 :
314 0 : if (addr->sin_addr.s_addr == htonl(INADDR_ANY))
315 : chk_addr_ret = RTN_LOCAL;
316 : else
317 0 : chk_addr_ret = inet_addr_type(net, addr->sin_addr.s_addr);
318 :
319 0 : if ((!inet_can_nonlocal_bind(net, isk) &&
320 : chk_addr_ret != RTN_LOCAL) ||
321 0 : chk_addr_ret == RTN_MULTICAST ||
322 0 : chk_addr_ret == RTN_BROADCAST)
323 0 : return -EADDRNOTAVAIL;
324 :
325 : #if IS_ENABLED(CONFIG_IPV6)
326 : } else if (sk->sk_family == AF_INET6) {
327 : struct sockaddr_in6 *addr = (struct sockaddr_in6 *) uaddr;
328 : int addr_type, scoped, has_addr;
329 : struct net_device *dev = NULL;
330 :
331 : if (addr_len < sizeof(*addr))
332 : return -EINVAL;
333 :
334 : if (addr->sin6_family != AF_INET6)
335 : return -EAFNOSUPPORT;
336 :
337 : pr_debug("ping_check_bind_addr(sk=%p,addr=%pI6c,port=%d)\n",
338 : sk, addr->sin6_addr.s6_addr, ntohs(addr->sin6_port));
339 :
340 : addr_type = ipv6_addr_type(&addr->sin6_addr);
341 : scoped = __ipv6_addr_needs_scope_id(addr_type);
342 : if ((addr_type != IPV6_ADDR_ANY &&
343 : !(addr_type & IPV6_ADDR_UNICAST)) ||
344 : (scoped && !addr->sin6_scope_id))
345 : return -EINVAL;
346 :
347 : rcu_read_lock();
348 : if (addr->sin6_scope_id) {
349 : dev = dev_get_by_index_rcu(net, addr->sin6_scope_id);
350 : if (!dev) {
351 : rcu_read_unlock();
352 : return -ENODEV;
353 : }
354 : }
355 : has_addr = pingv6_ops.ipv6_chk_addr(net, &addr->sin6_addr, dev,
356 : scoped);
357 : rcu_read_unlock();
358 :
359 : if (!(ipv6_can_nonlocal_bind(net, isk) || has_addr ||
360 : addr_type == IPV6_ADDR_ANY))
361 : return -EADDRNOTAVAIL;
362 :
363 : if (scoped)
364 : sk->sk_bound_dev_if = addr->sin6_scope_id;
365 : #endif
366 : } else {
367 : return -EAFNOSUPPORT;
368 : }
369 : return 0;
370 : }
371 :
372 0 : static void ping_set_saddr(struct sock *sk, struct sockaddr *saddr)
373 : {
374 0 : if (saddr->sa_family == AF_INET) {
375 0 : struct inet_sock *isk = inet_sk(sk);
376 0 : struct sockaddr_in *addr = (struct sockaddr_in *) saddr;
377 0 : isk->inet_rcv_saddr = isk->inet_saddr = addr->sin_addr.s_addr;
378 : #if IS_ENABLED(CONFIG_IPV6)
379 : } else if (saddr->sa_family == AF_INET6) {
380 : struct sockaddr_in6 *addr = (struct sockaddr_in6 *) saddr;
381 : struct ipv6_pinfo *np = inet6_sk(sk);
382 : sk->sk_v6_rcv_saddr = np->saddr = addr->sin6_addr;
383 : #endif
384 : }
385 : }
386 :
387 : /*
388 : * We need our own bind because there are no privileged id's == local ports.
389 : * Moreover, we don't allow binding to multi- and broadcast addresses.
390 : */
391 :
392 0 : int ping_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
393 : {
394 0 : struct inet_sock *isk = inet_sk(sk);
395 0 : unsigned short snum;
396 0 : int err;
397 0 : int dif = sk->sk_bound_dev_if;
398 :
399 0 : err = ping_check_bind_addr(sk, isk, uaddr, addr_len);
400 0 : if (err)
401 : return err;
402 :
403 0 : lock_sock(sk);
404 :
405 0 : err = -EINVAL;
406 0 : if (isk->inet_num != 0)
407 0 : goto out;
408 :
409 0 : err = -EADDRINUSE;
410 0 : snum = ntohs(((struct sockaddr_in *)uaddr)->sin_port);
411 0 : if (ping_get_port(sk, snum) != 0) {
412 : /* Restore possibly modified sk->sk_bound_dev_if by ping_check_bind_addr(). */
413 0 : sk->sk_bound_dev_if = dif;
414 0 : goto out;
415 : }
416 0 : ping_set_saddr(sk, uaddr);
417 :
418 0 : pr_debug("after bind(): num = %hu, dif = %d\n",
419 : isk->inet_num,
420 : sk->sk_bound_dev_if);
421 :
422 0 : err = 0;
423 0 : if (sk->sk_family == AF_INET && isk->inet_rcv_saddr)
424 0 : sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
425 : #if IS_ENABLED(CONFIG_IPV6)
426 : if (sk->sk_family == AF_INET6 && !ipv6_addr_any(&sk->sk_v6_rcv_saddr))
427 : sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
428 : #endif
429 :
430 0 : if (snum)
431 0 : sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
432 0 : isk->inet_sport = htons(isk->inet_num);
433 0 : isk->inet_daddr = 0;
434 0 : isk->inet_dport = 0;
435 :
436 : #if IS_ENABLED(CONFIG_IPV6)
437 : if (sk->sk_family == AF_INET6)
438 : memset(&sk->sk_v6_daddr, 0, sizeof(sk->sk_v6_daddr));
439 : #endif
440 :
441 0 : sk_dst_reset(sk);
442 0 : out:
443 0 : release_sock(sk);
444 0 : pr_debug("ping_v4_bind -> %d\n", err);
445 0 : return err;
446 : }
447 : EXPORT_SYMBOL_GPL(ping_bind);
448 :
449 : /*
450 : * Is this a supported type of ICMP message?
451 : */
452 :
453 0 : static inline int ping_supported(int family, int type, int code)
454 : {
455 0 : return (family == AF_INET && type == ICMP_ECHO && code == 0) ||
456 0 : (family == AF_INET6 && type == ICMPV6_ECHO_REQUEST && code == 0);
457 : }
458 :
459 : /*
460 : * This routine is called by the ICMP module when it gets some
461 : * sort of error condition.
462 : */
463 :
464 0 : void ping_err(struct sk_buff *skb, int offset, u32 info)
465 : {
466 0 : int family;
467 0 : struct icmphdr *icmph;
468 0 : struct inet_sock *inet_sock;
469 0 : int type;
470 0 : int code;
471 0 : struct net *net = dev_net(skb->dev);
472 0 : struct sock *sk;
473 0 : int harderr;
474 0 : int err;
475 :
476 0 : if (skb->protocol == htons(ETH_P_IP)) {
477 0 : family = AF_INET;
478 0 : type = icmp_hdr(skb)->type;
479 0 : code = icmp_hdr(skb)->code;
480 0 : icmph = (struct icmphdr *)(skb->data + offset);
481 0 : } else if (skb->protocol == htons(ETH_P_IPV6)) {
482 0 : family = AF_INET6;
483 0 : type = icmp6_hdr(skb)->icmp6_type;
484 0 : code = icmp6_hdr(skb)->icmp6_code;
485 0 : icmph = (struct icmphdr *) (skb->data + offset);
486 : } else {
487 0 : BUG();
488 : }
489 :
490 : /* We assume the packet has already been checked by icmp_unreach */
491 :
492 0 : if (!ping_supported(family, icmph->type, icmph->code))
493 : return;
494 :
495 0 : pr_debug("ping_err(proto=0x%x,type=%d,code=%d,id=%04x,seq=%04x)\n",
496 : skb->protocol, type, code, ntohs(icmph->un.echo.id),
497 : ntohs(icmph->un.echo.sequence));
498 :
499 0 : sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id));
500 0 : if (!sk) {
501 : pr_debug("no socket, dropping\n");
502 : return; /* No socket for error */
503 : }
504 0 : pr_debug("err on socket %p\n", sk);
505 :
506 0 : err = 0;
507 0 : harderr = 0;
508 0 : inet_sock = inet_sk(sk);
509 :
510 0 : if (skb->protocol == htons(ETH_P_IP)) {
511 0 : switch (type) {
512 : default:
513 : case ICMP_TIME_EXCEEDED:
514 : err = EHOSTUNREACH;
515 : break;
516 0 : case ICMP_SOURCE_QUENCH:
517 : /* This is not a real error but ping wants to see it.
518 : * Report it with some fake errno.
519 : */
520 0 : err = EREMOTEIO;
521 0 : break;
522 0 : case ICMP_PARAMETERPROB:
523 0 : err = EPROTO;
524 0 : harderr = 1;
525 0 : break;
526 0 : case ICMP_DEST_UNREACH:
527 0 : if (code == ICMP_FRAG_NEEDED) { /* Path MTU discovery */
528 0 : ipv4_sk_update_pmtu(skb, sk, info);
529 0 : if (inet_sock->pmtudisc != IP_PMTUDISC_DONT) {
530 : err = EMSGSIZE;
531 : harderr = 1;
532 : break;
533 : }
534 0 : goto out;
535 : }
536 0 : err = EHOSTUNREACH;
537 0 : if (code <= NR_ICMP_UNREACH) {
538 0 : harderr = icmp_err_convert[code].fatal;
539 0 : err = icmp_err_convert[code].errno;
540 : }
541 : break;
542 0 : case ICMP_REDIRECT:
543 : /* See ICMP_SOURCE_QUENCH */
544 0 : ipv4_sk_redirect(skb, sk);
545 0 : err = EREMOTEIO;
546 0 : break;
547 : }
548 : #if IS_ENABLED(CONFIG_IPV6)
549 : } else if (skb->protocol == htons(ETH_P_IPV6)) {
550 : harderr = pingv6_ops.icmpv6_err_convert(type, code, &err);
551 : #endif
552 0 : }
553 :
554 : /*
555 : * RFC1122: OK. Passes ICMP errors back to application, as per
556 : * 4.1.3.3.
557 : */
558 0 : if ((family == AF_INET && !inet_sock->recverr) ||
559 0 : (family == AF_INET6 && !inet6_sk(sk)->recverr)) {
560 0 : if (!harderr || sk->sk_state != TCP_ESTABLISHED)
561 0 : goto out;
562 : } else {
563 0 : if (family == AF_INET) {
564 0 : ip_icmp_error(sk, skb, err, 0 /* no remote port */,
565 : info, (u8 *)icmph);
566 : #if IS_ENABLED(CONFIG_IPV6)
567 : } else if (family == AF_INET6) {
568 : pingv6_ops.ipv6_icmp_error(sk, skb, err, 0,
569 : info, (u8 *)icmph);
570 : #endif
571 : }
572 : }
573 0 : sk->sk_err = err;
574 0 : sk->sk_error_report(sk);
575 0 : out:
576 0 : sock_put(sk);
577 : }
578 : EXPORT_SYMBOL_GPL(ping_err);
579 :
580 : /*
581 : * Copy and checksum an ICMP Echo packet from user space into a buffer
582 : * starting from the payload.
583 : */
584 :
585 0 : int ping_getfrag(void *from, char *to,
586 : int offset, int fraglen, int odd, struct sk_buff *skb)
587 : {
588 0 : struct pingfakehdr *pfh = (struct pingfakehdr *)from;
589 :
590 0 : if (offset == 0) {
591 0 : fraglen -= sizeof(struct icmphdr);
592 0 : if (fraglen < 0)
593 0 : BUG();
594 0 : if (!csum_and_copy_from_iter_full(to + sizeof(struct icmphdr),
595 : fraglen, &pfh->wcheck,
596 0 : &pfh->msg->msg_iter))
597 0 : return -EFAULT;
598 0 : } else if (offset < sizeof(struct icmphdr)) {
599 0 : BUG();
600 : } else {
601 0 : if (!csum_and_copy_from_iter_full(to, fraglen, &pfh->wcheck,
602 0 : &pfh->msg->msg_iter))
603 0 : return -EFAULT;
604 : }
605 :
606 : #if IS_ENABLED(CONFIG_IPV6)
607 : /* For IPv6, checksum each skb as we go along, as expected by
608 : * icmpv6_push_pending_frames. For IPv4, accumulate the checksum in
609 : * wcheck, it will be finalized in ping_v4_push_pending_frames.
610 : */
611 : if (pfh->family == AF_INET6) {
612 : skb->csum = pfh->wcheck;
613 : skb->ip_summed = CHECKSUM_NONE;
614 : pfh->wcheck = 0;
615 : }
616 : #endif
617 :
618 : return 0;
619 : }
620 : EXPORT_SYMBOL_GPL(ping_getfrag);
621 :
622 0 : static int ping_v4_push_pending_frames(struct sock *sk, struct pingfakehdr *pfh,
623 : struct flowi4 *fl4)
624 : {
625 0 : struct sk_buff *skb = skb_peek(&sk->sk_write_queue);
626 :
627 0 : if (!skb)
628 : return 0;
629 0 : pfh->wcheck = csum_partial((char *)&pfh->icmph,
630 : sizeof(struct icmphdr), pfh->wcheck);
631 0 : pfh->icmph.checksum = csum_fold(pfh->wcheck);
632 0 : memcpy(icmp_hdr(skb), &pfh->icmph, sizeof(struct icmphdr));
633 0 : skb->ip_summed = CHECKSUM_NONE;
634 0 : return ip_push_pending_frames(sk, fl4);
635 : }
636 :
637 0 : int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,
638 : void *user_icmph, size_t icmph_len)
639 : {
640 0 : u8 type, code;
641 :
642 0 : if (len > 0xFFFF)
643 : return -EMSGSIZE;
644 :
645 : /* Must have at least a full ICMP header. */
646 0 : if (len < icmph_len)
647 : return -EINVAL;
648 :
649 : /*
650 : * Check the flags.
651 : */
652 :
653 : /* Mirror BSD error message compatibility */
654 0 : if (msg->msg_flags & MSG_OOB)
655 : return -EOPNOTSUPP;
656 :
657 : /*
658 : * Fetch the ICMP header provided by the userland.
659 : * iovec is modified! The ICMP header is consumed.
660 : */
661 0 : if (memcpy_from_msg(user_icmph, msg, icmph_len))
662 : return -EFAULT;
663 :
664 0 : if (family == AF_INET) {
665 0 : type = ((struct icmphdr *) user_icmph)->type;
666 0 : code = ((struct icmphdr *) user_icmph)->code;
667 : #if IS_ENABLED(CONFIG_IPV6)
668 : } else if (family == AF_INET6) {
669 : type = ((struct icmp6hdr *) user_icmph)->icmp6_type;
670 : code = ((struct icmp6hdr *) user_icmph)->icmp6_code;
671 : #endif
672 : } else {
673 0 : BUG();
674 : }
675 :
676 0 : if (!ping_supported(family, type, code))
677 0 : return -EINVAL;
678 :
679 : return 0;
680 : }
681 : EXPORT_SYMBOL_GPL(ping_common_sendmsg);
682 :
683 0 : static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
684 : {
685 0 : struct net *net = sock_net(sk);
686 0 : struct flowi4 fl4;
687 0 : struct inet_sock *inet = inet_sk(sk);
688 0 : struct ipcm_cookie ipc;
689 0 : struct icmphdr user_icmph;
690 0 : struct pingfakehdr pfh;
691 0 : struct rtable *rt = NULL;
692 0 : struct ip_options_data opt_copy;
693 0 : int free = 0;
694 0 : __be32 saddr, daddr, faddr;
695 0 : u8 tos;
696 0 : int err;
697 :
698 0 : pr_debug("ping_v4_sendmsg(sk=%p,sk->num=%u)\n", inet, inet->inet_num);
699 :
700 0 : err = ping_common_sendmsg(AF_INET, msg, len, &user_icmph,
701 : sizeof(user_icmph));
702 0 : if (err)
703 : return err;
704 :
705 : /*
706 : * Get and verify the address.
707 : */
708 :
709 0 : if (msg->msg_name) {
710 0 : DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name);
711 0 : if (msg->msg_namelen < sizeof(*usin))
712 : return -EINVAL;
713 0 : if (usin->sin_family != AF_INET)
714 : return -EAFNOSUPPORT;
715 0 : daddr = usin->sin_addr.s_addr;
716 : /* no remote port */
717 : } else {
718 0 : if (sk->sk_state != TCP_ESTABLISHED)
719 : return -EDESTADDRREQ;
720 0 : daddr = inet->inet_daddr;
721 : /* no remote port */
722 : }
723 :
724 0 : ipcm_init_sk(&ipc, inet);
725 :
726 0 : if (msg->msg_controllen) {
727 0 : err = ip_cmsg_send(sk, msg, &ipc, false);
728 0 : if (unlikely(err)) {
729 0 : kfree(ipc.opt);
730 0 : return err;
731 : }
732 0 : if (ipc.opt)
733 0 : free = 1;
734 : }
735 0 : if (!ipc.opt) {
736 0 : struct ip_options_rcu *inet_opt;
737 :
738 0 : rcu_read_lock();
739 0 : inet_opt = rcu_dereference(inet->inet_opt);
740 0 : if (inet_opt) {
741 0 : memcpy(&opt_copy, inet_opt,
742 0 : sizeof(*inet_opt) + inet_opt->opt.optlen);
743 0 : ipc.opt = &opt_copy.opt;
744 : }
745 0 : rcu_read_unlock();
746 : }
747 :
748 0 : saddr = ipc.addr;
749 0 : ipc.addr = faddr = daddr;
750 :
751 0 : if (ipc.opt && ipc.opt->opt.srr) {
752 0 : if (!daddr) {
753 0 : err = -EINVAL;
754 0 : goto out_free;
755 : }
756 0 : faddr = ipc.opt->opt.faddr;
757 : }
758 0 : tos = get_rttos(&ipc, inet);
759 0 : if (sock_flag(sk, SOCK_LOCALROUTE) ||
760 0 : (msg->msg_flags & MSG_DONTROUTE) ||
761 0 : (ipc.opt && ipc.opt->opt.is_strictroute)) {
762 0 : tos |= RTO_ONLINK;
763 : }
764 :
765 0 : if (ipv4_is_multicast(daddr)) {
766 0 : if (!ipc.oif || netif_index_is_l3_master(sock_net(sk), ipc.oif))
767 0 : ipc.oif = inet->mc_index;
768 0 : if (!saddr)
769 0 : saddr = inet->mc_addr;
770 0 : } else if (!ipc.oif)
771 0 : ipc.oif = inet->uc_index;
772 :
773 0 : flowi4_init_output(&fl4, ipc.oif, ipc.sockc.mark, tos,
774 0 : RT_SCOPE_UNIVERSE, sk->sk_protocol,
775 0 : inet_sk_flowi_flags(sk), faddr, saddr, 0, 0,
776 : sk->sk_uid);
777 :
778 0 : fl4.fl4_icmp_type = user_icmph.type;
779 0 : fl4.fl4_icmp_code = user_icmph.code;
780 :
781 0 : security_sk_classify_flow(sk, flowi4_to_flowi_common(&fl4));
782 0 : rt = ip_route_output_flow(net, &fl4, sk);
783 0 : if (IS_ERR(rt)) {
784 0 : err = PTR_ERR(rt);
785 0 : rt = NULL;
786 0 : if (err == -ENETUNREACH)
787 0 : IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
788 0 : goto out;
789 : }
790 :
791 0 : err = -EACCES;
792 0 : if ((rt->rt_flags & RTCF_BROADCAST) &&
793 0 : !sock_flag(sk, SOCK_BROADCAST))
794 0 : goto out;
795 :
796 0 : if (msg->msg_flags & MSG_CONFIRM)
797 0 : goto do_confirm;
798 0 : back_from_confirm:
799 :
800 0 : if (!ipc.addr)
801 0 : ipc.addr = fl4.daddr;
802 :
803 0 : lock_sock(sk);
804 :
805 0 : pfh.icmph.type = user_icmph.type; /* already checked */
806 0 : pfh.icmph.code = user_icmph.code; /* ditto */
807 0 : pfh.icmph.checksum = 0;
808 0 : pfh.icmph.un.echo.id = inet->inet_sport;
809 0 : pfh.icmph.un.echo.sequence = user_icmph.un.echo.sequence;
810 0 : pfh.msg = msg;
811 0 : pfh.wcheck = 0;
812 0 : pfh.family = AF_INET;
813 :
814 0 : err = ip_append_data(sk, &fl4, ping_getfrag, &pfh, len,
815 : 0, &ipc, &rt, msg->msg_flags);
816 0 : if (err)
817 0 : ip_flush_pending_frames(sk);
818 : else
819 0 : err = ping_v4_push_pending_frames(sk, &pfh, &fl4);
820 0 : release_sock(sk);
821 :
822 0 : out:
823 0 : ip_rt_put(rt);
824 0 : out_free:
825 0 : if (free)
826 0 : kfree(ipc.opt);
827 0 : if (!err) {
828 0 : icmp_out_count(sock_net(sk), user_icmph.type);
829 0 : return len;
830 : }
831 : return err;
832 :
833 0 : do_confirm:
834 0 : if (msg->msg_flags & MSG_PROBE)
835 0 : dst_confirm_neigh(&rt->dst, &fl4.daddr);
836 0 : if (!(msg->msg_flags & MSG_PROBE) || len)
837 0 : goto back_from_confirm;
838 0 : err = 0;
839 0 : goto out;
840 : }
841 :
842 0 : int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
843 : int flags, int *addr_len)
844 : {
845 0 : struct inet_sock *isk = inet_sk(sk);
846 0 : int family = sk->sk_family;
847 0 : struct sk_buff *skb;
848 0 : int copied, err;
849 :
850 0 : pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num);
851 :
852 0 : err = -EOPNOTSUPP;
853 0 : if (flags & MSG_OOB)
854 0 : goto out;
855 :
856 0 : if (flags & MSG_ERRQUEUE)
857 0 : return inet_recv_error(sk, msg, len, addr_len);
858 :
859 0 : skb = skb_recv_datagram(sk, flags, noblock, &err);
860 0 : if (!skb)
861 0 : goto out;
862 :
863 0 : copied = skb->len;
864 0 : if (copied > len) {
865 0 : msg->msg_flags |= MSG_TRUNC;
866 0 : copied = len;
867 : }
868 :
869 : /* Don't bother checking the checksum */
870 0 : err = skb_copy_datagram_msg(skb, 0, msg, copied);
871 0 : if (err)
872 0 : goto done;
873 :
874 0 : sock_recv_timestamp(msg, sk, skb);
875 :
876 : /* Copy the address and add cmsg data. */
877 0 : if (family == AF_INET) {
878 0 : DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
879 :
880 0 : if (sin) {
881 0 : sin->sin_family = AF_INET;
882 0 : sin->sin_port = 0 /* skb->h.uh->source */;
883 0 : sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
884 0 : memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
885 0 : *addr_len = sizeof(*sin);
886 : }
887 :
888 0 : if (isk->cmsg_flags)
889 0 : ip_cmsg_recv(msg, skb);
890 :
891 : #if IS_ENABLED(CONFIG_IPV6)
892 : } else if (family == AF_INET6) {
893 : struct ipv6_pinfo *np = inet6_sk(sk);
894 : struct ipv6hdr *ip6 = ipv6_hdr(skb);
895 : DECLARE_SOCKADDR(struct sockaddr_in6 *, sin6, msg->msg_name);
896 :
897 : if (sin6) {
898 : sin6->sin6_family = AF_INET6;
899 : sin6->sin6_port = 0;
900 : sin6->sin6_addr = ip6->saddr;
901 : sin6->sin6_flowinfo = 0;
902 : if (np->sndflow)
903 : sin6->sin6_flowinfo = ip6_flowinfo(ip6);
904 : sin6->sin6_scope_id =
905 : ipv6_iface_scope_id(&sin6->sin6_addr,
906 : inet6_iif(skb));
907 : *addr_len = sizeof(*sin6);
908 : }
909 :
910 : if (inet6_sk(sk)->rxopt.all)
911 : pingv6_ops.ip6_datagram_recv_common_ctl(sk, msg, skb);
912 : if (skb->protocol == htons(ETH_P_IPV6) &&
913 : inet6_sk(sk)->rxopt.all)
914 : pingv6_ops.ip6_datagram_recv_specific_ctl(sk, msg, skb);
915 : else if (skb->protocol == htons(ETH_P_IP) && isk->cmsg_flags)
916 : ip_cmsg_recv(msg, skb);
917 : #endif
918 : } else {
919 0 : BUG();
920 : }
921 :
922 0 : err = copied;
923 :
924 0 : done:
925 0 : skb_free_datagram(sk, skb);
926 0 : out:
927 0 : pr_debug("ping_recvmsg -> %d\n", err);
928 0 : return err;
929 : }
930 : EXPORT_SYMBOL_GPL(ping_recvmsg);
931 :
932 0 : int ping_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
933 : {
934 0 : pr_debug("ping_queue_rcv_skb(sk=%p,sk->num=%d,skb=%p)\n",
935 : inet_sk(sk), inet_sk(sk)->inet_num, skb);
936 0 : if (sock_queue_rcv_skb(sk, skb) < 0) {
937 0 : kfree_skb(skb);
938 0 : pr_debug("ping_queue_rcv_skb -> failed\n");
939 0 : return -1;
940 : }
941 : return 0;
942 : }
943 : EXPORT_SYMBOL_GPL(ping_queue_rcv_skb);
944 :
945 :
946 : /*
947 : * All we need to do is get the socket.
948 : */
949 :
950 0 : bool ping_rcv(struct sk_buff *skb)
951 : {
952 0 : struct sock *sk;
953 0 : struct net *net = dev_net(skb->dev);
954 0 : struct icmphdr *icmph = icmp_hdr(skb);
955 :
956 : /* We assume the packet has already been checked by icmp_rcv */
957 :
958 0 : pr_debug("ping_rcv(skb=%p,id=%04x,seq=%04x)\n",
959 : skb, ntohs(icmph->un.echo.id), ntohs(icmph->un.echo.sequence));
960 :
961 : /* Push ICMP header back */
962 0 : skb_push(skb, skb->data - (u8 *)icmph);
963 :
964 0 : sk = ping_lookup(net, skb, ntohs(icmph->un.echo.id));
965 0 : if (sk) {
966 0 : struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
967 :
968 0 : pr_debug("rcv on socket %p\n", sk);
969 0 : if (skb2)
970 0 : ping_queue_rcv_skb(sk, skb2);
971 0 : sock_put(sk);
972 0 : return true;
973 : }
974 : pr_debug("no socket, dropping\n");
975 :
976 : return false;
977 : }
978 : EXPORT_SYMBOL_GPL(ping_rcv);
979 :
980 : struct proto ping_prot = {
981 : .name = "PING",
982 : .owner = THIS_MODULE,
983 : .init = ping_init_sock,
984 : .close = ping_close,
985 : .connect = ip4_datagram_connect,
986 : .disconnect = __udp_disconnect,
987 : .setsockopt = ip_setsockopt,
988 : .getsockopt = ip_getsockopt,
989 : .sendmsg = ping_v4_sendmsg,
990 : .recvmsg = ping_recvmsg,
991 : .bind = ping_bind,
992 : .backlog_rcv = ping_queue_rcv_skb,
993 : .release_cb = ip4_datagram_release_cb,
994 : .hash = ping_hash,
995 : .unhash = ping_unhash,
996 : .get_port = ping_get_port,
997 : .obj_size = sizeof(struct inet_sock),
998 : };
999 : EXPORT_SYMBOL(ping_prot);
1000 :
1001 : #ifdef CONFIG_PROC_FS
1002 :
1003 0 : static struct sock *ping_get_first(struct seq_file *seq, int start)
1004 : {
1005 0 : struct sock *sk;
1006 0 : struct ping_iter_state *state = seq->private;
1007 0 : struct net *net = seq_file_net(seq);
1008 :
1009 0 : for (state->bucket = start; state->bucket < PING_HTABLE_SIZE;
1010 0 : ++state->bucket) {
1011 0 : struct hlist_nulls_node *node;
1012 0 : struct hlist_nulls_head *hslot;
1013 :
1014 0 : hslot = &ping_table.hash[state->bucket];
1015 :
1016 0 : if (hlist_nulls_empty(hslot))
1017 0 : continue;
1018 :
1019 0 : sk_nulls_for_each(sk, node, hslot) {
1020 0 : if (net_eq(sock_net(sk), net) &&
1021 0 : sk->sk_family == state->family)
1022 0 : goto found;
1023 : }
1024 : }
1025 : sk = NULL;
1026 0 : found:
1027 0 : return sk;
1028 : }
1029 :
1030 0 : static struct sock *ping_get_next(struct seq_file *seq, struct sock *sk)
1031 : {
1032 0 : struct ping_iter_state *state = seq->private;
1033 0 : struct net *net = seq_file_net(seq);
1034 :
1035 0 : do {
1036 0 : sk = sk_nulls_next(sk);
1037 0 : } while (sk && (!net_eq(sock_net(sk), net)));
1038 :
1039 0 : if (!sk)
1040 0 : return ping_get_first(seq, state->bucket + 1);
1041 : return sk;
1042 : }
1043 :
1044 0 : static struct sock *ping_get_idx(struct seq_file *seq, loff_t pos)
1045 : {
1046 0 : struct sock *sk = ping_get_first(seq, 0);
1047 :
1048 0 : if (sk)
1049 0 : while (pos && (sk = ping_get_next(seq, sk)) != NULL)
1050 0 : --pos;
1051 0 : return pos ? NULL : sk;
1052 : }
1053 :
1054 0 : void *ping_seq_start(struct seq_file *seq, loff_t *pos, sa_family_t family)
1055 : __acquires(ping_table.lock)
1056 : {
1057 0 : struct ping_iter_state *state = seq->private;
1058 0 : state->bucket = 0;
1059 0 : state->family = family;
1060 :
1061 0 : read_lock_bh(&ping_table.lock);
1062 :
1063 0 : return *pos ? ping_get_idx(seq, *pos-1) : SEQ_START_TOKEN;
1064 : }
1065 : EXPORT_SYMBOL_GPL(ping_seq_start);
1066 :
1067 0 : static void *ping_v4_seq_start(struct seq_file *seq, loff_t *pos)
1068 : {
1069 0 : return ping_seq_start(seq, pos, AF_INET);
1070 : }
1071 :
1072 0 : void *ping_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1073 : {
1074 0 : struct sock *sk;
1075 :
1076 0 : if (v == SEQ_START_TOKEN)
1077 0 : sk = ping_get_idx(seq, 0);
1078 : else
1079 0 : sk = ping_get_next(seq, v);
1080 :
1081 0 : ++*pos;
1082 0 : return sk;
1083 : }
1084 : EXPORT_SYMBOL_GPL(ping_seq_next);
1085 :
1086 0 : void ping_seq_stop(struct seq_file *seq, void *v)
1087 : __releases(ping_table.lock)
1088 : {
1089 0 : read_unlock_bh(&ping_table.lock);
1090 0 : }
1091 : EXPORT_SYMBOL_GPL(ping_seq_stop);
1092 :
1093 0 : static void ping_v4_format_sock(struct sock *sp, struct seq_file *f,
1094 : int bucket)
1095 : {
1096 0 : struct inet_sock *inet = inet_sk(sp);
1097 0 : __be32 dest = inet->inet_daddr;
1098 0 : __be32 src = inet->inet_rcv_saddr;
1099 0 : __u16 destp = ntohs(inet->inet_dport);
1100 0 : __u16 srcp = ntohs(inet->inet_sport);
1101 :
1102 0 : seq_printf(f, "%5d: %08X:%04X %08X:%04X"
1103 : " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %u",
1104 0 : bucket, src, srcp, dest, destp, sp->sk_state,
1105 : sk_wmem_alloc_get(sp),
1106 : sk_rmem_alloc_get(sp),
1107 : 0, 0L, 0,
1108 : from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
1109 : 0, sock_i_ino(sp),
1110 0 : refcount_read(&sp->sk_refcnt), sp,
1111 0 : atomic_read(&sp->sk_drops));
1112 0 : }
1113 :
1114 0 : static int ping_v4_seq_show(struct seq_file *seq, void *v)
1115 : {
1116 0 : seq_setwidth(seq, 127);
1117 0 : if (v == SEQ_START_TOKEN)
1118 0 : seq_puts(seq, " sl local_address rem_address st tx_queue "
1119 : "rx_queue tr tm->when retrnsmt uid timeout "
1120 : "inode ref pointer drops");
1121 : else {
1122 0 : struct ping_iter_state *state = seq->private;
1123 :
1124 0 : ping_v4_format_sock(v, seq, state->bucket);
1125 : }
1126 0 : seq_pad(seq, '\n');
1127 0 : return 0;
1128 : }
1129 :
1130 : static const struct seq_operations ping_v4_seq_ops = {
1131 : .start = ping_v4_seq_start,
1132 : .show = ping_v4_seq_show,
1133 : .next = ping_seq_next,
1134 : .stop = ping_seq_stop,
1135 : };
1136 :
1137 1 : static int __net_init ping_v4_proc_init_net(struct net *net)
1138 : {
1139 1 : if (!proc_create_net("icmp", 0444, net->proc_net, &ping_v4_seq_ops,
1140 : sizeof(struct ping_iter_state)))
1141 0 : return -ENOMEM;
1142 : return 0;
1143 : }
1144 :
1145 0 : static void __net_exit ping_v4_proc_exit_net(struct net *net)
1146 : {
1147 0 : remove_proc_entry("icmp", net->proc_net);
1148 0 : }
1149 :
1150 : static struct pernet_operations ping_v4_net_ops = {
1151 : .init = ping_v4_proc_init_net,
1152 : .exit = ping_v4_proc_exit_net,
1153 : };
1154 :
1155 1 : int __init ping_proc_init(void)
1156 : {
1157 1 : return register_pernet_subsys(&ping_v4_net_ops);
1158 : }
1159 :
1160 0 : void ping_proc_exit(void)
1161 : {
1162 0 : unregister_pernet_subsys(&ping_v4_net_ops);
1163 0 : }
1164 :
1165 : #endif
1166 :
1167 1 : void __init ping_init(void)
1168 : {
1169 1 : int i;
1170 :
1171 65 : for (i = 0; i < PING_HTABLE_SIZE; i++)
1172 64 : INIT_HLIST_NULLS_HEAD(&ping_table.hash[i], i);
1173 1 : rwlock_init(&ping_table.lock);
1174 1 : }
|