From: Greg Kroah-Hartman Date: Thu, 22 Jul 2021 15:42:04 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v5.4.135~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=04986ff5f76fd249970ef715cd3e18c9da4fa377;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: ipv6-tcp-drop-silly-icmpv6-packet-too-big-messages.patch tcp-annotate-data-races-around-tp-mtu_info.patch --- diff --git a/queue-4.4/ipv6-tcp-drop-silly-icmpv6-packet-too-big-messages.patch b/queue-4.4/ipv6-tcp-drop-silly-icmpv6-packet-too-big-messages.patch new file mode 100644 index 00000000000..40334f7f830 --- /dev/null +++ b/queue-4.4/ipv6-tcp-drop-silly-icmpv6-packet-too-big-messages.patch @@ -0,0 +1,130 @@ +From c7bb4b89033b764eb07db4e060548a6311d801ee Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 8 Jul 2021 00:21:09 -0700 +Subject: ipv6: tcp: drop silly ICMPv6 packet too big messages +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Eric Dumazet + +commit c7bb4b89033b764eb07db4e060548a6311d801ee upstream. + +While TCP stack scales reasonably well, there is still one part that +can be used to DDOS it. + +IPv6 Packet too big messages have to lookup/insert a new route, +and if abused by attackers, can easily put hosts under high stress, +with many cpus contending on a spinlock while one is stuck in fib6_run_gc() + +ip6_protocol_deliver_rcu() + icmpv6_rcv() + icmpv6_notify() + tcp_v6_err() + tcp_v6_mtu_reduced() + inet6_csk_update_pmtu() + ip6_rt_update_pmtu() + __ip6_rt_update_pmtu() + ip6_rt_cache_alloc() + ip6_dst_alloc() + dst_alloc() + ip6_dst_gc() + fib6_run_gc() + spin_lock_bh() ... + +Some of our servers have been hit by malicious ICMPv6 packets +trying to _increase_ the MTU/MSS of TCP flows. + +We believe these ICMPv6 packets are a result of a bug in one ISP stack, +since they were blindly sent back for _every_ (small) packet sent to them. + +These packets are for one TCP flow: +09:24:36.266491 IP6 Addr1 > Victim ICMP6, packet too big, mtu 1460, length 1240 +09:24:36.266509 IP6 Addr1 > Victim ICMP6, packet too big, mtu 1460, length 1240 +09:24:36.316688 IP6 Addr1 > Victim ICMP6, packet too big, mtu 1460, length 1240 +09:24:36.316704 IP6 Addr1 > Victim ICMP6, packet too big, mtu 1460, length 1240 +09:24:36.608151 IP6 Addr1 > Victim ICMP6, packet too big, mtu 1460, length 1240 + +TCP stack can filter some silly requests : + +1) MTU below IPV6_MIN_MTU can be filtered early in tcp_v6_err() +2) tcp_v6_mtu_reduced() can drop requests trying to increase current MSS. + +This tests happen before the IPv6 routing stack is entered, thus +removing the potential contention and route exhaustion. + +Note that IPv6 stack was performing these checks, but too late +(ie : after the route has been added, and after the potential +garbage collect war) + +v2: fix typo caught by Martin, thanks ! +v3: exports tcp_mtu_to_mss(), caught by David, thanks ! + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Reviewed-by: Maciej Żenczykowski +Cc: Martin KaFai Lau +Acked-by: Martin KaFai Lau +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_output.c | 1 + + net/ipv6/tcp_ipv6.c | 19 +++++++++++++++++-- + 2 files changed, 18 insertions(+), 2 deletions(-) + +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -1353,6 +1353,7 @@ int tcp_mtu_to_mss(struct sock *sk, int + return __tcp_mtu_to_mss(sk, pmtu) - + (tcp_sk(sk)->tcp_header_len - sizeof(struct tcphdr)); + } ++EXPORT_SYMBOL(tcp_mtu_to_mss); + + /* Inverse of above */ + int tcp_mss_to_mtu(struct sock *sk, int mss) +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -308,11 +308,20 @@ failure: + static void tcp_v6_mtu_reduced(struct sock *sk) + { + struct dst_entry *dst; ++ u32 mtu; + + if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) + return; + +- dst = inet6_csk_update_pmtu(sk, READ_ONCE(tcp_sk(sk)->mtu_info)); ++ mtu = READ_ONCE(tcp_sk(sk)->mtu_info); ++ ++ /* Drop requests trying to increase our current mss. ++ * Check done in __ip6_rt_update_pmtu() is too late. ++ */ ++ if (tcp_mtu_to_mss(sk, mtu) >= tcp_sk(sk)->mss_cache) ++ return; ++ ++ dst = inet6_csk_update_pmtu(sk, mtu); + if (!dst) + return; + +@@ -391,6 +400,8 @@ static void tcp_v6_err(struct sk_buff *s + } + + if (type == ICMPV6_PKT_TOOBIG) { ++ u32 mtu = ntohl(info); ++ + /* We are not interested in TCP_LISTEN and open_requests + * (SYN-ACKs send out by Linux are always <576bytes so + * they should go through unfragmented). +@@ -401,7 +412,11 @@ static void tcp_v6_err(struct sk_buff *s + if (!ip6_sk_accept_pmtu(sk)) + goto out; + +- WRITE_ONCE(tp->mtu_info, ntohl(info)); ++ if (mtu < IPV6_MIN_MTU) ++ goto out; ++ ++ WRITE_ONCE(tp->mtu_info, mtu); ++ + if (!sock_owned_by_user(sk)) + tcp_v6_mtu_reduced(sk); + else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, diff --git a/queue-4.4/series b/queue-4.4/series index 838bd7e2536..01041c06b31 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -13,3 +13,5 @@ net-bcmgenet-ensure-all-tx-rx-queues-dmas-are-disabled.patch net-moxa-fix-uaf-in-moxart_mac_probe.patch net-ti-fix-uaf-in-tlan_remove_one.patch net-validate-lwtstate-data-before-returning-from-skb_tunnel_info.patch +tcp-annotate-data-races-around-tp-mtu_info.patch +ipv6-tcp-drop-silly-icmpv6-packet-too-big-messages.patch diff --git a/queue-4.4/tcp-annotate-data-races-around-tp-mtu_info.patch b/queue-4.4/tcp-annotate-data-races-around-tp-mtu_info.patch new file mode 100644 index 00000000000..152cc782ee6 --- /dev/null +++ b/queue-4.4/tcp-annotate-data-races-around-tp-mtu_info.patch @@ -0,0 +1,62 @@ +From 561022acb1ce62e50f7a8258687a21b84282a4cb Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 2 Jul 2021 13:09:03 -0700 +Subject: tcp: annotate data races around tp->mtu_info + +From: Eric Dumazet + +commit 561022acb1ce62e50f7a8258687a21b84282a4cb upstream. + +While tp->mtu_info is read while socket is owned, the write +sides happen from err handlers (tcp_v[46]_mtu_reduced) +which only own the socket spinlock. + +Fixes: 563d34d05786 ("tcp: dont drop MTU reduction indications") +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_ipv4.c | 4 ++-- + net/ipv6/tcp_ipv6.c | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -277,7 +277,7 @@ void tcp_v4_mtu_reduced(struct sock *sk) + + if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) + return; +- mtu = tcp_sk(sk)->mtu_info; ++ mtu = READ_ONCE(tcp_sk(sk)->mtu_info); + dst = inet_csk_update_pmtu(sk, mtu); + if (!dst) + return; +@@ -444,7 +444,7 @@ void tcp_v4_err(struct sk_buff *icmp_skb + if (sk->sk_state == TCP_LISTEN) + goto out; + +- tp->mtu_info = info; ++ WRITE_ONCE(tp->mtu_info, info); + if (!sock_owned_by_user(sk)) { + tcp_v4_mtu_reduced(sk); + } else { +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -312,7 +312,7 @@ static void tcp_v6_mtu_reduced(struct so + if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) + return; + +- dst = inet6_csk_update_pmtu(sk, tcp_sk(sk)->mtu_info); ++ dst = inet6_csk_update_pmtu(sk, READ_ONCE(tcp_sk(sk)->mtu_info)); + if (!dst) + return; + +@@ -401,7 +401,7 @@ static void tcp_v6_err(struct sk_buff *s + if (!ip6_sk_accept_pmtu(sk)) + goto out; + +- tp->mtu_info = ntohl(info); ++ WRITE_ONCE(tp->mtu_info, ntohl(info)); + if (!sock_owned_by_user(sk)) + tcp_v6_mtu_reduced(sk); + else if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED,