In the Linux kernel, the following vulnerability has been resolved:
wireguard: netlink: check for dangling peer via is_dead instead of empty list
If all peers are removed via wgpeerremoveall(), rather than setting peerlist to empty, the peer is added to a temporary list with a head on the stack of wgpeerremoveall(). If a netlink dump is resumed and the cursored peer is one that has been removed via wgpeerremoveall(), it will iterate from that peer and then attempt to dump freed peers.
Fix this by instead checking peer->isdead, which was explictly created for this purpose. Also move up the deviceupdatelock lockdep assertion, since reading isdead relies on that.
It can be reproduced by a small script like:
echo "Setting config..."
ip link add dev wg0 type wireguard
wg setconf wg0 /big-config
(
while true; do
echo "Showing config..."
wg showconf wg0 > /dev/null
done
) &
sleep 4
wg setconf wg0 <(printf "[Peer]\nPublicKey=$(wg genkey)\n")
Resulting in:
BUG: KASAN: slab-use-after-free in __lock_acquire+0x182a/0x1b20
Read of size 8 at addr ffff88811956ec70 by task wg/59
CPU: 2 PID: 59 Comm: wg Not tainted 6.8.0-rc2-debug+ #5
Call Trace:
<TASK>
dump_stack_lvl+0x47/0x70
print_address_description.constprop.0+0x2c/0x380
print_report+0xab/0x250
kasan_report+0xba/0xf0
__lock_acquire+0x182a/0x1b20
lock_acquire+0x191/0x4b0
down_read+0x80/0x440
get_peer+0x140/0xcb0
wg_get_device_dump+0x471/0x1130