From: Greg Kroah-Hartman Date: Thu, 22 Jul 2021 15:58:08 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v5.4.135~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=49996d5340fc47aa900da6a22adb89b03e94dfd6;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-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.14/ipv6-tcp-drop-silly-icmpv6-packet-too-big-messages.patch b/queue-4.14/ipv6-tcp-drop-silly-icmpv6-packet-too-big-messages.patch new file mode 100644 index 00000000000..88ec1a4928e --- /dev/null +++ b/queue-4.14/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 +@@ -1470,6 +1470,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 +@@ -319,11 +319,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; + +@@ -402,6 +411,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). +@@ -412,7 +423,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.14/series b/queue-4.14/series index da4311818f6..55cb18d39e8 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -30,3 +30,5 @@ net-ti-fix-uaf-in-tlan_remove_one.patch net-send-synack-packet-with-accepted-fwmark.patch net-validate-lwtstate-data-before-returning-from-skb_tunnel_info.patch dma-buf-sync_file-don-t-leak-fences-on-merge-failure.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.14/tcp-annotate-data-races-around-tp-mtu_info.patch b/queue-4.14/tcp-annotate-data-races-around-tp-mtu_info.patch new file mode 100644 index 00000000000..562b3e26013 --- /dev/null +++ b/queue-4.14/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 +@@ -285,7 +285,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; +@@ -453,7 +453,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 +@@ -323,7 +323,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; + +@@ -412,7 +412,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,