lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Sat, 30 Mar 2019 20:37:40 +0800 From: hujunwei <hujunwei4@...wei.com> To: Eric Dumazet <eric.dumazet@...il.com>, <davem@...emloft.net>, <kuznet@....inr.ac.ru>, <yoshfuji@...ux-ipv6.org>, <netdev@...r.kernel.org>, <linux-kernel@...r.kernel.org> CC: <mingfangsen@...wei.com>, <liuzhiqiang26@...wei.com>, <zhangwenhao8@...wei.com> Subject: Re: [PATCH net] ipv6: Fix dangling pointer when ipv6 fragment Hi Eri, Thanks for your suggestion, u8 may not enough when the packet have a lot of exthdr. I will update the patch in v2, by the way update Report-by tag. On 2019/3/30 15:57, Eric Dumazet wrote: > > On 03/30/2019 12:48 AM, Eric Dumazet wrote: >> >> On 03/30/2019 12:29 AM, hujunwei wrote: >>> From: Junwei Hu <hujunwei4@...wei.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); >>> > . >
Powered by blists - more mailing lists