• Jason A. Donenfeld's avatar
    wireguard: netlink: check for dangling peer via is_dead instead of empty list · 55b6c738
    Jason A. Donenfeld authored
    If all peers are removed via wg_peer_remove_all(), rather than setting
    peer_list to empty, the peer is added to a temporary list with a head on
    the stack of wg_peer_remove_all(). If a netlink dump is resumed and the
    cursored peer is one that has been removed via wg_peer_remove_all(), it
    will iterate from that peer and then attempt to dump freed peers.
    
    Fix this by instead checking peer->is_dead, which was explictly created
    for this purpose. Also move up the device_update_lock lockdep assertion,
    since reading is_dead 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
    
    Cc: stable@vger.kernel.org
    Fixes: e7096c13 ("net: WireGuard secure network tunnel")
    Reported-by: default avatarLillian Berry <lillian@star-ark.net>
    Signed-off-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
    Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
    Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
    55b6c738
netlink.c 17.9 KB