hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/net/ipv4/icmp.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * NET3: Implementation of the ICMP protocol layer.
34 *
45 * Alan Cox, <alan@lxorguk.ukuu.org.uk>
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the License, or (at your option) any later version.
106 *
117 * Some of the function names and the icmp unreach table for this
128 * module were derived from [icmp.c 1.0.11 06/02/93] by
....@@ -59,7 +55,6 @@
5955 *
6056 * - Should use skb_pull() instead of all the manual checking.
6157 * This would also greatly simply some upper layer error handlers. --AK
62
- *
6358 */
6459
6560 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -206,7 +201,7 @@
206201 */
207202 static struct sock *icmp_sk(struct net *net)
208203 {
209
- return *this_cpu_ptr(net->ipv4.icmp_sk);
204
+ return this_cpu_read(*net->ipv4.icmp_sk);
210205 }
211206
212207 /* Called with BH disabled */
....@@ -266,11 +261,12 @@
266261 spin_lock(&icmp_global.lock);
267262 delta = min_t(u32, now - icmp_global.stamp, HZ);
268263 if (delta >= HZ / 50) {
269
- incr = sysctl_icmp_msgs_per_sec * delta / HZ ;
264
+ incr = READ_ONCE(sysctl_icmp_msgs_per_sec) * delta / HZ;
270265 if (incr)
271266 WRITE_ONCE(icmp_global.stamp, now);
272267 }
273
- credit = min_t(u32, icmp_global.credit + incr, sysctl_icmp_msgs_burst);
268
+ credit = min_t(u32, icmp_global.credit + incr,
269
+ READ_ONCE(sysctl_icmp_msgs_burst));
274270 if (credit) {
275271 /* We want to use a credit of one in average, but need to randomize
276272 * it for security reasons.
....@@ -294,7 +290,7 @@
294290 return true;
295291
296292 /* Limit if icmp type is enabled in ratemask. */
297
- if (!((1 << type) & net->ipv4.sysctl_icmp_ratemask))
293
+ if (!((1 << type) & READ_ONCE(net->ipv4.sysctl_icmp_ratemask)))
298294 return true;
299295
300296 return false;
....@@ -332,7 +328,8 @@
332328
333329 vif = l3mdev_master_ifindex(dst->dev);
334330 peer = inet_getpeer_v4(net->ipv4.peers, fl4->daddr, vif, 1);
335
- rc = inet_peer_xrlim_allow(peer, net->ipv4.sysctl_icmp_ratelimit);
331
+ rc = inet_peer_xrlim_allow(peer,
332
+ READ_ONCE(net->ipv4.sysctl_icmp_ratelimit));
336333 if (peer)
337334 inet_putpeer(peer);
338335 out:
....@@ -360,7 +357,7 @@
360357
361358 csum = skb_copy_and_csum_bits(icmp_param->skb,
362359 icmp_param->offset + offset,
363
- to, len, 0);
360
+ to, len);
364361
365362 skb->csum = csum_block_add(skb->csum, csum, odd);
366363 if (icmp_pointers[icmp_param->data.icmph.type].error)
....@@ -384,15 +381,15 @@
384381 ip_flush_pending_frames(sk);
385382 } else if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) {
386383 struct icmphdr *icmph = icmp_hdr(skb);
387
- __wsum csum = 0;
384
+ __wsum csum;
388385 struct sk_buff *skb1;
389386
387
+ csum = csum_partial_copy_nocheck((void *)&icmp_param->data,
388
+ (char *)icmph,
389
+ icmp_param->head_len);
390390 skb_queue_walk(&sk->sk_write_queue, skb1) {
391391 csum = csum_add(csum, skb1->csum);
392392 }
393
- csum = csum_partial_copy_nocheck((void *)&icmp_param->data,
394
- (char *)icmph,
395
- icmp_param->head_len, csum);
396393 icmph->checksum = csum_fold(csum);
397394 skb->ip_summed = CHECKSUM_NONE;
398395 ip_push_pending_frames(sk, fl4);
....@@ -435,7 +432,7 @@
435432
436433 ipcm_init(&ipc);
437434 inet->tos = ip_hdr(skb)->tos;
438
- sk->sk_mark = mark;
435
+ ipc.sockc.mark = mark;
439436 daddr = ipc.addr = ip_hdr(skb)->saddr;
440437 saddr = fib_compute_spec_dst(skb);
441438
....@@ -452,7 +449,7 @@
452449 fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
453450 fl4.flowi4_proto = IPPROTO_ICMP;
454451 fl4.flowi4_oif = l3mdev_master_ifindex(skb->dev);
455
- security_skb_classify_flow(skb, flowi4_to_flowi(&fl4));
452
+ security_skb_classify_flow(skb, flowi4_to_flowi_common(&fl4));
456453 rt = ip_route_output_key(net, &fl4);
457454 if (IS_ERR(rt))
458455 goto out_unlock;
....@@ -508,7 +505,7 @@
508505 route_lookup_dev = icmp_get_route_lookup_dev(skb_in);
509506 fl4->flowi4_oif = l3mdev_master_ifindex(route_lookup_dev);
510507
511
- security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4));
508
+ security_skb_classify_flow(skb_in, flowi4_to_flowi_common(fl4));
512509 rt = ip_route_output_key_hash(net, fl4, skb_in);
513510 if (IS_ERR(rt))
514511 return rt;
....@@ -710,15 +707,16 @@
710707 dev = dev_get_by_index_rcu(net, inet_iif(skb_in));
711708
712709 if (dev)
713
- saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK);
710
+ saddr = inet_select_addr(dev, iph->saddr,
711
+ RT_SCOPE_LINK);
714712 else
715713 saddr = 0;
716714 rcu_read_unlock();
717715 }
718716
719
- tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) |
717
+ tos = icmp_pointers[type].error ? (RT_TOS(iph->tos) |
720718 IPTOS_PREC_INTERNETCONTROL) :
721
- iph->tos;
719
+ iph->tos;
722720 mark = IP4_REPLY_MARK(net, skb_in->mark);
723721
724722 if (__ip_options_echo(net, &icmp_param.replyopts.opt.opt, skb_in, opt))
....@@ -736,10 +734,10 @@
736734 icmp_param.skb = skb_in;
737735 icmp_param.offset = skb_network_offset(skb_in);
738736 inet_sk(sk)->tos = tos;
739
- sk->sk_mark = mark;
740737 ipcm_init(&ipc);
741738 ipc.addr = iph->saddr;
742739 ipc.opt = &icmp_param.replyopts.opt;
740
+ ipc.sockc.mark = mark;
743741
744742 rt = icmp_route_lookup(net, &fl4, skb_in, iph, saddr, tos, mark,
745743 type, code, &icmp_param);
....@@ -818,7 +816,7 @@
818816
819817 static void icmp_socket_deliver(struct sk_buff *skb, u32 info)
820818 {
821
- const struct iphdr *iph = (const struct iphdr *) skb->data;
819
+ const struct iphdr *iph = (const struct iphdr *)skb->data;
822820 const struct net_protocol *ipprot;
823821 int protocol = iph->protocol;
824822
....@@ -887,9 +885,9 @@
887885 case ICMP_FRAG_NEEDED:
888886 /* for documentation of the ip_no_pmtu_disc
889887 * values please see
890
- * Documentation/networking/ip-sysctl.txt
888
+ * Documentation/networking/ip-sysctl.rst
891889 */
892
- switch (net->ipv4.sysctl_ip_no_pmtu_disc) {
890
+ switch (READ_ONCE(net->ipv4.sysctl_ip_no_pmtu_disc)) {
893891 default:
894892 net_dbg_ratelimited("%pI4: fragmentation needed and DF set\n",
895893 &iph->daddr);
....@@ -899,7 +897,7 @@
899897 case 3:
900898 if (!icmp_tag_validation(iph->protocol))
901899 goto out;
902
- /* fall through */
900
+ fallthrough;
903901 case 0:
904902 info = ntohs(icmph->un.frag.mtu);
905903 }
....@@ -977,7 +975,7 @@
977975 return false;
978976 }
979977
980
- icmp_socket_deliver(skb, icmp_hdr(skb)->un.gateway);
978
+ icmp_socket_deliver(skb, ntohl(icmp_hdr(skb)->un.gateway));
981979 return true;
982980 }
983981
....@@ -1150,7 +1148,66 @@
11501148 goto drop;
11511149 }
11521150
1153
-void icmp_err(struct sk_buff *skb, u32 info)
1151
+static bool ip_icmp_error_rfc4884_validate(const struct sk_buff *skb, int off)
1152
+{
1153
+ struct icmp_extobj_hdr *objh, _objh;
1154
+ struct icmp_ext_hdr *exth, _exth;
1155
+ u16 olen;
1156
+
1157
+ exth = skb_header_pointer(skb, off, sizeof(_exth), &_exth);
1158
+ if (!exth)
1159
+ return false;
1160
+ if (exth->version != 2)
1161
+ return true;
1162
+
1163
+ if (exth->checksum &&
1164
+ csum_fold(skb_checksum(skb, off, skb->len - off, 0)))
1165
+ return false;
1166
+
1167
+ off += sizeof(_exth);
1168
+ while (off < skb->len) {
1169
+ objh = skb_header_pointer(skb, off, sizeof(_objh), &_objh);
1170
+ if (!objh)
1171
+ return false;
1172
+
1173
+ olen = ntohs(objh->length);
1174
+ if (olen < sizeof(_objh))
1175
+ return false;
1176
+
1177
+ off += olen;
1178
+ if (off > skb->len)
1179
+ return false;
1180
+ }
1181
+
1182
+ return true;
1183
+}
1184
+
1185
+void ip_icmp_error_rfc4884(const struct sk_buff *skb,
1186
+ struct sock_ee_data_rfc4884 *out,
1187
+ int thlen, int off)
1188
+{
1189
+ int hlen;
1190
+
1191
+ /* original datagram headers: end of icmph to payload (skb->data) */
1192
+ hlen = -skb_transport_offset(skb) - thlen;
1193
+
1194
+ /* per rfc 4884: minimal datagram length of 128 bytes */
1195
+ if (off < 128 || off < hlen)
1196
+ return;
1197
+
1198
+ /* kernel has stripped headers: return payload offset in bytes */
1199
+ off -= hlen;
1200
+ if (off + sizeof(struct icmp_ext_hdr) > skb->len)
1201
+ return;
1202
+
1203
+ out->len = off;
1204
+
1205
+ if (!ip_icmp_error_rfc4884_validate(skb, off))
1206
+ out->flags |= SO_EE_RFC4884_FLAG_INVALID;
1207
+}
1208
+EXPORT_SYMBOL_GPL(ip_icmp_error_rfc4884);
1209
+
1210
+int icmp_err(struct sk_buff *skb, u32 info)
11541211 {
11551212 struct iphdr *iph = (struct iphdr *)skb->data;
11561213 int offset = iph->ihl<<2;
....@@ -1165,13 +1222,15 @@
11651222 */
11661223 if (icmph->type != ICMP_ECHOREPLY) {
11671224 ping_err(skb, offset, info);
1168
- return;
1225
+ return 0;
11691226 }
11701227
11711228 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
1172
- ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ICMP, 0);
1229
+ ipv4_update_pmtu(skb, net, info, 0, IPPROTO_ICMP);
11731230 else if (type == ICMP_REDIRECT)
1174
- ipv4_redirect(skb, net, 0, 0, IPPROTO_ICMP, 0);
1231
+ ipv4_redirect(skb, net, 0, IPPROTO_ICMP);
1232
+
1233
+ return 0;
11751234 }
11761235
11771236 /*
....@@ -1314,9 +1373,7 @@
13141373 return 0;
13151374
13161375 fail:
1317
- for_each_possible_cpu(i)
1318
- inet_ctl_sock_destroy(*per_cpu_ptr(net->ipv4.icmp_sk, i));
1319
- free_percpu(net->ipv4.icmp_sk);
1376
+ icmp_sk_exit(net);
13201377 return err;
13211378 }
13221379