• John Fastabend's avatar
    bpf: sockmap/tls, close can race with map free · 95fa1454
    John Fastabend authored
    When a map free is called and in parallel a socket is closed we
    have two paths that can potentially reset the socket prot ops, the
    bpf close() path and the map free path. This creates a problem
    with which prot ops should be used from the socket closed side.
    
    If the map_free side completes first then we want to call the
    original lowest level ops. However, if the tls path runs first
    we want to call the sockmap ops. Additionally there was no locking
    around prot updates in TLS code paths so the prot ops could
    be changed multiple times once from TLS path and again from sockmap
    side potentially leaving ops pointed at either TLS or sockmap
    when psock and/or tls context have already been destroyed.
    
    To fix this race first only update ops inside callback lock
    so that TLS, sockmap and lowest level all agree on prot state.
    Second and a ULP callback update() so that lower layers can
    inform the upper layer when they are being removed allowing the
    upper layer to reset prot ops.
    
    This gets us close to allowing sockmap and tls to be stacked
    in arbitrary order but will save that patch for *next trees.
    
    v4:
     - make sure we don't free things for device;
     - remove the checks which swap the callbacks back
       only if TLS is at the top.
    
    Reported-by: syzbot+06537213db7ba2745c4a@syzkaller.appspotmail.com
    Fixes: 02c558b2 ("bpf: sockmap, support for msg_peek in sk_msg with redirect ingress")
    Signed-off-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
    Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
    Reviewed-by: default avatarDirk van der Merwe <dirk.vandermerwe@netronome.com>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    95fa1454
tls_main.c 21.5 KB