Message ID | 9104f44b-2ce0-7be9-2fca-8b6c12abbb86@huawei.com |
---|---|
State | Changes Requested |
Delegated to: | David Miller |
Headers | show |
Series | [v2,net] ipv6: Fix dangling pointer when ipv6 fragment | expand |
On Sun, Mar 31, 2019 at 05:04:29PM +0800, hujunwei wrote: > From: Junwei Hu <hujunwei4@huawei.com> > > At the beginning of ip6_fragment func, the prevhdr pointer is > obtained in the ip6_find_1stfragopt func. > However, all the pointers pointing into skb header may change > when calling skb_checksum_help func with > skb->ip_summed = CHECKSUM_PARTIAL condition. > The prevhdr pointe will be dangling if it is not reloaded after > calling __skb_linearize func in skb_checksum_help func. > > Here, I add a variable, nexthdr_offset, to evaluate the offset, > which does not changes even after calling __skb_linearize func. Acked-by: Martin KaFai Lau <kafai@fb.com>
From: hujunwei <hujunwei4@huawei.com> Date: Sun, 31 Mar 2019 17:04:29 +0800 > diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c > index edbd12067170..e51f3c648b09 100644 > --- a/net/ipv6/ip6_output.c > +++ b/net/ipv6/ip6_output.c > @@ -601,7 +601,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, > inet6_sk(skb->sk) : NULL; > struct ipv6hdr *tmp_hdr; > struct frag_hdr *fh; > - unsigned int mtu, hlen, left, len; Your patch was corrupted by your email client. Please fix this, email a test patch to yourself, and only when you can successfully apply that test patch should you repost this to the mailing list. Thank you.
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index edbd12067170..e51f3c648b09 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -601,7 +601,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, inet6_sk(skb->sk) : NULL; struct ipv6hdr *tmp_hdr; struct frag_hdr *fh; - unsigned int mtu, hlen, left, len; + unsigned int mtu, hlen, left, len, nexthdr_offset; int hroom, troom; __be32 frag_id; int ptr, offset = 0, err = 0; @@ -612,6 +612,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, goto fail; hlen = err; nexthdr = *prevhdr; + nexthdr_offset = prevhdr - skb_network_header(skb); mtu = ip6_skb_dst_mtu(skb); @@ -646,6 +647,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, (err = skb_checksum_help(skb))) goto fail; + prevhdr = skb_network_header(skb) + nexthdr_offset; hroom = LL_RESERVED_SPACE(rt->dst.dev); if (skb_has_frag_list(skb)) { unsigned int first_len = skb_pagelen(skb);