diff options
| author | Eric Dumazet <eric.dumazet@gmail.com> | 2012-02-23 05:55:02 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2012-03-19 11:57:45 -0400 |
| commit | e38b849e2fc481c5a6924f6872468104969e5d3c (patch) | |
| tree | dc1e5df29a9b535846017f41efd17690523eef57 /net/ipv6 | |
| parent | 035e3f6e8d1353abcbefd5b87710f8ae8bf1b4f6 (diff) | |
ipsec: be careful of non existing mac headers
[ Upstream commit 03606895cd98c0a628b17324fd7b5ff15db7e3cd ]
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 <darkbasic@linuxsystems.it>
Tested-by: Niccolò Belli <darkbasic@linuxsystems.it>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/xfrm6_mode_beet.c | 6 | ||||
| -rw-r--r-- | net/ipv6/xfrm6_mode_tunnel.c | 6 |
2 files changed, 3 insertions, 9 deletions
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c index 3437d7d4eed..f37cba9e689 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) | |||
| 80 | static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) | 80 | static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) |
| 81 | { | 81 | { |
| 82 | struct ipv6hdr *ip6h; | 82 | struct ipv6hdr *ip6h; |
| 83 | const unsigned char *old_mac; | ||
| 84 | int size = sizeof(struct ipv6hdr); | 83 | int size = sizeof(struct ipv6hdr); |
| 85 | int err; | 84 | int err; |
| 86 | 85 | ||
| @@ -90,10 +89,7 @@ static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) | |||
| 90 | 89 | ||
| 91 | __skb_push(skb, size); | 90 | __skb_push(skb, size); |
| 92 | skb_reset_network_header(skb); | 91 | skb_reset_network_header(skb); |
| 93 | 92 | skb_mac_header_rebuild(skb); | |
| 94 | old_mac = skb_mac_header(skb); | ||
| 95 | skb_set_mac_header(skb, -skb->mac_len); | ||
| 96 | memmove(skb_mac_header(skb), old_mac, skb->mac_len); | ||
| 97 | 93 | ||
| 98 | xfrm6_beet_make_header(skb); | 94 | xfrm6_beet_make_header(skb); |
| 99 | 95 | ||
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index 4d6edff0498..23ecd68a5e6 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) | |||
| 63 | static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) | 63 | static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) |
| 64 | { | 64 | { |
| 65 | int err = -EINVAL; | 65 | int err = -EINVAL; |
| 66 | const unsigned char *old_mac; | ||
| 67 | 66 | ||
| 68 | if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6) | 67 | if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6) |
| 69 | goto out; | 68 | goto out; |
| @@ -80,10 +79,9 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) | |||
| 80 | if (!(x->props.flags & XFRM_STATE_NOECN)) | 79 | if (!(x->props.flags & XFRM_STATE_NOECN)) |
| 81 | ipip6_ecn_decapsulate(skb); | 80 | ipip6_ecn_decapsulate(skb); |
| 82 | 81 | ||
| 83 | old_mac = skb_mac_header(skb); | ||
| 84 | skb_set_mac_header(skb, -skb->mac_len); | ||
| 85 | memmove(skb_mac_header(skb), old_mac, skb->mac_len); | ||
| 86 | skb_reset_network_header(skb); | 82 | skb_reset_network_header(skb); |
| 83 | skb_mac_header_rebuild(skb); | ||
| 84 | |||
| 87 | err = 0; | 85 | err = 0; |
| 88 | 86 | ||
| 89 | out: | 87 | out: |
