From patchwork Thu Feb 23 14:36:26 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Eric Dumazet X-Patchwork-Id: 142640 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id DEEC2B6EF3 for ; Fri, 24 Feb 2012 01:36:39 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755714Ab2BWOgf (ORCPT ); Thu, 23 Feb 2012 09:36:35 -0500 Received: from mail-we0-f174.google.com ([74.125.82.174]:57016 "EHLO mail-we0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753084Ab2BWOge (ORCPT ); Thu, 23 Feb 2012 09:36:34 -0500 Received: by werb13 with SMTP id b13so789898wer.19 for ; Thu, 23 Feb 2012 06:36:33 -0800 (PST) Received-SPF: pass (google.com: domain of eric.dumazet@gmail.com designates 10.181.13.113 as permitted sender) client-ip=10.181.13.113; Authentication-Results: mr.google.com; spf=pass (google.com: domain of eric.dumazet@gmail.com designates 10.181.13.113 as permitted sender) smtp.mail=eric.dumazet@gmail.com; dkim=pass header.i=eric.dumazet@gmail.com Received: from mr.google.com ([10.181.13.113]) by 10.181.13.113 with SMTP id ex17mr4004697wid.15.1330007793184 (num_hops = 1); Thu, 23 Feb 2012 06:36:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=message-id:subject:from:to:cc:date:in-reply-to:references :content-type:x-mailer:content-transfer-encoding:mime-version; bh=8tK64/fH+uB7RPWF8WUOx6lOwZ04g/k6d4RhlBsP7r0=; b=B0DBk/sVfpf65AX06H81Qr8T0RztqhGnkBIO5U1Ya+YHs0DzMpJyaOd1ZmUNUcrYxs SzgoNEGxQ6faHfJQ43dLtiyb+tWdlUcD3KwfLPcnN2U1hr47Da6vkbAJ1vLTBR6Mhy9z u/zaWRAeFWRH1HbZrE3GjFtSbEHuN6dEiMYx4= Received: by 10.181.13.113 with SMTP id ex17mr3265690wid.15.1330007793087; Thu, 23 Feb 2012 06:36:33 -0800 (PST) Received: from [192.168.1.97] (122.237.66.86.rev.sfr.net. [86.66.237.122]) by mx.google.com with ESMTPS id s2sm7460278wix.3.2012.02.23.06.36.31 (version=SSLv3 cipher=OTHER); Thu, 23 Feb 2012 06:36:32 -0800 (PST) Message-ID: <1330007786.15610.26.camel@edumazet-laptop> Subject: Re: [Bug 42809] New: kernel panic when receiving an ipsec packet From: Eric Dumazet To: =?ISO-8859-1?Q?Niccol=F2?= Belli , David Miller Cc: Linux Networking Developer Mailing List , openadsl-users@lists.sourceforge.net, openadsl-devel@lists.sourceforge.net, 660804@bugs.debian.org, support@traverse.com.au, support@rocksolidelectronics.com Date: Thu, 23 Feb 2012 15:36:26 +0100 In-Reply-To: <4F46430D.3060802@linuxsystems.it> References: <20120222092056.5fca788b@nehalam.linuxnetplumber.net> <4F4528CE.7080702@linuxsystems.it> <4F458F82.3060808@linuxsystems.it> <1329961083.15610.2.camel@edumazet-laptop> <4F459E37.9010507@linuxsystems.it> <1329962785.15610.8.camel@edumazet-laptop> <4F46430D.3060802@linuxsystems.it> X-Mailer: Evolution 3.2.2- Mime-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org > Your patch does solve the problem, thanks! > Thanks for testing. Here is the official patch I submit for review then. [PATCH] ipsec: be careful of non existing mac headers Nicollo Belli reported ipsec crashes in case we handle a frame without mac header (atm in his case) Before copying mac header, better make sure it is present. Bugzilla reference: https://bugzilla.kernel.org/show_bug.cgi?id=42809 Reported-by: Niccolò Belli Tested-by: Niccolò Belli Signed-off-by: Eric Dumazet --- net/ipv4/xfrm4_mode_beet.c | 9 +++++---- net/ipv4/xfrm4_mode_tunnel.c | 10 ++++++---- net/ipv6/xfrm6_mode_beet.c | 9 +++++---- net/ipv6/xfrm6_mode_tunnel.c | 10 ++++++---- 4 files changed, 22 insertions(+), 16 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" 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/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c index 6341818..d3451f6 100644 --- a/net/ipv4/xfrm4_mode_beet.c +++ b/net/ipv4/xfrm4_mode_beet.c @@ -111,10 +111,11 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) skb_push(skb, sizeof(*iph)); skb_reset_network_header(skb); - memmove(skb->data - skb->mac_len, skb_mac_header(skb), - skb->mac_len); - skb_set_mac_header(skb, -skb->mac_len); - + if (skb_mac_header_was_set(skb)) { + memmove(skb->data - skb->mac_len, skb_mac_header(skb), + skb->mac_len); + skb_set_mac_header(skb, -skb->mac_len); + } xfrm4_beet_make_header(skb); iph = ip_hdr(skb); diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index 534972e..a646f30 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c @@ -66,7 +66,6 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) { - const unsigned char *old_mac; int err = -EINVAL; if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP) @@ -84,9 +83,12 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) if (!(x->props.flags & XFRM_STATE_NOECN)) ipip_ecn_decapsulate(skb); - old_mac = skb_mac_header(skb); - skb_set_mac_header(skb, -skb->mac_len); - memmove(skb_mac_header(skb), old_mac, skb->mac_len); + if (skb_mac_header_was_set(skb)) { + const unsigned char *old_mac = skb_mac_header(skb); + + skb_set_mac_header(skb, -skb->mac_len); + memmove(skb_mac_header(skb), old_mac, skb->mac_len); + } skb_reset_network_header(skb); err = 0; diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c index a81ce94..74c4b92 100644 --- a/net/ipv6/xfrm6_mode_beet.c +++ b/net/ipv6/xfrm6_mode_beet.c @@ -80,7 +80,6 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb) static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) { struct ipv6hdr *ip6h; - const unsigned char *old_mac; int size = sizeof(struct ipv6hdr); int err; @@ -91,10 +90,12 @@ static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) __skb_push(skb, size); skb_reset_network_header(skb); - old_mac = skb_mac_header(skb); - skb_set_mac_header(skb, -skb->mac_len); - memmove(skb_mac_header(skb), old_mac, skb->mac_len); + if (skb_mac_header_was_set(skb)) { + const unsigned char *old_mac = skb_mac_header(skb); + skb_set_mac_header(skb, -skb->mac_len); + memmove(skb_mac_header(skb), old_mac, skb->mac_len); + } xfrm6_beet_make_header(skb); ip6h = ipv6_hdr(skb); diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index 261e6e6..edb7091 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c @@ -63,7 +63,6 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) { int err = -EINVAL; - const unsigned char *old_mac; if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6) goto out; @@ -80,9 +79,12 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) if (!(x->props.flags & XFRM_STATE_NOECN)) ipip6_ecn_decapsulate(skb); - old_mac = skb_mac_header(skb); - skb_set_mac_header(skb, -skb->mac_len); - memmove(skb_mac_header(skb), old_mac, skb->mac_len); + if (skb_mac_header_was_set(skb)) { + const unsigned char *old_mac = skb_mac_header(skb); + + skb_set_mac_header(skb, -skb->mac_len); + memmove(skb_mac_header(skb), old_mac, skb->mac_len); + } skb_reset_network_header(skb); err = 0;