Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp5453596imm; Tue, 16 Oct 2018 10:27:05 -0700 (PDT) X-Google-Smtp-Source: ACcGV606EoTD3ZdRKwZtLrjDiUesV8DHREFuXf4obLpM5bfaWbfLWn9lnl5SboQyP7N4YUIFknjf X-Received: by 2002:a63:1624:: with SMTP id w36-v6mr20538943pgl.409.1539710825425; Tue, 16 Oct 2018 10:27:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539710825; cv=none; d=google.com; s=arc-20160816; b=pf6f+Wf4+fH10n3DGh1QSuTqBd8dGLeDKGROU2er8LQUdVWpquDzEF6xsQk7J6cuJm 8QSqekRlU1UQoOYHAi7jYBeOWSLdjcg2jWz+RyG+6y0w3WAylU6RMudFQg31pdq8bICX S7JbBNEiKTcG+mtGXIAmz4EoqCpi6bS8D3M7poFcg+IXnxavvm2XnEVEKoyVPNxN1Daa oaDIYrg8ftbzK73LcePRAU69xefh+smUJxNitt1Ddtl2wwvOAOh0r/DO6RqygU0oSAO7 ZJN6aKjvaruV9qbFcaNDoo5h4nMAiSuOZOq9Q5jDbfKkfUP3H58pydRQ9NOkI1QgIbD6 0fEA== 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=wJOgKJUIJNg1XuODkRN1VmuPybhWJr2ha+9xHLYVrS8=; b=SHSY42W4SR2n20OeWuR01QRM2MDDn0QVvyf3MwMIlU2BKsICG9AMOn9RATw+O9/HLj JmqhTfS/jAkZsDtdcyVFifYxNQy9/LvYcib4II1ZyW5VMlR2zxRAUtieWgxHpljWkgNY ggEV0T+VlmOjS0bxnTJLr4ohd8GuIezKsQDsLAiUOhhZE8r+lg+1smHOuHOCUMkRP/BW 6nLA66W1Opc3dRh2iqt0j/2tg20UNMfjDPdSqYyP97xxxn8GAxIs6En9wcIB9EBbSces ECGo5+TWNumfS0FrEudSN25WcXFIlw3JI6TOVDhLpg5vVojloyKOy7BgP8qa6Mss3t5V lcUg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b="b/+PqLen"; 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 k6-v6si14304592pls.174.2018.10.16.10.26.49; Tue, 16 Oct 2018 10:27:05 -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="b/+PqLen"; 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 S1731881AbeJQBQf (ORCPT + 99 others); Tue, 16 Oct 2018 21:16:35 -0400 Received: from mail.kernel.org ([198.145.29.99]:35258 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730396AbeJQBQe (ORCPT ); Tue, 16 Oct 2018 21:16:34 -0400 Received: from localhost (ip-213-127-77-176.ip.prioritytelecom.net [213.127.77.176]) (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 F3A2B20658; Tue, 16 Oct 2018 17:25:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1539710708; bh=UGo6ONMXMNCFmMn5h5v+fXtqdnrfH9AmmDWAmr+76o0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=b/+PqLenmUfAy6VTlTg71FXV1nQchKmXGMQXP5MGD2NfpZYaLqtcqL5m+vF5jvlNe /NX5suPBiZxVwqOO1f1ra+Kz+Xh88uK+DQp4jheI7o2h89clgEH+eLlEYKtLQ/Rjy+ dA56csiEIIBY4qCSc5AbMsjTJj3X7VWUYF8NxZSo= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, netdev@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "David S. Miller" , Peter Oskolkov , Eric Dumazet , Florian Westphal , Stephen Hemminger Subject: [PATCH 4.9 61/71] ip: discard IPv4 datagrams with overlapping segments. Date: Tue, 16 Oct 2018 19:09:58 +0200 Message-Id: <20181016170542.451084535@linuxfoundation.org> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181016170539.315587743@linuxfoundation.org> References: <20181016170539.315587743@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review 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 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Peter Oskolkov This behavior is required in IPv6, and there is little need to tolerate overlapping fragments in IPv4. This change simplifies the code and eliminates potential DDoS attack vectors. Tested: ran ip_defrag selftest (not yet available uptream). Suggested-by: David S. Miller Signed-off-by: Peter Oskolkov Signed-off-by: Eric Dumazet Cc: Florian Westphal Acked-by: Stephen Hemminger Signed-off-by: David S. Miller (cherry picked from commit 7969e5c40dfd04799d4341f1b7cd266b6e47f227) Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/snmp.h | 1 net/ipv4/ip_fragment.c | 77 +++++++++++----------------------------------- net/ipv4/proc.c | 1 3 files changed, 22 insertions(+), 57 deletions(-) --- a/include/uapi/linux/snmp.h +++ b/include/uapi/linux/snmp.h @@ -55,6 +55,7 @@ enum IPSTATS_MIB_ECT1PKTS, /* InECT1Pkts */ IPSTATS_MIB_ECT0PKTS, /* InECT0Pkts */ IPSTATS_MIB_CEPKTS, /* InCEPkts */ + IPSTATS_MIB_REASM_OVERLAPS, /* ReasmOverlaps */ __IPSTATS_MIB_MAX }; --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -275,6 +275,7 @@ static int ip_frag_reinit(struct ipq *qp /* Add new segment to existing queue. */ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) { + struct net *net = container_of(qp->q.net, struct net, ipv4.frags); struct sk_buff *prev, *next; struct net_device *dev; unsigned int fragsize; @@ -355,65 +356,23 @@ static int ip_frag_queue(struct ipq *qp, } found: - /* We found where to put this one. Check for overlap with - * preceding fragment, and, if needed, align things so that - * any overlaps are eliminated. + /* RFC5722, Section 4, amended by Errata ID : 3089 + * When reassembling an IPv6 datagram, if + * one or more its constituent fragments is determined to be an + * overlapping fragment, the entire datagram (and any constituent + * fragments) MUST be silently discarded. + * + * We do the same here for IPv4. */ - if (prev) { - int i = (prev->ip_defrag_offset + prev->len) - offset; - if (i > 0) { - offset += i; - err = -EINVAL; - if (end <= offset) - goto err; - err = -ENOMEM; - if (!pskb_pull(skb, i)) - goto err; - if (skb->ip_summed != CHECKSUM_UNNECESSARY) - skb->ip_summed = CHECKSUM_NONE; - } - } - - err = -ENOMEM; - - while (next && next->ip_defrag_offset < end) { - int i = end - next->ip_defrag_offset; /* overlap is 'i' bytes */ - - if (i < next->len) { - int delta = -next->truesize; - - /* Eat head of the next overlapped fragment - * and leave the loop. The next ones cannot overlap. - */ - if (!pskb_pull(next, i)) - goto err; - delta += next->truesize; - if (delta) - add_frag_mem_limit(qp->q.net, delta); - next->ip_defrag_offset += i; - qp->q.meat -= i; - if (next->ip_summed != CHECKSUM_UNNECESSARY) - next->ip_summed = CHECKSUM_NONE; - break; - } else { - struct sk_buff *free_it = next; - - /* Old fragment is completely overridden with - * new one drop it. - */ - next = next->next; - - if (prev) - prev->next = next; - else - qp->q.fragments = next; - - qp->q.meat -= free_it->len; - sub_frag_mem_limit(qp->q.net, free_it->truesize); - kfree_skb(free_it); - } - } + /* Is there an overlap with the previous fragment? */ + if (prev && + (prev->ip_defrag_offset + prev->len) > offset) + goto discard_qp; + + /* Is there an overlap with the next fragment? */ + if (next && next->ip_defrag_offset < end) + goto discard_qp; /* Note : skb->ip_defrag_offset and skb->dev share the same location */ dev = skb->dev; @@ -461,6 +420,10 @@ found: skb_dst_drop(skb); return -EINPROGRESS; +discard_qp: + inet_frag_kill(&qp->q); + err = -EINVAL; + __IP_INC_STATS(net, IPSTATS_MIB_REASM_OVERLAPS); err: kfree_skb(skb); return err; --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -134,6 +134,7 @@ static const struct snmp_mib snmp4_ipext SNMP_MIB_ITEM("InECT1Pkts", IPSTATS_MIB_ECT1PKTS), SNMP_MIB_ITEM("InECT0Pkts", IPSTATS_MIB_ECT0PKTS), SNMP_MIB_ITEM("InCEPkts", IPSTATS_MIB_CEPKTS), + SNMP_MIB_ITEM("ReasmOverlaps", IPSTATS_MIB_REASM_OVERLAPS), SNMP_MIB_SENTINEL };