aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2008-01-30 00:11:46 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-31 22:27:11 -0500
commit2614fa59fa805cd488083c5602eb48533cdbc018 (patch)
tree604fcae5cb381eadb8d8e13e0bef42a7e0c13d11
parent936f6f8e1bc46834bbb3e3fa3ac13ab44f1e7ba6 (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.c5
-rw-r--r--net/ipv6/ipcomp6.c5
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
75static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb) 75static 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
95out: 98out:
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
65static int ipcomp6_input(struct xfrm_state *x, struct sk_buff *skb) 65static 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
113out_put_cpu: 116out_put_cpu:
114 put_cpu(); 117 put_cpu();