geneve: avoid use-after-free of skb->data
[ Upstream commit 5b01014759991887b1e450c9def01e58c02ab81b ] geneve{,6}_build_skb can end up doing a pskb_expand_head(), which makes the ip_hdr(skb) reference we stashed earlier stale. Since it's only needed as an argument to ip_tunnel_ecn_encap(), move this directly in the function call. Fixes: 08399efc6319 ("geneve: ensure ECN info is handled properly in all tx/rx paths") Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Reviewed-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
a89e2ff894
commit
6e682c528b
@ -815,7 +815,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
struct geneve_dev *geneve = netdev_priv(dev);
|
||||
struct geneve_sock *gs4 = geneve->sock4;
|
||||
struct rtable *rt = NULL;
|
||||
const struct iphdr *iip; /* interior IP header */
|
||||
int err = -EINVAL;
|
||||
struct flowi4 fl4;
|
||||
__u8 tos, ttl;
|
||||
@ -842,8 +841,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
iip = ip_hdr(skb);
|
||||
|
||||
if (info) {
|
||||
const struct ip_tunnel_key *key = &info->key;
|
||||
u8 *opts = NULL;
|
||||
@ -859,7 +856,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
if (unlikely(err))
|
||||
goto err;
|
||||
|
||||
tos = ip_tunnel_ecn_encap(key->tos, iip, skb);
|
||||
tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
|
||||
ttl = key->ttl;
|
||||
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
|
||||
} else {
|
||||
@ -869,7 +866,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
if (unlikely(err))
|
||||
goto err;
|
||||
|
||||
tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, iip, skb);
|
||||
tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, ip_hdr(skb), skb);
|
||||
ttl = geneve->ttl;
|
||||
if (!ttl && IN_MULTICAST(ntohl(fl4.daddr)))
|
||||
ttl = 1;
|
||||
@ -903,7 +900,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
struct geneve_dev *geneve = netdev_priv(dev);
|
||||
struct geneve_sock *gs6 = geneve->sock6;
|
||||
struct dst_entry *dst = NULL;
|
||||
const struct iphdr *iip; /* interior IP header */
|
||||
int err = -EINVAL;
|
||||
struct flowi6 fl6;
|
||||
__u8 prio, ttl;
|
||||
@ -927,8 +923,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
|
||||
skb_reset_mac_header(skb);
|
||||
|
||||
iip = ip_hdr(skb);
|
||||
|
||||
if (info) {
|
||||
const struct ip_tunnel_key *key = &info->key;
|
||||
u8 *opts = NULL;
|
||||
@ -945,7 +939,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
if (unlikely(err))
|
||||
goto err;
|
||||
|
||||
prio = ip_tunnel_ecn_encap(key->tos, iip, skb);
|
||||
prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
|
||||
ttl = key->ttl;
|
||||
} else {
|
||||
udp_csum = false;
|
||||
@ -954,7 +948,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
|
||||
if (unlikely(err))
|
||||
goto err;
|
||||
|
||||
prio = ip_tunnel_ecn_encap(fl6.flowi6_tos, iip, skb);
|
||||
prio = ip_tunnel_ecn_encap(fl6.flowi6_tos, ip_hdr(skb), skb);
|
||||
ttl = geneve->ttl;
|
||||
if (!ttl && ipv6_addr_is_multicast(&fl6.daddr))
|
||||
ttl = 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user