[PATCH 4.10 15/63] vxlan: lock RCU on TX path

From: Greg Kroah-Hartman
Date: Mon Mar 20 2017 - 14:18:07 EST


4.10-stable review patch. If anyone has any objections, please let me know.

------------------

From: Jakub Kicinski <jakub.kicinski@xxxxxxxxxxxxx>


[ Upstream commit 56de859e9967c070464a9a9f4f18d73f9447298e ]

There is no guarantees that callers of the TX path will hold
the RCU lock. Grab it explicitly.

Fixes: c6fcc4fc5f8b ("vxlan: avoid using stale vxlan socket.")
Signed-off-by: Jakub Kicinski <jakub.kicinski@xxxxxxxxxxxxx>
Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
---
drivers/net/vxlan.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)

--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2062,6 +2062,7 @@ static void vxlan_xmit_one(struct sk_buf
src_port = udp_flow_src_port(dev_net(dev), skb, vxlan->cfg.port_min,
vxlan->cfg.port_max, true);

+ rcu_read_lock();
if (dst->sa.sa_family == AF_INET) {
struct vxlan_sock *sock4 = rcu_dereference(vxlan->vn4_sock);
struct rtable *rt;
@@ -2084,7 +2085,7 @@ static void vxlan_xmit_one(struct sk_buf
dst_port, vni, &rt->dst,
rt->rt_flags);
if (err)
- return;
+ goto out_unlock;
} else if (info->key.tun_flags & TUNNEL_DONT_FRAGMENT) {
df = htons(IP_DF);
}
@@ -2123,7 +2124,7 @@ static void vxlan_xmit_one(struct sk_buf
dst_port, vni, ndst,
rt6i_flags);
if (err)
- return;
+ goto out_unlock;
}

tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
@@ -2140,6 +2141,8 @@ static void vxlan_xmit_one(struct sk_buf
label, src_port, dst_port, !udp_sum);
#endif
}
+out_unlock:
+ rcu_read_unlock();
return;

drop:
@@ -2148,6 +2151,7 @@ drop:
return;

tx_error:
+ rcu_read_unlock();
if (err == -ELOOP)
dev->stats.collisions++;
else if (err == -ENETUNREACH)