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>
static int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb)
{
+ int nexthdr;
int err = -ENOMEM;
struct ip_comp_hdr *ipch;
/* 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;
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;
/* 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));
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();