From 725fc9cfad6678b4b6a9c5080d0d84d329a854fa Mon Sep 17 00:00:00 2001 From: Gaukas Wang Date: Sun, 26 Nov 2023 11:45:37 -0700 Subject: [PATCH] sync: go 1.21.4 (#261) [release-branch.go1.21] crypto/tls: QUIC: fix panics when processing post-handshake messages The check for fragmentary post-handshake messages in QUICConn.HandleData was reversed, resulting in a potential panic when HandleData receives a partial message. In addition, HandleData wasn't checking the size of buffered post-handshake messages. Produce an error when a post-handshake message is larger than maxHandshake. TestQUICConnectionState was using an onHandleCryptoData hook in runTestQUICConnection that was never being called. (I think it was inadvertently removed at some point while the CL was in review.) Fix this test while making the hook more general. For #62266 Fixes #62290 Change-Id: I210b70634e50beb456ab3977eb11272b8724c241 Reviewed-on: https://go-review.googlesource.com/c/go/+/522595 Run-TryBot: Damien Neil TryBot-Result: Gopher Robot Reviewed-by: Marten Seemann Reviewed-by: Roland Shoemaker (cherry picked from commit e92c0f8) Reviewed-on: https://go-review.googlesource.com/c/go/+/523039 Auto-Submit: Dmitri Shuralyov LUCI-TryBot-Result: Go LUCI Co-authored-by: Damien Neil <52544+neild@users.noreply.github.com> Co-authored-by: GopherBot <8566911+gopherbot@users.noreply.github.com> --- u_quic.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/u_quic.go b/u_quic.go index e0c44d55..c312522e 100644 --- a/u_quic.go +++ b/u_quic.go @@ -7,6 +7,7 @@ package tls import ( "context" "errors" + "fmt" ) // A UQUICConn represents a connection which uses a QUIC implementation as the underlying @@ -108,16 +109,22 @@ func (q *UQUICConn) HandleData(level QUICEncryptionLevel, data []byte) error { return nil } // The handshake goroutine has exited. + c.handshakeMutex.Lock() + defer c.handshakeMutex.Unlock() c.hand.Write(c.quic.readbuf) c.quic.readbuf = nil for q.conn.hand.Len() >= 4 && q.conn.handshakeErr == nil { b := q.conn.hand.Bytes() n := int(b[1])<<16 | int(b[2])<<8 | int(b[3]) - if 4+n < len(b) { + if n > maxHandshake { + q.conn.handshakeErr = fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake) + break + } + if len(b) < 4+n { return nil } if err := q.conn.handlePostHandshakeMessage(); err != nil { - return quicError(err) + q.conn.handshakeErr = err } } if q.conn.handshakeErr != nil {