Commit 7bb77d4b authored by David S. Miller's avatar David S. Miller

Merge branch 'wg-fixes'

Jason A. Donenfeld says:

====================
wireguard fixes for 5.6-rc1

Here are fixes for WireGuard before 5.6-rc1 is tagged. It includes:

1) A fix for a UaF (caused by kmalloc failing during a very small
   allocation) that syzkaller found, from Eric Dumazet.

2) A fix for a deadlock that syzkaller found, along with an additional
   selftest to ensure that the bug fix remains correct, from me.

3) Two little fixes/cleanups to the selftests from Krzysztof Kozlowski
   and me.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 52b5ae50 88f404a9
...@@ -263,6 +263,7 @@ static int add(struct allowedips_node __rcu **trie, u8 bits, const u8 *key, ...@@ -263,6 +263,7 @@ static int add(struct allowedips_node __rcu **trie, u8 bits, const u8 *key,
} else { } else {
node = kzalloc(sizeof(*node), GFP_KERNEL); node = kzalloc(sizeof(*node), GFP_KERNEL);
if (unlikely(!node)) { if (unlikely(!node)) {
list_del(&newnode->peer_list);
kfree(newnode); kfree(newnode);
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -569,10 +569,8 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info) ...@@ -569,10 +569,8 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
private_key); private_key);
list_for_each_entry_safe(peer, temp, &wg->peer_list, list_for_each_entry_safe(peer, temp, &wg->peer_list,
peer_list) { peer_list) {
if (wg_noise_precompute_static_static(peer)) BUG_ON(!wg_noise_precompute_static_static(peer));
wg_noise_expire_current_peer_keypairs(peer); wg_noise_expire_current_peer_keypairs(peer);
else
wg_peer_remove(peer);
} }
wg_cookie_checker_precompute_device_keys(&wg->cookie_checker); wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
up_write(&wg->static_identity.lock); up_write(&wg->static_identity.lock);
......
...@@ -46,17 +46,21 @@ void __init wg_noise_init(void) ...@@ -46,17 +46,21 @@ void __init wg_noise_init(void)
/* Must hold peer->handshake.static_identity->lock */ /* Must hold peer->handshake.static_identity->lock */
bool wg_noise_precompute_static_static(struct wg_peer *peer) bool wg_noise_precompute_static_static(struct wg_peer *peer)
{ {
bool ret = true; bool ret;
down_write(&peer->handshake.lock); down_write(&peer->handshake.lock);
if (peer->handshake.static_identity->has_identity) if (peer->handshake.static_identity->has_identity) {
ret = curve25519( ret = curve25519(
peer->handshake.precomputed_static_static, peer->handshake.precomputed_static_static,
peer->handshake.static_identity->static_private, peer->handshake.static_identity->static_private,
peer->handshake.remote_static); peer->handshake.remote_static);
else } else {
u8 empty[NOISE_PUBLIC_KEY_LEN] = { 0 };
ret = curve25519(empty, empty, peer->handshake.remote_static);
memset(peer->handshake.precomputed_static_static, 0, memset(peer->handshake.precomputed_static_static, 0,
NOISE_PUBLIC_KEY_LEN); NOISE_PUBLIC_KEY_LEN);
}
up_write(&peer->handshake.lock); up_write(&peer->handshake.lock);
return ret; return ret;
} }
......
...@@ -38,9 +38,8 @@ ip0() { pretty 0 "ip $*"; ip -n $netns0 "$@"; } ...@@ -38,9 +38,8 @@ ip0() { pretty 0 "ip $*"; ip -n $netns0 "$@"; }
ip1() { pretty 1 "ip $*"; ip -n $netns1 "$@"; } ip1() { pretty 1 "ip $*"; ip -n $netns1 "$@"; }
ip2() { pretty 2 "ip $*"; ip -n $netns2 "$@"; } ip2() { pretty 2 "ip $*"; ip -n $netns2 "$@"; }
sleep() { read -t "$1" -N 1 || true; } sleep() { read -t "$1" -N 1 || true; }
waitiperf() { pretty "${1//*-}" "wait for iperf:5201"; while [[ $(ss -N "$1" -tlp 'sport = 5201') != *iperf3* ]]; do sleep 0.1; done; } waitiperf() { pretty "${1//*-}" "wait for iperf:5201 pid $2"; while [[ $(ss -N "$1" -tlpH 'sport = 5201') != *\"iperf3\",pid=$2,fd=* ]]; do sleep 0.1; done; }
waitncatudp() { pretty "${1//*-}" "wait for udp:1111"; while [[ $(ss -N "$1" -ulp 'sport = 1111') != *ncat* ]]; do sleep 0.1; done; } waitncatudp() { pretty "${1//*-}" "wait for udp:1111 pid $2"; while [[ $(ss -N "$1" -ulpH 'sport = 1111') != *\"ncat\",pid=$2,fd=* ]]; do sleep 0.1; done; }
waitncattcp() { pretty "${1//*-}" "wait for tcp:1111"; while [[ $(ss -N "$1" -tlp 'sport = 1111') != *ncat* ]]; do sleep 0.1; done; }
waitiface() { pretty "${1//*-}" "wait for $2 to come up"; ip netns exec "$1" bash -c "while [[ \$(< \"/sys/class/net/$2/operstate\") != up ]]; do read -t .1 -N 0 || true; done;"; } waitiface() { pretty "${1//*-}" "wait for $2 to come up"; ip netns exec "$1" bash -c "while [[ \$(< \"/sys/class/net/$2/operstate\") != up ]]; do read -t .1 -N 0 || true; done;"; }
cleanup() { cleanup() {
...@@ -119,22 +118,22 @@ tests() { ...@@ -119,22 +118,22 @@ tests() {
# TCP over IPv4 # TCP over IPv4
n2 iperf3 -s -1 -B 192.168.241.2 & n2 iperf3 -s -1 -B 192.168.241.2 &
waitiperf $netns2 waitiperf $netns2 $!
n1 iperf3 -Z -t 3 -c 192.168.241.2 n1 iperf3 -Z -t 3 -c 192.168.241.2
# TCP over IPv6 # TCP over IPv6
n1 iperf3 -s -1 -B fd00::1 & n1 iperf3 -s -1 -B fd00::1 &
waitiperf $netns1 waitiperf $netns1 $!
n2 iperf3 -Z -t 3 -c fd00::1 n2 iperf3 -Z -t 3 -c fd00::1
# UDP over IPv4 # UDP over IPv4
n1 iperf3 -s -1 -B 192.168.241.1 & n1 iperf3 -s -1 -B 192.168.241.1 &
waitiperf $netns1 waitiperf $netns1 $!
n2 iperf3 -Z -t 3 -b 0 -u -c 192.168.241.1 n2 iperf3 -Z -t 3 -b 0 -u -c 192.168.241.1
# UDP over IPv6 # UDP over IPv6
n2 iperf3 -s -1 -B fd00::2 & n2 iperf3 -s -1 -B fd00::2 &
waitiperf $netns2 waitiperf $netns2 $!
n1 iperf3 -Z -t 3 -b 0 -u -c fd00::2 n1 iperf3 -Z -t 3 -b 0 -u -c fd00::2
} }
...@@ -207,7 +206,7 @@ n1 ping -W 1 -c 1 192.168.241.2 ...@@ -207,7 +206,7 @@ n1 ping -W 1 -c 1 192.168.241.2
n1 wg set wg0 peer "$pub2" allowed-ips 192.168.241.0/24 n1 wg set wg0 peer "$pub2" allowed-ips 192.168.241.0/24
exec 4< <(n1 ncat -l -u -p 1111) exec 4< <(n1 ncat -l -u -p 1111)
ncat_pid=$! ncat_pid=$!
waitncatudp $netns1 waitncatudp $netns1 $ncat_pid
n2 ncat -u 192.168.241.1 1111 <<<"X" n2 ncat -u 192.168.241.1 1111 <<<"X"
read -r -N 1 -t 1 out <&4 && [[ $out == "X" ]] read -r -N 1 -t 1 out <&4 && [[ $out == "X" ]]
kill $ncat_pid kill $ncat_pid
...@@ -216,7 +215,7 @@ n1 wg set wg0 peer "$more_specific_key" allowed-ips 192.168.241.2/32 ...@@ -216,7 +215,7 @@ n1 wg set wg0 peer "$more_specific_key" allowed-ips 192.168.241.2/32
n2 wg set wg0 listen-port 9997 n2 wg set wg0 listen-port 9997
exec 4< <(n1 ncat -l -u -p 1111) exec 4< <(n1 ncat -l -u -p 1111)
ncat_pid=$! ncat_pid=$!
waitncatudp $netns1 waitncatudp $netns1 $ncat_pid
n2 ncat -u 192.168.241.1 1111 <<<"X" n2 ncat -u 192.168.241.1 1111 <<<"X"
! read -r -N 1 -t 1 out <&4 || false ! read -r -N 1 -t 1 out <&4 || false
kill $ncat_pid kill $ncat_pid
...@@ -516,6 +515,12 @@ n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0,10.0.0.0/8,100.0.0.0/10,172.16. ...@@ -516,6 +515,12 @@ n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0,10.0.0.0/8,100.0.0.0/10,172.16.
n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0 n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0
n0 wg set wg0 peer "$pub2" allowed-ips ::/0,1700::/111,5000::/4,e000::/37,9000::/75 n0 wg set wg0 peer "$pub2" allowed-ips ::/0,1700::/111,5000::/4,e000::/37,9000::/75
n0 wg set wg0 peer "$pub2" allowed-ips ::/0 n0 wg set wg0 peer "$pub2" allowed-ips ::/0
n0 wg set wg0 peer "$pub2" remove
low_order_points=( AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38= )
n0 wg set wg0 private-key /dev/null ${low_order_points[@]/#/peer }
[[ -z $(n0 wg show wg0 peers) ]]
n0 wg set wg0 private-key <(echo "$key1") ${low_order_points[@]/#/peer }
[[ -z $(n0 wg show wg0 peers) ]]
ip0 link del wg0 ip0 link del wg0
declare -A objects declare -A objects
......
CONFIG_LOCALVERSION="-debug" CONFIG_LOCALVERSION="-debug"
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_POINTER=y CONFIG_FRAME_POINTER=y
CONFIG_STACK_VALIDATION=y CONFIG_STACK_VALIDATION=y
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment