From patchwork Wed Jul 11 20:38:42 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brad Figg X-Patchwork-Id: 170511 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from chlorine.canonical.com (chlorine.canonical.com [91.189.94.204]) by ozlabs.org (Postfix) with ESMTP id 6FB632C0200 for ; Thu, 12 Jul 2012 06:38:55 +1000 (EST) Received: from localhost ([127.0.0.1] helo=chlorine.canonical.com) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1Sp3gN-0007Zz-NP; Wed, 11 Jul 2012 20:38:47 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by chlorine.canonical.com with esmtp (Exim 4.71) (envelope-from ) id 1Sp3gK-0007Z8-14 for kernel-team@lists.ubuntu.com; Wed, 11 Jul 2012 20:38:44 +0000 Received: from static-50-53-107-235.bvtn.or.frontiernet.net ([50.53.107.235] helo=localhost) by youngberry.canonical.com with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1Sp3gJ-00025v-En for kernel-team@lists.ubuntu.com; Wed, 11 Jul 2012 20:38:43 +0000 From: Brad Figg To: kernel-team@lists.ubuntu.com Subject: [PATCH 1/1] [HARDY] [CVE-2012-2744] netfilter: nf_conntrack_reasm: properly handle packets fragmented into a single fragment Date: Wed, 11 Jul 2012 13:38:42 -0700 Message-Id: <1342039122-29194-2-git-send-email-brad.figg@canonical.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1342039122-29194-1-git-send-email-brad.figg@canonical.com> References: <1342039122-29194-1-git-send-email-brad.figg@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.13 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: kernel-team-bounces@lists.ubuntu.com Errors-To: kernel-team-bounces@lists.ubuntu.com From: Patrick McHardy CVE-2012-2744 BugLink: http://bugs.launchpad.net/bugs/1234567 When an ICMPV6_PKT_TOOBIG message is received with a MTU below 1280, all further packets include a fragment header. Unlike regular defragmentation, conntrack also needs to "reassemble" those fragments in order to obtain a packet without the fragment header for connection tracking. Currently nf_conntrack_reasm checks whether a fragment has either IP6_MF set or an offset != 0, which makes it ignore those fragments. Remove the invalid check and make reassembly handle fragment queues containing only a single fragment. Reported-and-tested-by: Ulrich Weber Signed-off-by: Patrick McHardy (backported from commit 9e2dcf72023d1447f09c47d77c99b0c49659e5ce upstream) Signed-off-by: Brad Figg --- .../src/net/ipv6/netfilter/nf_conntrack_reasm.c | 8 +------- .../src/net/ipv6/netfilter/nf_conntrack_reasm.c | 8 +------- net/ipv6/netfilter/nf_conntrack_reasm.c | 8 +------- 3 files changed, 3 insertions(+), 21 deletions(-) diff --git a/debian/binary-custom.d/openvz/src/net/ipv6/netfilter/nf_conntrack_reasm.c b/debian/binary-custom.d/openvz/src/net/ipv6/netfilter/nf_conntrack_reasm.c index fd6054a..c555cfa 100644 --- a/debian/binary-custom.d/openvz/src/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/debian/binary-custom.d/openvz/src/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -481,7 +481,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */ fp = skb_shinfo(head)->frag_list; - if (NFCT_FRAG6_CB(fp)->orig == NULL) + if (fp && NFCT_FRAG6_CB(fp)->orig == NULL) /* at above code, head skb is divided into two skbs. */ fp = fp->next; @@ -607,12 +607,6 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb) hdr = ipv6_hdr(clone); fhdr = (struct frag_hdr *)skb_transport_header(clone); - if (!(fhdr->frag_off & htons(0xFFF9))) { - pr_debug("Invalid fragment offset\n"); - /* It is not a fragmented frame */ - goto ret_orig; - } - if (atomic_read(&ve_nf_frags.mem) > ve_nf_frags_ctl.high_thresh) nf_ct_frag6_evictor(); diff --git a/debian/binary-custom.d/xen/src/net/ipv6/netfilter/nf_conntrack_reasm.c b/debian/binary-custom.d/xen/src/net/ipv6/netfilter/nf_conntrack_reasm.c index 89f95f9..c138783 100644 --- a/debian/binary-custom.d/xen/src/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/debian/binary-custom.d/xen/src/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -473,7 +473,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */ fp = skb_shinfo(head)->frag_list; - if (NFCT_FRAG6_CB(fp)->orig == NULL) + if (fp && NFCT_FRAG6_CB(fp)->orig == NULL) /* at above code, head skb is divided into two skbs. */ fp = fp->next; @@ -599,12 +599,6 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb) hdr = ipv6_hdr(clone); fhdr = (struct frag_hdr *)skb_transport_header(clone); - if (!(fhdr->frag_off & htons(0xFFF9))) { - pr_debug("Invalid fragment offset\n"); - /* It is not a fragmented frame */ - goto ret_orig; - } - if (atomic_read(&nf_frags.mem) > nf_frags_ctl.high_thresh) nf_ct_frag6_evictor(); diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c index 89f95f9..c138783 100644 --- a/net/ipv6/netfilter/nf_conntrack_reasm.c +++ b/net/ipv6/netfilter/nf_conntrack_reasm.c @@ -473,7 +473,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev) /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */ fp = skb_shinfo(head)->frag_list; - if (NFCT_FRAG6_CB(fp)->orig == NULL) + if (fp && NFCT_FRAG6_CB(fp)->orig == NULL) /* at above code, head skb is divided into two skbs. */ fp = fp->next; @@ -599,12 +599,6 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb) hdr = ipv6_hdr(clone); fhdr = (struct frag_hdr *)skb_transport_header(clone); - if (!(fhdr->frag_off & htons(0xFFF9))) { - pr_debug("Invalid fragment offset\n"); - /* It is not a fragmented frame */ - goto ret_orig; - } - if (atomic_read(&nf_frags.mem) > nf_frags_ctl.high_thresh) nf_ct_frag6_evictor();