Skip to content

Commit f58d0a9

Browse files
zx2c4davem330
authored andcommitted
wireguard: netlink: send staged packets when setting initial private key
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: e7096c1 ("net: WireGuard secure network tunnel") Cc: [email protected] Reported-by: Maxim Cournoyer <[email protected]> Tested-by: Maxim Cournoyer <[email protected]> Link: https://lore.kernel.org/wireguard/[email protected]/ Signed-off-by: Jason A. Donenfeld <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 7387943 commit f58d0a9

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

drivers/net/wireguard/netlink.c

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

550551
if (!crypto_memneq(wg->static_identity.static_private,
551552
private_key, NOISE_PUBLIC_KEY_LEN))
@@ -564,14 +565,17 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
564565
}
565566

566567
down_write(&wg->static_identity.lock);
567-
wg_noise_set_static_identity_private_key(&wg->static_identity,
568-
private_key);
569-
list_for_each_entry_safe(peer, temp, &wg->peer_list,
570-
peer_list) {
568+
send_staged_packets = !wg->static_identity.has_identity && netif_running(wg->dev);
569+
wg_noise_set_static_identity_private_key(&wg->static_identity, private_key);
570+
send_staged_packets = send_staged_packets && wg->static_identity.has_identity;
571+
572+
wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
573+
list_for_each_entry_safe(peer, temp, &wg->peer_list, peer_list) {
571574
wg_noise_precompute_static_static(peer);
572575
wg_noise_expire_current_peer_keypairs(peer);
576+
if (send_staged_packets)
577+
wg_packet_send_staged_packets(peer);
573578
}
574-
wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
575579
up_write(&wg->static_identity.lock);
576580
}
577581
skip_set_private_key:

tools/testing/selftests/wireguard/netns.sh

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

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

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

0 commit comments

Comments
 (0)