Alternative TLS implementation in Go
Go to file
Adam Langley b7ba182f28 crypto/tls: fix deadlock when racing to complete handshake.
After renegotiation support was added (af125a5193c) it's possible for a
Write to block on a Read when racing to complete the handshake:
   1. The Write determines that a handshake is needed and tries to
      take the neccesary locks in the correct order.
   2. The Read also determines that a handshake is needed and wins
      the race to take the locks.
   3. The Read goroutine completes the handshake and wins a race
      to unlock and relock c.in, which it'll hold when waiting for
      more network data.

If the application-level protocol requires the Write to complete before
data can be read then the system as a whole will deadlock.

Unfortunately it doesn't appear possible to reverse the locking order of
c.in and handshakeMutex because we might read a renegotiation request at
any point and need to be able to do a handshake without unlocking.

So this change adds a sync.Cond that indicates that a goroutine has
committed to doing a handshake. Other interested goroutines can wait on
that Cond when needed.

The test for this isn't great. I was able to reproduce the deadlock with
it only when building with -race. (Because -race happened to alter the
timing just enough.)

Fixes #17101.

Change-Id: I4e8757f7b82a84e46c9963a977d089f0fb675495
Reviewed-on: https://go-review.googlesource.com/29164
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2016-09-22 18:36:58 +00:00
testdata crypto/tls: add KeyLogWriter for debugging 2016-08-27 17:20:55 +00:00
alert.go crypto/tls: make error prefix uniform. 2016-04-14 16:28:53 +00:00
cipher_suites.go crypto/tls: fix comment typo. 2016-08-18 21:52:31 +00:00
common.go crypto/tls: Add mutex to protect KeyLogWriter 2016-09-10 21:31:48 +00:00
conn_test.go crypto/tls: add Config.Clone 2016-09-01 04:26:12 +00:00
conn.go crypto/tls: fix deadlock when racing to complete handshake. 2016-09-22 18:36:58 +00:00
example_test.go crypto/x509: add example of using a custom root list. 2014-02-19 11:18:35 -05:00
generate_cert.go crypto/tls: Support ECDSA keys in generate_cert.go 2014-07-28 14:46:34 -07:00
handshake_client_test.go crypto/tls: fix deadlock when racing to complete handshake. 2016-09-22 18:36:58 +00:00
handshake_client.go crypto/tls: add KeyLogWriter for debugging 2016-08-27 17:20:55 +00:00
handshake_messages_test.go crypto/tls: decouple handshake signatures from the handshake hash. 2015-04-30 03:47:02 +00:00
handshake_messages.go crypto/tls: allow renegotiation to be handled by a client. 2016-04-28 17:56:28 +00:00
handshake_server_test.go crypto/tls: add Config.Clone 2016-09-01 04:26:12 +00:00
handshake_server.go crypto/tls: add KeyLogWriter for debugging 2016-08-27 17:20:55 +00:00
handshake_test.go crypto/tls: fix WriteTo method signature 2016-08-16 14:36:19 +00:00
key_agreement.go crypto/tls: make error prefix uniform. 2016-04-14 16:28:53 +00:00
prf_test.go crypto/tls: decouple handshake signatures from the handshake hash. 2015-04-30 03:47:02 +00:00
prf.go all: standardize RFC mention format 2016-04-12 21:07:52 +00:00
ticket.go crypto/tls: minor refactors for readability 2016-03-14 21:17:37 +00:00
tls_test.go crypto/tls: add Config.Clone 2016-09-01 04:26:12 +00:00
tls.go crypto/tls: add Config.Clone 2016-09-01 04:26:12 +00:00