From patchwork Fri Jan 12 06:04:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Subash Abhinov Kasiviswanathan X-Patchwork-Id: 859524 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netfilter-devel-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=codeaurora.org header.i=@codeaurora.org header.b="cXYZFXXX"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=codeaurora.org header.i=@codeaurora.org header.b="dFxa++S+"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zHsfX5pKXz9t3p for ; Fri, 12 Jan 2018 17:05:08 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754293AbeALGFH (ORCPT ); Fri, 12 Jan 2018 01:05:07 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:44576 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754259AbeALGFF (ORCPT ); Fri, 12 Jan 2018 01:05:05 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 6EC6C60BF9; Fri, 12 Jan 2018 06:05:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1515737104; bh=nwKdYEuFlXRs0Ex90sLe8ffWOBt9BIuzKOdpiPuRs70=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cXYZFXXX9bgDQ1nLcIn4sZJfNVdRTwjMhJ+Sxk6eTFUmHqArsVnsx6T+gLeBo/2nt Lyr1fqQv1zkZNigb1r8UAJD7yfCzIjEfyFhlBvARRpQYjabHh9nufMd+fST7bjBk3e vq/f5fU9YJULo3prCTM3M7jpG+mt2ffiXiQExsm8= X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on pdx-caf-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.8 required=2.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED, T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0 Received: from subashab-lnx.qualcomm.com (unknown [129.46.15.92]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: subashab@codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id 077DB60BDF; Fri, 12 Jan 2018 06:05:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1515737102; bh=nwKdYEuFlXRs0Ex90sLe8ffWOBt9BIuzKOdpiPuRs70=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dFxa++S+syninb/udGwM7trQXLVs+BU+Y05g0vk8dMDjwlB4z2bpV+TtE7yGwILKz vdEE2jeTUKzqc0W0lCKjpu3dtPYNbTZVz2rSB9W5anRfSR0ecsxMcNKkFUiuRkd4hC ABHen0VK++JruGJj4ACNJ3r7ebZZD3Y9UyNCmQxQ= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 077DB60BDF Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=subashab@codeaurora.org From: Subash Abhinov Kasiviswanathan To: pablo@netfilter.org, netfilter-devel@vger.kernel.org, fw@strlen.de Cc: Subash Abhinov Kasiviswanathan Subject: [PATCH nf-next] netfilter: ipv6: nf_defrag: Always pass on packets to stack Date: Thu, 11 Jan 2018 23:04:33 -0700 Message-Id: <1515737073-32344-2-git-send-email-subashab@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1515737073-32344-1-git-send-email-subashab@codeaurora.org> References: <1515737073-32344-1-git-send-email-subashab@codeaurora.org> Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org ipv6_defrag pulls network headers before fragment header. In case of an error, the netfilter layer is currently dropping these packets. This results in failure of some IPv6 standards tests which passed on older kernels due to the netfilter framework using cloning. The test case run here is a check for ICMPv6 error message replies when some invalid IPv6 fragments are sent. This specific test case is listed in https://www.ipv6ready.org/docs/Core_Conformance_Latest.pdf in the Extension Header Processing Order section. A packet with unrecognized option Type 11 is sent and the test expects an ICMP error in line with RFC2460 section 4.2 - 11 - discard the packet and, only if the packet's Destination Address was not a multicast address, send an ICMP Parameter Problem, Code 2, message to the packet's Source Address, pointing to the unrecognized Option Type. Since netfilter layer now drops all invalid IPv6 frag packets, we no longer see the ICMP error message and fail the test case. To fix this, clone the packet and allow it to be processed by the defrag queue. In case defrag holds onto the packet, drop the original skb. If defrag is unable to process it, free this cloned skb and pass on the original skb. Signed-off-by: Subash Abhinov Kasiviswanathan --- net/ipv6/netfilter/nf_conntrack_reasm.c | 15 +++++++++++++-- net/ipv6/netfilter/nf_defrag_ipv6_hooks.c | 4 ++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 977d890..a44c8b2 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -574,17 +574,26 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) struct ipv6hdr *hdr; u8 prevhdr; + skb = skb_clone(skb, GFP_ATOMIC); + if (!skb) + return -ENOMEM; + /* Jumbo payload inhibits frag. header */ if (ipv6_hdr(skb)->payload_len == 0) { pr_debug("payload len = 0\n"); + kfree(skb); return 0; } - if (find_prev_fhdr(skb, &prevhdr, &nhoff, &fhoff) < 0) + if (find_prev_fhdr(skb, &prevhdr, &nhoff, &fhoff) < 0) { + kfree(skb); return 0; + } - if (!pskb_may_pull(skb, fhoff + sizeof(*fhdr))) + if (!pskb_may_pull(skb, fhoff + sizeof(*fhdr))) { + kfree(skb); return -ENOMEM; + } skb_set_transport_header(skb, fhoff); hdr = ipv6_hdr(skb); @@ -595,6 +604,7 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr)); if (fq == NULL) { pr_debug("Can't find and can't create new queue\n"); + kfree(skb); return -ENOMEM; } @@ -602,6 +612,7 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user) if (nf_ct_frag6_queue(fq, skb, fhdr, nhoff) < 0) { ret = -EINVAL; + kfree(skb); goto out_unlock; } diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c index c87b483..08717cd 100644 --- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c +++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c @@ -72,9 +72,9 @@ static unsigned int ipv6_defrag(void *priv, nf_ct6_defrag_user(state->hook, skb)); /* queued */ if (err == -EINPROGRESS) - return NF_STOLEN; + return NF_DROP; - return err == 0 ? NF_ACCEPT : NF_DROP; + return NF_ACCEPT; } static const struct nf_hook_ops ipv6_defrag_ops[] = {