Messages in this thread | | | Subject | Re: [PATCH net] ipv6: Fix dangling pointer when ipv6 fragment | From | Eric Dumazet <> | Date | Sat, 30 Mar 2019 00:57:55 -0700 |
| |
On 03/30/2019 12:48 AM, Eric Dumazet wrote: > > > On 03/30/2019 12:29 AM, 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. >>
...
>> diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c >> index edbd12067170..6db3c60b3b66 100644 >> --- a/net/ipv6/ip6_output.c >> +++ b/net/ipv6/ip6_output.c >> @@ -606,12 +606,14 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, >> __be32 frag_id; >> int ptr, offset = 0, err = 0; >> u8 *prevhdr, nexthdr = 0; >> + u8 nexthdr_offset;
Why u8 here ?
I would use "unsigned int" really.
>> >> err = ip6_find_1stfragopt(skb, &prevhdr); >> if (err < 0) >> goto fail; >> hlen = err; >> nexthdr = *prevhdr; >> + nexthdr_offset = prevhdr - skb_network_header(skb); >> >> mtu = ip6_skb_dst_mtu(skb); >> >> @@ -646,6 +648,8 @@ 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); >>
| |