aboutsummaryrefslogtreecommitdiff
path: root/src/net/http
diff options
context:
space:
mode:
authorDmitri Shuralyov <dmitshur@golang.org>2024-04-03 15:52:28 -0400
committerGopher Robot <gobot@golang.org>2024-04-05 22:18:39 +0000
commit5d18f889276fec9fd478124a0691bd7d1bca37c1 (patch)
treeb40e2657e3c8ea94606cfda1db0ae6210551068d /src/net/http
parentd186dde81844badfa961f8af5044136dce8dc39e (diff)
downloadgo-5d18f889276fec9fd478124a0691bd7d1bca37c1.tar.xz
all: update vendored golang.org/x/net to v0.23.0
Pull in CL 576155: ba872109 http2: close connections when receiving too many headers Fixes CVE-2023-45288. Fixes #65051. Change-Id: I3f4e3d565189b4ed552935fe1d96f94ebac86d48 Reviewed-on: https://go-review.googlesource.com/c/go/+/576295 Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Than McIntosh <thanm@google.com>
Diffstat (limited to 'src/net/http')
-rw-r--r--src/net/http/h2_bundle.go35
1 files changed, 33 insertions, 2 deletions
diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go
index af839dd1bf..9285f90d9e 100644
--- a/src/net/http/h2_bundle.go
+++ b/src/net/http/h2_bundle.go
@@ -2972,6 +2972,7 @@ func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFr
if size > remainSize {
hdec.SetEmitEnabled(false)
mh.Truncated = true
+ remainSize = 0
return
}
remainSize -= size
@@ -2984,6 +2985,36 @@ func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFr
var hc http2headersOrContinuation = hf
for {
frag := hc.HeaderBlockFragment()
+
+ // Avoid parsing large amounts of headers that we will then discard.
+ // If the sender exceeds the max header list size by too much,
+ // skip parsing the fragment and close the connection.
+ //
+ // "Too much" is either any CONTINUATION frame after we've already
+ // exceeded the max header list size (in which case remainSize is 0),
+ // or a frame whose encoded size is more than twice the remaining
+ // header list bytes we're willing to accept.
+ if int64(len(frag)) > int64(2*remainSize) {
+ if http2VerboseLogs {
+ log.Printf("http2: header list too large")
+ }
+ // It would be nice to send a RST_STREAM before sending the GOAWAY,
+ // but the structure of the server's frame writer makes this difficult.
+ return nil, http2ConnectionError(http2ErrCodeProtocol)
+ }
+
+ // Also close the connection after any CONTINUATION frame following an
+ // invalid header, since we stop tracking the size of the headers after
+ // an invalid one.
+ if invalid != nil {
+ if http2VerboseLogs {
+ log.Printf("http2: invalid header: %v", invalid)
+ }
+ // It would be nice to send a RST_STREAM before sending the GOAWAY,
+ // but the structure of the server's frame writer makes this difficult.
+ return nil, http2ConnectionError(http2ErrCodeProtocol)
+ }
+
if _, err := hdec.Write(frag); err != nil {
return nil, http2ConnectionError(http2ErrCodeCompression)
}
@@ -7672,7 +7703,7 @@ type http2ClientConn struct {
readerErr error // set before readerDone is closed
idleTimeout time.Duration // or 0 for never
- idleTimer *time.Timer
+ idleTimer http2timer
mu sync.Mutex // guards following
cond *sync.Cond // hold mu; broadcast on flow/closed changes
@@ -8191,7 +8222,7 @@ func (t *http2Transport) newClientConn(c net.Conn, singleUse bool, hooks *http2t
}
if d := t.idleConnTimeout(); d != 0 {
cc.idleTimeout = d
- cc.idleTimer = time.AfterFunc(d, cc.onIdleTimeout)
+ cc.idleTimer = cc.afterFunc(d, cc.onIdleTimeout)
}
if http2VerboseLogs {
t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr())