From patchwork Fri Jan 9 08:32:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Sharma X-Patchwork-Id: 426949 X-Patchwork-Delegate: pablo@netfilter.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id D2424140119 for ; Fri, 9 Jan 2015 19:32:36 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932128AbbAIIcU (ORCPT ); Fri, 9 Jan 2015 03:32:20 -0500 Received: from mail-wi0-f180.google.com ([209.85.212.180]:40593 "EHLO mail-wi0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754575AbbAIIcT (ORCPT ); Fri, 9 Jan 2015 03:32:19 -0500 Received: by mail-wi0-f180.google.com with SMTP id n3so740754wiv.1 for ; Fri, 09 Jan 2015 00:32:17 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to:cc :content-type; bh=uNbRmJEpXpiBKo+fMwQKI4DuG6/CVo8CXxGaSNTJieU=; b=dBj8zMBwdxyUvFS/o8c5+YCqTl9Kd00celOaeLhu0Eo8ckIqrJsWGclI7oX8fkzri4 Pq4StrlHUrpr6DEpGGTxjx6x86qNPkm0aFIdRtgPFmp2RXAk+XpVTHB7vVIDF4QJPjXL UTTmJXc2VJsCTbDsZussqjdSyILDmWElpoPKkIv0e4DjEdav8uXFwmGjc9mRk54IqEQ/ M/uUh9XSYr1jSOxsWVx/YeOyvh7xqT2WmhcdSk2BuUMQjWKvaq9uyIWSbiNjMObqA7ae GRp6Hyc+gSHinxxJuILlimHhFdRlVXWPZAuV52yQFPMXer5TCzUBLF5/U4n6kgRNeQOT MdmA== X-Gm-Message-State: ALoCoQnSRXlwIMDA7VtrvxIKUgUlLS3u8LNiH3L0w1Bf+NCNWflCvjpRBJ0+X17dxjZXFaIwICM5 MIME-Version: 1.0 X-Received: by 10.180.96.33 with SMTP id dp1mr2682167wib.13.1420792337802; Fri, 09 Jan 2015 00:32:17 -0800 (PST) Received: by 10.194.31.132 with HTTP; Fri, 9 Jan 2015 00:32:17 -0800 (PST) Date: Fri, 9 Jan 2015 14:02:17 +0530 Message-ID: Subject: [PATCH v2] net: ipv6: Prevent ipv6_find_hdr() from returning ENOENT for valid non-first fragments From: Rahul Sharma To: netdev@vger.kernel.org Cc: Hannes Frederic Sowa , linux-kernel@vger.kernel.org, netfilter-devel@vger.kernel.org, Pablo Neira Ayuso Sender: netfilter-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netfilter-devel@vger.kernel.org ipv6_find_hdr() currently assumes that the next-header field in the fragment header of the non-first fragment is the "protocol number of the last header" (here last header excludes any extension header protocol numbers ) which is incorrect as per RFC2460. The next-header value is the first header of the fragmentable part of the original packet (which can be extension header as well). This can create reassembly problems. For example: Fragmented authenticated OSPFv3 packets (where AH header is inserted before the protocol header). For the second fragment, the next header value in the fragment header will be NEXTHDR_AUTH which is correct but ipv6_find_hdr will return ENOENT since AH is an extension header resulting in second fragment getting dropped. This check for the presence of non-extension header needs to be removed. Signed-off-by: Rahul Sharma --- net/ipv6/exthdrs_core.c | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) return hp->nexthdr; -- 1.7.4.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c index 8af3eb5..5949f87 100644 --- a/net/ipv6/exthdrs_core.c +++ b/net/ipv6/exthdrs_core.c @@ -171,10 +171,11 @@ EXPORT_SYMBOL_GPL(ipv6_find_tlv); * If the first fragment doesn't contain the final protocol header or * NEXTHDR_NONE it is considered invalid. * - * Note that non-1st fragment is special case that "the protocol number - * of last header" is "next header" field in Fragment header. In this case, - * *offset is meaningless and fragment offset is stored in *fragoff if fragoff - * isn't NULL. + * Note that non-1st fragment is special case that "the protocol number of the + * first header of the fragmentable part of the original packet" is + * "next header" field in the Fragment header. In this case, *offset is + * meaningless and fragment offset is stored in *fragoff if fragoff isn't + * NULL. * * if flags is not NULL and it's a fragment, then the frag flag * IP6_FH_F_FRAG will be set. If it's an AH header, the @@ -250,9 +251,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, _frag_off = ntohs(*fp) & ~0x7; if (_frag_off) { - if (target < 0 && - ((!ipv6_ext_hdr(hp->nexthdr)) || - hp->nexthdr == NEXTHDR_NONE)) { + if (target < 0) { if (fragoff) *fragoff = _frag_off;