Skip to content

Commit 58ffe3e

Browse files
Junwei Hugregkh
authored andcommitted
ipv6: Fix dangling pointer when ipv6 fragment
[ Upstream commit ef0efcd ] 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. Fixes: 405c92f ("ipv6: add defensive check for CHECKSUM_PARTIAL skbs in ip_fragment") Signed-off-by: Junwei Hu <[email protected]> Reported-by: Wenhao Zhang <[email protected]> Reported-by: [email protected] Reviewed-by: Zhiqiang Liu <[email protected]> Acked-by: Martin KaFai Lau <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ad2548c commit 58ffe3e

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

net/ipv6/ip6_output.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
611611
inet6_sk(skb->sk) : NULL;
612612
struct ipv6hdr *tmp_hdr;
613613
struct frag_hdr *fh;
614-
unsigned int mtu, hlen, left, len;
614+
unsigned int mtu, hlen, left, len, nexthdr_offset;
615615
int hroom, troom;
616616
__be32 frag_id;
617617
int ptr, offset = 0, err = 0;
@@ -622,6 +622,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
622622
goto fail;
623623
hlen = err;
624624
nexthdr = *prevhdr;
625+
nexthdr_offset = prevhdr - skb_network_header(skb);
625626

626627
mtu = ip6_skb_dst_mtu(skb);
627628

@@ -656,6 +657,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
656657
(err = skb_checksum_help(skb)))
657658
goto fail;
658659

660+
prevhdr = skb_network_header(skb) + nexthdr_offset;
659661
hroom = LL_RESERVED_SPACE(rt->dst.dev);
660662
if (skb_has_frag_list(skb)) {
661663
unsigned int first_len = skb_pagelen(skb);

0 commit comments

Comments
 (0)