提交 218b47e4 编写于 作者: J Jason A. Donenfeld 提交者: Zheng Zengkai

wireguard: use synchronize_net rather than synchronize_rcu

stable inclusion
from stable-5.10.43
commit f74da2c2546c402cd2fc4165ef54b48cce6e39cc
bugzilla: 109284
CVE: NA

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

commit 24b70eee upstream.

Many of the synchronization points are sometimes called under the rtnl
lock, which means we should use synchronize_net rather than
synchronize_rcu. Under the hood, this expands to using the expedited
flavor of function in the event that rtnl is held, in order to not stall
other concurrent changes.

This fixes some very, very long delays when removing multiple peers at
once, which would cause some operations to take several minutes.

Fixes: e7096c13 ("net: WireGuard secure network tunnel")
Cc: stable@vger.kernel.org
Signed-off-by: NJason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 26133eba
...@@ -89,7 +89,7 @@ static void peer_make_dead(struct wg_peer *peer) ...@@ -89,7 +89,7 @@ static void peer_make_dead(struct wg_peer *peer)
/* Mark as dead, so that we don't allow jumping contexts after. */ /* Mark as dead, so that we don't allow jumping contexts after. */
WRITE_ONCE(peer->is_dead, true); WRITE_ONCE(peer->is_dead, true);
/* The caller must now synchronize_rcu() for this to take effect. */ /* The caller must now synchronize_net() for this to take effect. */
} }
static void peer_remove_after_dead(struct wg_peer *peer) static void peer_remove_after_dead(struct wg_peer *peer)
...@@ -161,7 +161,7 @@ void wg_peer_remove(struct wg_peer *peer) ...@@ -161,7 +161,7 @@ void wg_peer_remove(struct wg_peer *peer)
lockdep_assert_held(&peer->device->device_update_lock); lockdep_assert_held(&peer->device->device_update_lock);
peer_make_dead(peer); peer_make_dead(peer);
synchronize_rcu(); synchronize_net();
peer_remove_after_dead(peer); peer_remove_after_dead(peer);
} }
...@@ -179,7 +179,7 @@ void wg_peer_remove_all(struct wg_device *wg) ...@@ -179,7 +179,7 @@ void wg_peer_remove_all(struct wg_device *wg)
peer_make_dead(peer); peer_make_dead(peer);
list_add_tail(&peer->peer_list, &dead_peers); list_add_tail(&peer->peer_list, &dead_peers);
} }
synchronize_rcu(); synchronize_net();
list_for_each_entry_safe(peer, temp, &dead_peers, peer_list) list_for_each_entry_safe(peer, temp, &dead_peers, peer_list)
peer_remove_after_dead(peer); peer_remove_after_dead(peer);
} }
......
...@@ -430,7 +430,7 @@ void wg_socket_reinit(struct wg_device *wg, struct sock *new4, ...@@ -430,7 +430,7 @@ void wg_socket_reinit(struct wg_device *wg, struct sock *new4,
if (new4) if (new4)
wg->incoming_port = ntohs(inet_sk(new4)->inet_sport); wg->incoming_port = ntohs(inet_sk(new4)->inet_sport);
mutex_unlock(&wg->socket_update_lock); mutex_unlock(&wg->socket_update_lock);
synchronize_rcu(); synchronize_net();
sock_free(old4); sock_free(old4);
sock_free(old6); sock_free(old6);
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册