hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
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);
....@@ -757,6 +755,11 @@
757755 room = 576;
758756 room -= sizeof(struct iphdr) + icmp_param.replyopts.opt.opt.optlen;
759757 room -= sizeof(struct icmphdr);
758
+ /* Guard against tiny mtu. We need to include at least one
759
+ * IP network header for this message to make any sense.
760
+ */
761
+ if (room <= (int)sizeof(struct iphdr))
762
+ goto ende;
760763
761764 icmp_param.data_len = skb_in->len - icmp_param.offset;
762765 if (icmp_param.data_len > room)
....@@ -818,7 +821,7 @@
818821
819822 static void icmp_socket_deliver(struct sk_buff *skb, u32 info)
820823 {
821
- const struct iphdr *iph = (const struct iphdr *) skb->data;
824
+ const struct iphdr *iph = (const struct iphdr *)skb->data;
822825 const struct net_protocol *ipprot;
823826 int protocol = iph->protocol;
824827
....@@ -887,9 +890,9 @@
887890 case ICMP_FRAG_NEEDED:
888891 /* for documentation of the ip_no_pmtu_disc
889892 * values please see
890
- * Documentation/networking/ip-sysctl.txt
893
+ * Documentation/networking/ip-sysctl.rst
891894 */
892
- switch (net->ipv4.sysctl_ip_no_pmtu_disc) {
895
+ switch (READ_ONCE(net->ipv4.sysctl_ip_no_pmtu_disc)) {
893896 default:
894897 net_dbg_ratelimited("%pI4: fragmentation needed and DF set\n",
895898 &iph->daddr);
....@@ -899,7 +902,7 @@
899902 case 3:
900903 if (!icmp_tag_validation(iph->protocol))
901904 goto out;
902
- /* fall through */
905
+ fallthrough;
903906 case 0:
904907 info = ntohs(icmph->un.frag.mtu);
905908 }
....@@ -977,7 +980,7 @@
977980 return false;
978981 }
979982
980
- icmp_socket_deliver(skb, icmp_hdr(skb)->un.gateway);
983
+ icmp_socket_deliver(skb, ntohl(icmp_hdr(skb)->un.gateway));
981984 return true;
982985 }
983986
....@@ -1150,7 +1153,66 @@
11501153 goto drop;
11511154 }
11521155
1153
-void icmp_err(struct sk_buff *skb, u32 info)
1156
+static bool ip_icmp_error_rfc4884_validate(const struct sk_buff *skb, int off)
1157
+{
1158
+ struct icmp_extobj_hdr *objh, _objh;
1159
+ struct icmp_ext_hdr *exth, _exth;
1160
+ u16 olen;
1161
+
1162
+ exth = skb_header_pointer(skb, off, sizeof(_exth), &_exth);
1163
+ if (!exth)
1164
+ return false;
1165
+ if (exth->version != 2)
1166
+ return true;
1167
+
1168
+ if (exth->checksum &&
1169
+ csum_fold(skb_checksum(skb, off, skb->len - off, 0)))
1170
+ return false;
1171
+
1172
+ off += sizeof(_exth);
1173
+ while (off < skb->len) {
1174
+ objh = skb_header_pointer(skb, off, sizeof(_objh), &_objh);
1175
+ if (!objh)
1176
+ return false;
1177
+
1178
+ olen = ntohs(objh->length);
1179
+ if (olen < sizeof(_objh))
1180
+ return false;
1181
+
1182
+ off += olen;
1183
+ if (off > skb->len)
1184
+ return false;
1185
+ }
1186
+
1187
+ return true;
1188
+}
1189
+
1190
+void ip_icmp_error_rfc4884(const struct sk_buff *skb,
1191
+ struct sock_ee_data_rfc4884 *out,
1192
+ int thlen, int off)
1193
+{
1194
+ int hlen;
1195
+
1196
+ /* original datagram headers: end of icmph to payload (skb->data) */
1197
+ hlen = -skb_transport_offset(skb) - thlen;
1198
+
1199
+ /* per rfc 4884: minimal datagram length of 128 bytes */
1200
+ if (off < 128 || off < hlen)
1201
+ return;
1202
+
1203
+ /* kernel has stripped headers: return payload offset in bytes */
1204
+ off -= hlen;
1205
+ if (off + sizeof(struct icmp_ext_hdr) > skb->len)
1206
+ return;
1207
+
1208
+ out->len = off;
1209
+
1210
+ if (!ip_icmp_error_rfc4884_validate(skb, off))
1211
+ out->flags |= SO_EE_RFC4884_FLAG_INVALID;
1212
+}
1213
+EXPORT_SYMBOL_GPL(ip_icmp_error_rfc4884);
1214
+
1215
+int icmp_err(struct sk_buff *skb, u32 info)
11541216 {
11551217 struct iphdr *iph = (struct iphdr *)skb->data;
11561218 int offset = iph->ihl<<2;
....@@ -1165,13 +1227,15 @@
11651227 */
11661228 if (icmph->type != ICMP_ECHOREPLY) {
11671229 ping_err(skb, offset, info);
1168
- return;
1230
+ return 0;
11691231 }
11701232
11711233 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED)
1172
- ipv4_update_pmtu(skb, net, info, 0, 0, IPPROTO_ICMP, 0);
1234
+ ipv4_update_pmtu(skb, net, info, 0, IPPROTO_ICMP);
11731235 else if (type == ICMP_REDIRECT)
1174
- ipv4_redirect(skb, net, 0, 0, IPPROTO_ICMP, 0);
1236
+ ipv4_redirect(skb, net, 0, IPPROTO_ICMP);
1237
+
1238
+ return 0;
11751239 }
11761240
11771241 /*
....@@ -1314,9 +1378,7 @@
13141378 return 0;
13151379
13161380 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);
1381
+ icmp_sk_exit(net);
13201382 return err;
13211383 }
13221384