| From foo@baz Sat Mar 18 22:03:53 CST 2017 |
| From: Jakub Kicinski <jakub.kicinski@netronome.com> |
| Date: Fri, 24 Feb 2017 11:43:36 -0800 |
| Subject: vxlan: lock RCU on TX path |
| |
| From: Jakub Kicinski <jakub.kicinski@netronome.com> |
| |
| |
| [ 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@netronome.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| 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) |