From: Herbert Xu Date: Fri, 15 Feb 2008 09:44:03 +0000 (-0800) Subject: IPCOMP: Fetch nexthdr before ipch is destroyed X-Git-Tag: v2.6.24.3~20 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=363c11d7e1c2b2cc30e33416a518cea5ef9e0cc8;p=karo-tx-linux.git IPCOMP: Fetch nexthdr before ipch is destroyed Upstream commit: 2614fa59fa805cd488083c5602eb48533cdbc018 When I moved the nexthdr setting out of IPComp I accidently moved the reading of ipch->nexthdr after the decompression. Unfortunately this means that we'd be reading from a stale ipch pointer which doesn't work very well. This patch moves the reading up so that we get the correct nexthdr value. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 2c44a94c2135..80cab8c73074 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -74,6 +74,7 @@ out: static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) { + int nexthdr; int err = -ENOMEM; struct ip_comp_hdr *ipch; @@ -84,13 +85,15 @@ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) /* Remove ipcomp header and decompress original payload */ ipch = (void *)skb->data; + nexthdr = ipch->nexthdr; + skb->transport_header = skb->network_header + sizeof(*ipch); __skb_pull(skb, sizeof(*ipch)); err = ipcomp_decompress(x, skb); if (err) goto out; - err = ipch->nexthdr; + err = nexthdr; out: return err; diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 0cd4056f9127..1c5b09f44a75 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c @@ -64,6 +64,7 @@ static LIST_HEAD(ipcomp6_tfms_list); static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) { + int nexthdr; int err = -ENOMEM; struct ip_comp_hdr *ipch; int plen, dlen; @@ -79,6 +80,8 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) /* Remove ipcomp header and decompress original payload */ ipch = (void *)skb->data; + nexthdr = ipch->nexthdr; + skb->transport_header = skb->network_header + sizeof(*ipch); __skb_pull(skb, sizeof(*ipch)); @@ -108,7 +111,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) skb->truesize += dlen - plen; __skb_put(skb, dlen - plen); skb_copy_to_linear_data(skb, scratch, dlen); - err = ipch->nexthdr; + err = nexthdr; out_put_cpu: put_cpu();