Commit 6e682c52 authored by Sabrina Dubroca's avatar Sabrina Dubroca Committed by Greg Kroah-Hartman

geneve: avoid use-after-free of skb->data

[ Upstream commit 5b010147 ]

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: 08399efc ("geneve: ensure ECN info is handled properly in all tx/rx paths")
Signed-off-by: default avatarSabrina Dubroca <sd@queasysnail.net>
Reviewed-by: default avatarJohn W. Linville <linville@tuxdriver.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a89e2ff8
...@@ -815,7 +815,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, ...@@ -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_dev *geneve = netdev_priv(dev);
struct geneve_sock *gs4 = geneve->sock4; struct geneve_sock *gs4 = geneve->sock4;
struct rtable *rt = NULL; struct rtable *rt = NULL;
const struct iphdr *iip; /* interior IP header */
int err = -EINVAL; int err = -EINVAL;
struct flowi4 fl4; struct flowi4 fl4;
__u8 tos, ttl; __u8 tos, ttl;
...@@ -842,8 +841,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, ...@@ -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); sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
iip = ip_hdr(skb);
if (info) { if (info) {
const struct ip_tunnel_key *key = &info->key; const struct ip_tunnel_key *key = &info->key;
u8 *opts = NULL; u8 *opts = NULL;
...@@ -859,7 +856,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, ...@@ -859,7 +856,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (unlikely(err)) if (unlikely(err))
goto 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; ttl = key->ttl;
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
} else { } else {
...@@ -869,7 +866,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, ...@@ -869,7 +866,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (unlikely(err)) if (unlikely(err))
goto 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; ttl = geneve->ttl;
if (!ttl && IN_MULTICAST(ntohl(fl4.daddr))) if (!ttl && IN_MULTICAST(ntohl(fl4.daddr)))
ttl = 1; ttl = 1;
...@@ -903,7 +900,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, ...@@ -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_dev *geneve = netdev_priv(dev);
struct geneve_sock *gs6 = geneve->sock6; struct geneve_sock *gs6 = geneve->sock6;
struct dst_entry *dst = NULL; struct dst_entry *dst = NULL;
const struct iphdr *iip; /* interior IP header */
int err = -EINVAL; int err = -EINVAL;
struct flowi6 fl6; struct flowi6 fl6;
__u8 prio, ttl; __u8 prio, ttl;
...@@ -927,8 +923,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, ...@@ -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); sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
iip = ip_hdr(skb);
if (info) { if (info) {
const struct ip_tunnel_key *key = &info->key; const struct ip_tunnel_key *key = &info->key;
u8 *opts = NULL; u8 *opts = NULL;
...@@ -945,7 +939,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, ...@@ -945,7 +939,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (unlikely(err)) if (unlikely(err))
goto 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; ttl = key->ttl;
} else { } else {
udp_csum = false; udp_csum = false;
...@@ -954,7 +948,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, ...@@ -954,7 +948,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
if (unlikely(err)) if (unlikely(err))
goto 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; ttl = geneve->ttl;
if (!ttl && ipv6_addr_is_multicast(&fl6.daddr)) if (!ttl && ipv6_addr_is_multicast(&fl6.daddr))
ttl = 1; ttl = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment