From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-by2nam01on0132.outbound.protection.outlook.com ([104.47.34.132]:19853 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753956AbeARVAX (ORCPT ); Thu, 18 Jan 2018 16:00:23 -0500 From: Sasha Levin To: "stable@vger.kernel.org" , "stable-commits@vger.kernel.org" CC: Eric Dumazet , "David S . Miller" , Sasha Levin Subject: [added to the 4.1 stable tree] tcp: fix various issues for sockets morphing to listen state Date: Thu, 18 Jan 2018 20:59:44 +0000 Message-ID: <20180118205908.3220-40-alexander.levin@microsoft.com> References: <20180118205908.3220-1-alexander.levin@microsoft.com> In-Reply-To: <20180118205908.3220-1-alexander.levin@microsoft.com> Content-Language: en-US Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org List-ID: From: Eric Dumazet This patch has been added to the stable tree. If you have any objections, please let us know. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D [ Upstream commit 02b2faaf0af1d85585f6d6980e286d53612acfc2 ] Dmitry Vyukov reported a divide by 0 triggered by syzkaller, exploiting tcp_disconnect() path that was never really considered and/or used before syzkaller ;) I was not able to reproduce the bug, but it seems issues here are the three possible actions that assumed they would never trigger on a listener. 1) tcp_write_timer_handler 2) tcp_delack_timer_handler 3) MTU reduction Only IPv6 MTU reduction was properly testing TCP_CLOSE and TCP_LISTEN states from tcp_v6_mtu_reduced() Signed-off-by: Eric Dumazet Reported-by: Dmitry Vyukov Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- net/ipv4/tcp_ipv4.c | 7 +++++-- net/ipv4/tcp_timer.c | 6 ++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 13b92d595138..23ea6cf1a4e5 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -271,10 +271,13 @@ EXPORT_SYMBOL(tcp_v4_connect); */ void tcp_v4_mtu_reduced(struct sock *sk) { - struct dst_entry *dst; struct inet_sock *inet =3D inet_sk(sk); - u32 mtu =3D tcp_sk(sk)->mtu_info; + struct dst_entry *dst; + u32 mtu; =20 + if ((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) + return; + mtu =3D tcp_sk(sk)->mtu_info; dst =3D inet_csk_update_pmtu(sk, mtu); if (!dst) return; diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index c8f97858d6f6..f8c6b2343301 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -223,7 +223,8 @@ void tcp_delack_timer_handler(struct sock *sk) =20 sk_mem_reclaim_partial(sk); =20 - if (sk->sk_state =3D=3D TCP_CLOSE || !(icsk->icsk_ack.pending & ICSK_ACK_= TIMER)) + if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || + !(icsk->icsk_ack.pending & ICSK_ACK_TIMER)) goto out; =20 if (time_after(icsk->icsk_ack.timeout, jiffies)) { @@ -504,7 +505,8 @@ void tcp_write_timer_handler(struct sock *sk) struct inet_connection_sock *icsk =3D inet_csk(sk); int event; =20 - if (sk->sk_state =3D=3D TCP_CLOSE || !icsk->icsk_pending) + if (((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN)) || + !icsk->icsk_pending) goto out; =20 if (time_after(icsk->icsk_timeout, jiffies)) { --=20 2.11.0