Received: by 2002:ac0:946b:0:0:0:0:0 with SMTP id j40csp245173imj; Thu, 7 Feb 2019 03:43:57 -0800 (PST) X-Google-Smtp-Source: AHgI3Iamg3cDaVDPyXW3VFsV2TLEH12cl3kZszIHo5YitMeajyM+laeGLlDHJoM6dAys55B4HyYj X-Received: by 2002:a17:902:7683:: with SMTP id m3mr3414797pll.191.1549539837791; Thu, 07 Feb 2019 03:43:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549539837; cv=none; d=google.com; s=arc-20160816; b=xn2D1U7K7UU+M02sSDZ/BevcKdVK/kYSuhwQG0oyb5jG8nxwEdGzPFbK9ymdOk3e0W b4TAnzD5jhaPwZRffWpt0kApm2492UgUwdZ6gJ2mMRSSM/JWP+3ls2Jqufv87DuZEMm+ +hGnnytLXPag7Z8wTXPJjCNNy1KD9sNhKDBYnsTDWoYpPDq33HUFngNkNKGXj5qViN4G n7vMtHU7pkB93hTlNnWYQVT4kp9QBzKsq+HAyIpI3A1j9iRALshXYww7Ss7jV7jA+4x6 RjZOL9DSxGZ3opWo2BUxweqAyYED2oheBRGkSAY8FJTj9o4zQ3vzu/7AWMxRdJJk09JC Hwmw== 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=cA6Y1f5pTbAyWbg6//qyJFU9glZFq14d5exdPNETq38=; b=rlq+NvYaO9bTxDCUN+jdpXkKbQUET91+fsSvnSp7dKNlMLX4ALm5Gte0zeaJrNH0Jz 1f4w5hwd7/HSxSTj4AthNqZf5GO4+HICWRoQ5ioVBoe5B+WeDpEgd2PhisMlbWionY0l Eu5JdW37qw/b7IXRcJ/dDsNi7j79csIy1WqfPnc2yyyyn5kOUbb5ov/C5jcOuv/A1CCW bzUJ63lYsNp/mZjr4TfoOkbS2pVgLr4dNfRP6jP9Fg+G29RcS3hc2V7f6hIk9mk19wMq 0pXZDIl+vU1p3SDN/n4gXKaZ8pE5/hC0ddZzLj8OQewY8Ywrz8Oa7mtO2nHBNj6lnhLB 4Jng== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=jrUxvZCc; 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 m63si9319726pld.132.2019.02.07.03.43.42; Thu, 07 Feb 2019 03:43:57 -0800 (PST) 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=jrUxvZCc; 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 S1727320AbfBGLnG (ORCPT + 99 others); Thu, 7 Feb 2019 06:43:06 -0500 Received: from mail.kernel.org ([198.145.29.99]:33210 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727300AbfBGLnF (ORCPT ); Thu, 7 Feb 2019 06:43:05 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.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 B3F5B21907; Thu, 7 Feb 2019 11:43:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1549539784; bh=eHKBfYoxOgh7HqC6fevUYoC3uJ6dzDnzXQnRQUk2T0A=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jrUxvZCcSKX+XlFljsDABt2Akm9O7x4JOBgvmiC2M8xs91aIKMkqPf6HcXzbTlJrJ 0KlXlrGOn5iqlR3NJ9Qb5hIH6RdxY8dJe5GNJZ1QEjj+5GQS+8+pbvByPpCroU6Uh8 hQ1Zd5Big58Ii/1Upao3OIVAhyDxsXtke7w5otrs= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "David S. Miller" , Peter Oskolkov , Eric Dumazet , Florian Westphal , Stephen Hemminger , Mao Wenan , Ben Hutchings Subject: [PATCH 4.4 22/34] ip: discard IPv4 datagrams with overlapping segments. Date: Thu, 7 Feb 2019 12:42:04 +0100 Message-Id: <20190207113026.434645173@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190207113025.552605181@linuxfoundation.org> References: <20190207113025.552605181@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore 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.4-stable review patch. If anyone has any objections, please let me know. ------------------ From: Peter Oskolkov commit 7969e5c40dfd04799d4341f1b7cd266b6e47f227 upstream. 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 Signed-off-by: Mao Wenan [bwh: Backported to 4.4: - s/__IP_INC_STATS/IP_INC_STATS_BH/ - Deleted code is slightly different] Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman --- include/uapi/linux/snmp.h | 1 net/ipv4/ip_fragment.c | 72 ++++++++++++---------------------------------- net/ipv4/proc.c | 1 3 files changed, 22 insertions(+), 52 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 @@ -277,6 +277,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; @@ -357,60 +358,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) { - /* Eat head of the next overlapped fragment - * and leave the loop. The next ones cannot overlap. - */ - if (!pskb_pull(next, i)) - goto err; - 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; @@ -458,6 +422,10 @@ found: skb_dst_drop(skb); return -EINPROGRESS; +discard_qp: + inet_frag_kill(&qp->q); + err = -EINVAL; + IP_INC_STATS_BH(net, IPSTATS_MIB_REASM_OVERLAPS); err: kfree_skb(skb); return err; --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c @@ -132,6 +132,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 };