net/tls: fix transition through disconnect with close
authorJohn Fastabend <john.fastabend@gmail.com>
Fri, 19 Jul 2019 17:29:18 +0000 (10:29 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Mon, 22 Jul 2019 14:04:17 +0000 (16:04 +0200)
commit32857cf57f920cdc03b5095f08febec94cf9c36b
tree1ac174d1b05d6d1a3644c6cc5defbe6c6e41345b
parent313ab004805cf52a42673b15852b3842474ccd87
net/tls: fix transition through disconnect with close

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: 3c4d7559159bf ("tls: kernel TLS support")
Reported-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Documentation/networking/tls-offload.rst
include/net/tls.h
net/tls/tls_main.c