Skip to content

Commit 39bb781

Browse files
zx2c4syphyr
authored andcommitted
wireguard: netlink: send staged packets when setting initial private key
commit f58d0a9b4c6a7a5199c3af967e43cc8b654604d4 upstream. Packets bound for peers can queue up prior to the device private key being set. For example, if persistent keepalive is set, a packet is queued up to be sent as soon as the device comes up. However, if the private key hasn't been set yet, the handshake message never sends, and no timer is armed to retry, since that would be pointless. But, if a user later sets a private key, the expectation is that those queued packets, such as a persistent keepalive, are actually sent. So adjust the configuration logic to account for this edge case, and add a test case to make sure this works. Maxim noticed this with a wg-quick(8) config to the tune of: [Interface] PostUp = wg set %i private-key somefile [Peer] PublicKey = ... Endpoint = ... PersistentKeepalive = 25 Here, the private key gets set after the device comes up using a PostUp script, triggering the bug. Fixes: e7096c131e51 ("net: WireGuard secure network tunnel") Cc: stable@vger.kernel.org Reported-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> Tested-by: Maxim Cournoyer <maxim.cournoyer@gmail.com> Link: https://lore.kernel.org/wireguard/87fs7xtqrv.fsf@gmail.com/ Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 67abbd0 commit 39bb781

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

src/netlink.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,7 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
544544
u8 *private_key = nla_data(info->attrs[WGDEVICE_A_PRIVATE_KEY]);
545545
u8 public_key[NOISE_PUBLIC_KEY_LEN];
546546
struct wg_peer *peer, *temp;
547+
bool send_staged_packets;
547548

548549
if (!crypto_memneq(wg->static_identity.static_private,
549550
private_key, NOISE_PUBLIC_KEY_LEN))
@@ -562,14 +563,17 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
562563
}
563564

564565
down_write(&wg->static_identity.lock);
565-
wg_noise_set_static_identity_private_key(&wg->static_identity,
566-
private_key);
567-
list_for_each_entry_safe(peer, temp, &wg->peer_list,
568-
peer_list) {
566+
send_staged_packets = !wg->static_identity.has_identity && netif_running(wg->dev);
567+
wg_noise_set_static_identity_private_key(&wg->static_identity, private_key);
568+
send_staged_packets = send_staged_packets && wg->static_identity.has_identity;
569+
570+
wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
571+
list_for_each_entry_safe(peer, temp, &wg->peer_list, peer_list) {
569572
wg_noise_precompute_static_static(peer);
570573
wg_noise_expire_current_peer_keypairs(peer);
574+
if (send_staged_packets)
575+
wg_packet_send_staged_packets(peer);
571576
}
572-
wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
573577
up_write(&wg->static_identity.lock);
574578
}
575579
skip_set_private_key:

src/tests/netns.sh

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -522,10 +522,32 @@ n2 bash -c 'printf 0 > /proc/sys/net/ipv4/conf/all/rp_filter'
522522
n1 ping -W 1 -c 1 192.168.241.2
523523
[[ $(n2 wg show wg0 endpoints) == "$pub1 10.0.0.3:1" ]]
524524

525-
ip1 link del veth1
526-
ip1 link del veth3
527-
ip1 link del wg0
528-
ip2 link del wg0
525+
ip1 link del dev veth3
526+
ip1 link del dev wg0
527+
ip2 link del dev wg0
528+
529+
# Make sure persistent keep alives are sent when an adapter comes up
530+
ip1 link add dev wg0 type wireguard
531+
n1 wg set wg0 private-key <(echo "$key1") peer "$pub2" endpoint 10.0.0.1:1 persistent-keepalive 1
532+
read _ _ tx_bytes < <(n1 wg show wg0 transfer)
533+
[[ $tx_bytes -eq 0 ]]
534+
ip1 link set dev wg0 up
535+
read _ _ tx_bytes < <(n1 wg show wg0 transfer)
536+
[[ $tx_bytes -gt 0 ]]
537+
ip1 link del dev wg0
538+
# This should also happen even if the private key is set later
539+
ip1 link add dev wg0 type wireguard
540+
n1 wg set wg0 peer "$pub2" endpoint 10.0.0.1:1 persistent-keepalive 1
541+
read _ _ tx_bytes < <(n1 wg show wg0 transfer)
542+
[[ $tx_bytes -eq 0 ]]
543+
ip1 link set dev wg0 up
544+
read _ _ tx_bytes < <(n1 wg show wg0 transfer)
545+
[[ $tx_bytes -eq 0 ]]
546+
n1 wg set wg0 private-key <(echo "$key1")
547+
read _ _ tx_bytes < <(n1 wg show wg0 transfer)
548+
[[ $tx_bytes -gt 0 ]]
549+
ip1 link del dev veth1
550+
ip1 link del dev wg0
529551

530552
# We test that Netlink/IPC is working properly by doing things that usually cause split responses
531553
ip0 link add dev wg0 type wireguard

0 commit comments

Comments
 (0)