diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2008-01-29 21:11:46 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-31 19:27:11 -0800 |
commit | 2614fa59fa805cd488083c5602eb48533cdbc018 (patch) | |
tree | 604fcae5cb381eadb8d8e13e0bef42a7e0c13d11 /net | |
parent | 936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6 (diff) | |
download | linux-2614fa59fa805cd488083c5602eb48533cdbc018.tar.gz linux-2614fa59fa805cd488083c5602eb48533cdbc018.tar.bz2 linux-2614fa59fa805cd488083c5602eb48533cdbc018.zip |
[IPCOMP]: Fetch nexthdr before ipch is destroyed
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 <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/ipcomp.c | 5 | ||||
-rw-r--r-- | net/ipv6/ipcomp6.c | 5 |
2 files changed, 8 insertions, 2 deletions
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index f4af99ad8fdb..b79cdbee68a9 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 b276d04d6db5..710325e7a842 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(); |