Received: by 2002:a25:b794:0:0:0:0:0 with SMTP id n20csp7232442ybh; Thu, 8 Aug 2019 12:13:09 -0700 (PDT) X-Google-Smtp-Source: APXvYqyIOgrIDQokUHgaOGhSip6g7gGrq3u/o+zTiw144ozMGWa+MhQFP18QFuzSSQ2kk3xK8t2R X-Received: by 2002:a17:90a:ba94:: with SMTP id t20mr5659431pjr.8.1565291589522; Thu, 08 Aug 2019 12:13:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1565291589; cv=none; d=google.com; s=arc-20160816; b=ybLCS4Q16UvD3noS6RwvDki50cWP2nnN5OI67/5tCZRU0CitQIwKHBZh7OjnFq5Uyv nHMPdjJkWTHPS646J8RFU/e0YY53QTFL+2bApUGd1a9OB+G1A5LD3MKD3r7BNwOLJoEL d+LOylP4z3Mf+fvJtDDUa+73sWYCeFF3ONe26Rq74PXaKnsb00AZIfBFkk40Xg1Ee0k3 C7gfW4YGWFZTzMT2w7ZVxP6q7/iyMC6tMlytLMvz4ciLDdRnv6S6fy4Rptky01OBxB1l 0GL4aWZnP0+F2nIgiOFCZrnHCiUGDFQk9/dgpaRi58jgJNAWaq22ixoIPJw8S3lfArgl O9tg== 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=XwXBsX5iyxBrCT+3SB3IXqMdmJ3Dvs21cY9U6OV/PiQ=; b=Gr7xj6F/IGQofeK6DUxvuoyFzYKeKqtuCijL8NxcBHflMpfrgmFbpKYzbnGH6xOhZe LsMufpgj29jEiQY+hhiZy67yoAdoC6DPRfCFywffWZwUEdczyBnXERHgfi8m0ImkverK suKiYhS1NhuqsMs0UZx0gopVbkGjXHvK+t1avX/qfZTH26H/UNbS3IyICdHgborKhJQQ 8wPIiNHjC5lvCxLa7fLiUcyGoIV8Ie+pcZlSXCSiNAhQ4mL4V6dekRCnaKNLRX6W++db xydwl9keVKJ/KZSlyc1/dUxEZR1vsj0ghLn479i1y9RI5cE0hrWw+QA5bZeQg3XLGmIq I5nA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=TZrLHrKA; 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 a59si50092730plc.319.2019.08.08.12.12.54; Thu, 08 Aug 2019 12:13:09 -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=TZrLHrKA; 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 S2405431AbfHHTLK (ORCPT + 99 others); Thu, 8 Aug 2019 15:11:10 -0400 Received: from mail.kernel.org ([198.145.29.99]:45676 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2405037AbfHHTLJ (ORCPT ); Thu, 8 Aug 2019 15:11:09 -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 8041721743; Thu, 8 Aug 2019 19:11:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1565291468; bh=Bt6EXsV6kBA3caCwt88SS2syaHLHgL7Yw6ffF4xTHHY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TZrLHrKAIPdo79fRKedb9uIIhl5hjOeDpcDw/QUmuVYPq2Y+el+czroF83tqFNtbf rWXFSW71YcazPuAbj+KySt2OQ7CpD8pFDrRtXm8iTVpyHXj0JU1RRxdhUlU5WAfz6Z PcMYmevkkCHMsTJ+ipb18ZsXiDI83vazYLBXWdIw= 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" , Matthieu Baerts , Sasha Levin Subject: [PATCH 4.14 04/33] tcp: be more careful in tcp_fragment() Date: Thu, 8 Aug 2019 21:05:11 +0200 Message-Id: <20190808190453.790722103@linuxfoundation.org> X-Mailer: git-send-email 2.22.0 In-Reply-To: <20190808190453.582417307@linuxfoundation.org> References: <20190808190453.582417307@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 commit b617158dc096709d8600c53b6052144d12b89fab upstream. 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: Matthieu Baerts 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 0b477a1e11770..7994e569644e0 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1688,6 +1688,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 a5960b9b6741c..a99086bf26eaf 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1264,6 +1264,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; @@ -1274,7 +1275,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