From 9ce5426da0c91ce452679e26bcc902cb9c3aeb8f Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 25 Sep 2020 13:19:36 +0700 Subject: [PATCH] fix deadlock in crypto setup when it is closed while handling a message --- internal/handshake/crypto_setup.go | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index 7e0bb99a..30760a65 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -299,7 +299,6 @@ func (h *cryptoSetup) RunHandshake() { h.mutex.Unlock() h.runner.OnHandshakeComplete() case <-h.closeChan: - close(h.messageChan) // wait until the Handshake() go routine has returned <-h.handshakeDone case alert := <-h.alertChan: @@ -346,6 +345,8 @@ readLoop: break readLoop case <-h.handshakeDone: break readLoop + case <-h.closeChan: + break readLoop } } // We're done with the Initial encryption level after processing a ClientHello / ServerHello, @@ -504,13 +505,18 @@ func (h *cryptoSetup) ReadHandshakeMessage() ([]byte, error) { if !h.readFirstHandshakeMessage { h.readFirstHandshakeMessage = true } else { - h.isReadingHandshakeMessage <- struct{}{} + select { + case h.isReadingHandshakeMessage <- struct{}{}: + case <-h.closeChan: + return nil, errors.New("error while handling the handshake message") + } } - msg, ok := <-h.messageChan - if !ok { + select { + case msg := <-h.messageChan: + return msg, nil + case <-h.closeChan: return nil, errors.New("error while handling the handshake message") } - return msg, nil } func (h *cryptoSetup) SetReadKey(encLevel qtls.EncryptionLevel, suite *qtls.CipherSuiteTLS13, trafficSecret []byte) { @@ -625,7 +631,11 @@ func (h *cryptoSetup) WriteRecord(p []byte) (int, error) { } func (h *cryptoSetup) SendAlert(alert uint8) { - h.alertChan <- alert + select { + case h.alertChan <- alert: + case <-h.closeChan: + // no need to send an alert when we've already closed + } } // used a callback in the handshakeSealer and handshakeOpener