From 71513149e2966fdcfbe680f51d3fe4ddf6d3aa8a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 26 Feb 2012 17:16:17 +0000 Subject: [PATCH] ipsec: be careful of non existing mac headers (Closes: #660804) svn path=/dists/sid/linux-2.6/; revision=18740 --- debian/changelog | 1 + ...-careful-of-non-existing-mac-headers.patch | 142 ++++++++++++++++++ debian/patches/series/base | 1 + 3 files changed, 144 insertions(+) create mode 100644 debian/patches/bugfix/all/ipsec-be-careful-of-non-existing-mac-headers.patch diff --git a/debian/changelog b/debian/changelog index b11e80d30..e853346b7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -23,6 +23,7 @@ linux-2.6 (3.2.7-1) UNRELEASED; urgency=low * [mips/r5k-ip32] Enable INPUT_SGI_BTNS (previously INPUT_SGIO2_BTNS) * [powerpc/powerpc64] Enable IBM_EMAC (previously IBM_NEW_EMAC) * [x86] drm/i915: do not enable RC6p on Sandy Bridge (Closes: #660265) + * ipsec: be careful of non existing mac headers (Closes: #660804) [ Bastian Blank ] * Don't advertise Xen support for rt images. (closes: #659988) diff --git a/debian/patches/bugfix/all/ipsec-be-careful-of-non-existing-mac-headers.patch b/debian/patches/bugfix/all/ipsec-be-careful-of-non-existing-mac-headers.patch new file mode 100644 index 000000000..e452ae58c --- /dev/null +++ b/debian/patches/bugfix/all/ipsec-be-careful-of-non-existing-mac-headers.patch @@ -0,0 +1,142 @@ +From: Eric Dumazet +Date: Thu, 23 Feb 2012 10:55:02 +0000 +Subject: [PATCH] ipsec: be careful of non existing mac headers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +commit 03606895cd98c0a628b17324fd7b5ff15db7e3cd upstream. + +Niccolo 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 +Signed-off-by: David S. Miller +--- + include/linux/skbuff.h | 10 ++++++++++ + net/ipv4/xfrm4_mode_beet.c | 5 +---- + net/ipv4/xfrm4_mode_tunnel.c | 6 ++---- + net/ipv6/xfrm6_mode_beet.c | 6 +----- + net/ipv6/xfrm6_mode_tunnel.c | 6 ++---- + 5 files changed, 16 insertions(+), 17 deletions(-) + +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index 50db9b0..ae86ade 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1465,6 +1465,16 @@ static inline void skb_set_mac_header(struct sk_buff *skb, const int offset) + } + #endif /* NET_SKBUFF_DATA_USES_OFFSET */ + ++static inline void skb_mac_header_rebuild(struct sk_buff *skb) ++{ ++ 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); ++ } ++} ++ + static inline int skb_checksum_start_offset(const struct sk_buff *skb) + { + return skb->csum_start - skb_headroom(skb); +diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c +index 6341818..e3db3f9 100644 +--- a/net/ipv4/xfrm4_mode_beet.c ++++ b/net/ipv4/xfrm4_mode_beet.c +@@ -110,10 +110,7 @@ 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); ++ skb_mac_header_rebuild(skb); + + xfrm4_beet_make_header(skb); + +diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c +index 534972e..ed4bf11 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,10 +83,9 @@ 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); + skb_reset_network_header(skb); ++ skb_mac_header_rebuild(skb); ++ + err = 0; + + out: +diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c +index a81ce94..9949a35 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; + +@@ -90,10 +89,7 @@ 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); ++ skb_mac_header_rebuild(skb); + + xfrm6_beet_make_header(skb); + +diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c +index 261e6e6..9f2095b 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,10 +79,9 @@ 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); + skb_reset_network_header(skb); ++ skb_mac_header_rebuild(skb); ++ + err = 0; + + out: +-- +1.7.9.1 + diff --git a/debian/patches/series/base b/debian/patches/series/base index d0afd3148..63730c61c 100644 --- a/debian/patches/series/base +++ b/debian/patches/series/base @@ -80,3 +80,4 @@ + bugfix/all/builddeb-Don-t-create-files-in-tmp-with-predictable-.patch + bugfix/x86/drm-i915-do-not-enable-RC6p-on-Sandy-Bridge.patch + bugfix/x86/drm-i915-fix-operator-precedence-when-enabling-RC6p.patch ++ bugfix/all/ipsec-be-careful-of-non-existing-mac-headers.patch