Skip to content

Commit 5b01014

Browse files
qsndavem330
authored andcommitted
geneve: avoid use-after-free of skb->data
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: 08399ef ("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>
1 parent 3de81b7 commit 5b01014

1 file changed

Lines changed: 4 additions & 10 deletions

File tree

drivers/net/geneve.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
859859
struct geneve_dev *geneve = netdev_priv(dev);
860860
struct geneve_sock *gs4;
861861
struct rtable *rt = NULL;
862-
const struct iphdr *iip; /* interior IP header */
863862
int err = -EINVAL;
864863
struct flowi4 fl4;
865864
__u8 tos, ttl;
@@ -890,8 +889,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
890889
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
891890
skb_reset_mac_header(skb);
892891

893-
iip = ip_hdr(skb);
894-
895892
if (info) {
896893
const struct ip_tunnel_key *key = &info->key;
897894
u8 *opts = NULL;
@@ -911,7 +908,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
911908
if (unlikely(err))
912909
goto tx_error;
913910

914-
tos = ip_tunnel_ecn_encap(key->tos, iip, skb);
911+
tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
915912
ttl = key->ttl;
916913
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
917914
} else {
@@ -920,7 +917,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
920917
if (unlikely(err))
921918
goto tx_error;
922919

923-
tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, iip, skb);
920+
tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, ip_hdr(skb), skb);
924921
ttl = geneve->ttl;
925922
if (!ttl && IN_MULTICAST(ntohl(fl4.daddr)))
926923
ttl = 1;
@@ -952,7 +949,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
952949
{
953950
struct geneve_dev *geneve = netdev_priv(dev);
954951
struct dst_entry *dst = NULL;
955-
const struct iphdr *iip; /* interior IP header */
956952
struct geneve_sock *gs6;
957953
int err = -EINVAL;
958954
struct flowi6 fl6;
@@ -982,8 +978,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
982978
sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
983979
skb_reset_mac_header(skb);
984980

985-
iip = ip_hdr(skb);
986-
987981
if (info) {
988982
const struct ip_tunnel_key *key = &info->key;
989983
u8 *opts = NULL;
@@ -1004,7 +998,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
1004998
if (unlikely(err))
1005999
goto tx_error;
10061000

1007-
prio = ip_tunnel_ecn_encap(key->tos, iip, skb);
1001+
prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
10081002
ttl = key->ttl;
10091003
label = info->key.label;
10101004
} else {
@@ -1014,7 +1008,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
10141008
goto tx_error;
10151009

10161010
prio = ip_tunnel_ecn_encap(ip6_tclass(fl6.flowlabel),
1017-
iip, skb);
1011+
ip_hdr(skb), skb);
10181012
ttl = geneve->ttl;
10191013
if (!ttl && ipv6_addr_is_multicast(&fl6.daddr))
10201014
ttl = 1;

0 commit comments

Comments
 (0)