diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2008-01-30 00:11:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-31 22:27:11 -0500 |
commit | 2614fa59fa805cd488083c5602eb48533cdbc018 (patch) | |
tree | 604fcae5cb381eadb8d8e13e0bef42a7e0c13d11 | |
parent | 936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6 (diff) |
[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>
-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: | |||
74 | 74 | ||
75 | static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) | 75 | static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) |
76 | { | 76 | { |
77 | int nexthdr; | ||
77 | int err = -ENOMEM; | 78 | int err = -ENOMEM; |
78 | struct ip_comp_hdr *ipch; | 79 | struct ip_comp_hdr *ipch; |
79 | 80 | ||
@@ -84,13 +85,15 @@ static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) | |||
84 | 85 | ||
85 | /* Remove ipcomp header and decompress original payload */ | 86 | /* Remove ipcomp header and decompress original payload */ |
86 | ipch = (void *)skb->data; | 87 | ipch = (void *)skb->data; |
88 | nexthdr = ipch->nexthdr; | ||
89 | |||
87 | skb->transport_header = skb->network_header + sizeof(*ipch); | 90 | skb->transport_header = skb->network_header + sizeof(*ipch); |
88 | __skb_pull(skb, sizeof(*ipch)); | 91 | __skb_pull(skb, sizeof(*ipch)); |
89 | err = ipcomp_decompress(x, skb); | 92 | err = ipcomp_decompress(x, skb); |
90 | if (err) | 93 | if (err) |
91 | goto out; | 94 | goto out; |
92 | 95 | ||
93 | err = ipch->nexthdr; | 96 | err = nexthdr; |
94 | 97 | ||
95 | out: | 98 | out: |
96 | return err; | 99 | 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); | |||
64 | 64 | ||
65 | static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) | 65 | static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) |
66 | { | 66 | { |
67 | int nexthdr; | ||
67 | int err = -ENOMEM; | 68 | int err = -ENOMEM; |
68 | struct ip_comp_hdr *ipch; | 69 | struct ip_comp_hdr *ipch; |
69 | int plen, dlen; | 70 | int plen, dlen; |
@@ -79,6 +80,8 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
79 | 80 | ||
80 | /* Remove ipcomp header and decompress original payload */ | 81 | /* Remove ipcomp header and decompress original payload */ |
81 | ipch = (void *)skb->data; | 82 | ipch = (void *)skb->data; |
83 | nexthdr = ipch->nexthdr; | ||
84 | |||
82 | skb->transport_header = skb->network_header + sizeof(*ipch); | 85 | skb->transport_header = skb->network_header + sizeof(*ipch); |
83 | __skb_pull(skb, sizeof(*ipch)); | 86 | __skb_pull(skb, sizeof(*ipch)); |
84 | 87 | ||
@@ -108,7 +111,7 @@ static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) | |||
108 | skb->truesize += dlen - plen; | 111 | skb->truesize += dlen - plen; |
109 | __skb_put(skb, dlen - plen); | 112 | __skb_put(skb, dlen - plen); |
110 | skb_copy_to_linear_data(skb, scratch, dlen); | 113 | skb_copy_to_linear_data(skb, scratch, dlen); |
111 | err = ipch->nexthdr; | 114 | err = nexthdr; |
112 | 115 | ||
113 | out_put_cpu: | 116 | out_put_cpu: |
114 | put_cpu(); | 117 | put_cpu(); |