diff options
author | Eric Dumazet <edumazet@google.com> | 2017-01-23 16:43:05 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-07-05 14:40:23 +0200 |
commit | b07bf2364605dc7d78401b7eb02a533b0b6ddc05 (patch) | |
tree | fbf40c24c669b40f6a8bf029f7a643c84d976426 | |
parent | 7fdc81f6e1a9b3f520e40cfc4ebccc94858da62d (diff) |
ip6_tunnel: must reload ipv6h in ip6ip6_tnl_xmit()
[ Upstream commit 21b995a9cb093fff33ec91d7cb3822b882a90a1e ]
Since ip6_tnl_parse_tlv_enc_lim() can call pskb_may_pull(),
we must reload any pointer that was related to skb->head
(or skb->data), or risk use after free.
Fixes: c12b395a4664 ("gre: Support GRE over IPv6")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Dmitry Kozlov <xeb@mail.ru>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <alexander.levin@verizon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | net/ipv6/ip6_gre.c | 3 | ||||
-rw-r--r-- | net/ipv6/ip6_tunnel.c | 2 |
2 files changed, 5 insertions, 0 deletions
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 0a5922055da2..a5fdc1aa7a9a 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c @@ -582,6 +582,9 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev) return -1; offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); + /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */ + ipv6h = ipv6_hdr(skb); + if (offset > 0) { struct ipv6_tlv_tnl_enc_lim *tel; tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset]; diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 116b4da06820..63fad2467a7e 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -1313,6 +1313,8 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev) fl6.flowlabel = key->label; } else { offset = ip6_tnl_parse_tlv_enc_lim(skb, skb_network_header(skb)); + /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */ + ipv6h = ipv6_hdr(skb); if (offset > 0) { struct ipv6_tlv_tnl_enc_lim *tel; |