• John Fastabend's avatar
    net/tls: fix transition through disconnect with close · 32857cf5
    John Fastabend authored
    It is possible (via shutdown()) for TCP socks to go through TCP_CLOSE
    state via tcp_disconnect() without actually calling tcp_close which
    would then call the tls close callback. Because of this a user could
    disconnect a socket then put it in a LISTEN state which would break
    our assumptions about sockets always being ESTABLISHED state.
    
    More directly because close() can call unhash() and unhash is
    implemented by sockmap if a sockmap socket has TLS enabled we can
    incorrectly destroy the psock from unhash() and then call its close
    handler again. But because the psock (sockmap socket representation)
    is already destroyed we call close handler in sk->prot. However,
    in some cases (TLS BASE/BASE case) this will still point at the
    sockmap close handler resulting in a circular call and crash reported
    by syzbot.
    
    To fix both above issues implement the unhash() routine for TLS.
    
    v4:
     - add note about tls offload still needing the fix;
     - move sk_proto to the cold cache line;
     - split TX context free into "release" and "free",
       otherwise the GC work itself is in already freed
       memory;
     - more TX before RX for consistency;
     - reuse tls_ctx_free();
     - schedule the GC work after we're done with context
       to avoid UAF;
     - don't set the unhash in all modes, all modes "inherit"
       TLS_BASE's callbacks anyway;
     - disable the unhash hook for TLS_HW.
    
    Fixes: 3c4d7559 ("tls: kernel TLS support")
    Reported-by: default avatarEric Dumazet <edumazet@google.com>
    Signed-off-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
    Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    32857cf5
tls.h 18.1 KB