Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp341025ybl; Fri, 9 Aug 2019 06:51:02 -0700 (PDT) X-Google-Smtp-Source: APXvYqyu4RBzGZpdo9h9YSng6I6ozRC4R3OCVDa4Xin1OMkoUot4NEorKOmVb4Q3sbzwcWzjNgev X-Received: by 2002:a65:4489:: with SMTP id l9mr18077473pgq.207.1565358662005; Fri, 09 Aug 2019 06:51:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1565358661; cv=none; d=google.com; s=arc-20160816; b=BGzhuxOUMfIiFAVUpBPxHLl7I9Xn0vHZttE52c+L4F+YOHaI6cflGzecvGau+W54Yb 89aB+GkDm+Jq/orzarkXBMH4I/C09qyndNMv3YyTaiOjLa9omu4svnxa6VTnE1YpL/ez N/Lj10QUbzZj1ywUDfK2ck8UYI4QQIN69gYr6KBbQFUDPKLfOMbZOFRJsvjWt4h13tjE A+Fa+Q4dXNaj127NPfBpLYghELEt+Oulcbzyxrf7Pa+a/oVp+qo+lD5IcwlI1ZWe6jXA h4N5MD/SlaC+T7+My8mvNIzMGQS+vJO05AW23SSxbp6FEDpqzc5AjejF3bALkbGQ5A1T lvcQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=icIg0ffDUisXCYO46seotriJ9cHW3hHbenPYznMXuUk=; b=fzNqNAtY6slDu7aPj1SDXkgYQVTg0JauqoVppXBUXKhfv7mVF930Dm0pFX/bNJbGr9 M6d1yxpJr7OnPlnOTGg1217oF4FYiGZrVTlQd5Gi4J3wmrlvaXMimvhtXQcXZcIqq1aq ChROXe8Z/FLHN/J9wPK5lH6fNpaV63efMmn+0Ibhc4/TjlyPHcKYvQtX7P7NleCDQzum gokayVhKi5m2aOgOgpcm1v+TtmSfEKZ5iDiFaAsdwn0MODzOFjfdqVP56Vhhq12nulAB TxV99Zc4U87iggbnw6Ik9cSRRmQMxmc0M8ehc/Z6hZPEi/CZZQ0oinuEbDh9ISW0jhGJ pHNQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=WJUs7m8s; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id b17si20689500pgw.519.2019.08.09.06.50.45; Fri, 09 Aug 2019 06:51:01 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=WJUs7m8s; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2406976AbfHINsI (ORCPT + 99 others); Fri, 9 Aug 2019 09:48:08 -0400 Received: from mail.kernel.org ([198.145.29.99]:38214 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2436666AbfHINsC (ORCPT ); Fri, 9 Aug 2019 09:48:02 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 887972086D; Fri, 9 Aug 2019 13:48:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1565358482; bh=wghxmeAPHzsujAz79/ipyVQr0oFzQXLpRvGjhXLRHZM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WJUs7m8sN3ZUh0mxuG9PdGwo4OA2F62sfS8Fjvy+26WMothE2wmDiujmSn903TxVd lgnN5JcfkDtvXmWbkg1zRtE6v13FbV3n4nmjRKxji05yr/g139SVMQkErvpuJx9qL7 NWTaV0Biid+tn1bIpsP3r7Lp14P6f/y2t2U1jo1I= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Eric Dumazet , Andrew Prout , Jonathan Lemon , Michal Kubecek , Neal Cardwell , Yuchung Cheng , Christoph Paasch , Jonathan Looney , "David S. Miller" , Sasha Levin Subject: [PATCH 4.9 07/32] tcp: be more careful in tcp_fragment() Date: Fri, 9 Aug 2019 15:45:10 +0200 Message-Id: <20190809133923.184065453@linuxfoundation.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190809133922.945349906@linuxfoundation.org> References: <20190809133922.945349906@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org [ Upstream commit b617158dc096709d8600c53b6052144d12b89fab ] Some applications set tiny SO_SNDBUF values and expect TCP to just work. Recent patches to address CVE-2019-11478 broke them in case of losses, since retransmits might be prevented. We should allow these flows to make progress. This patch allows the first and last skb in retransmit queue to be split even if memory limits are hit. It also adds the some room due to the fact that tcp_sendmsg() and tcp_sendpage() might overshoot sk_wmem_queued by about one full TSO skb (64KB size). Note this allowance was already present in stable backports for kernels < 4.15 Note for < 4.15 backports : tcp_rtx_queue_tail() will probably look like : static inline struct sk_buff *tcp_rtx_queue_tail(const struct sock *sk) { struct sk_buff *skb = tcp_send_head(sk); return skb ? tcp_write_queue_prev(sk, skb) : tcp_write_queue_tail(sk); } Fixes: f070ef2ac667 ("tcp: tcp_fragment() should apply sane memory limits") Signed-off-by: Eric Dumazet Reported-by: Andrew Prout Tested-by: Andrew Prout Tested-by: Jonathan Lemon Tested-by: Michal Kubecek Acked-by: Neal Cardwell Acked-by: Yuchung Cheng Acked-by: Christoph Paasch Cc: Jonathan Looney Signed-off-by: David S. Miller Signed-off-by: Sasha Levin --- include/net/tcp.h | 17 +++++++++++++++++ net/ipv4/tcp_output.c | 11 ++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 1eda31f7f013b..a474213ca015b 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1595,6 +1595,23 @@ static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unli tcp_sk(sk)->highest_sack = NULL; } +static inline struct sk_buff *tcp_rtx_queue_head(const struct sock *sk) +{ + struct sk_buff *skb = tcp_write_queue_head(sk); + + if (skb == tcp_send_head(sk)) + skb = NULL; + + return skb; +} + +static inline struct sk_buff *tcp_rtx_queue_tail(const struct sock *sk) +{ + struct sk_buff *skb = tcp_send_head(sk); + + return skb ? tcp_write_queue_prev(sk, skb) : tcp_write_queue_tail(sk); +} + static inline void __tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb) { __skb_queue_tail(&sk->sk_write_queue, skb); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 0c195b0f42169..9ddb05b98312c 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1175,6 +1175,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *buff; int nsize, old_factor; + long limit; int nlen; u8 flags; @@ -1185,7 +1186,15 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, if (nsize < 0) nsize = 0; - if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf + 0x20000)) { + /* tcp_sendmsg() can overshoot sk_wmem_queued by one full size skb. + * We need some allowance to not penalize applications setting small + * SO_SNDBUF values. + * Also allow first and last skb in retransmit queue to be split. + */ + limit = sk->sk_sndbuf + 2 * SKB_TRUESIZE(GSO_MAX_SIZE); + if (unlikely((sk->sk_wmem_queued >> 1) > limit && + skb != tcp_rtx_queue_head(sk) && + skb != tcp_rtx_queue_tail(sk))) { NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG); return -ENOMEM; } -- 2.20.1