From 1e00416f2fe5b720d35e7b22b5625fd5878398c3 Mon Sep 17 00:00:00 2001 From: David Benoit Date: Tue, 19 Sep 2023 13:15:35 -0400 Subject: [PATCH 1/2] enable mainline gating --- .github/workflows/gating.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/gating.yml diff --git a/.github/workflows/gating.yml b/.github/workflows/gating.yml new file mode 100644 index 00000000000..83a1ada7b57 --- /dev/null +++ b/.github/workflows/gating.yml @@ -0,0 +1,33 @@ +name: "Test Pull Request" + +on: + pull_request: + branches: + - 'main' + - 'go1.*-fips-release' + - 'go1.*-openssl-fips' + +# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions +permissions: + actions: none + checks: read + contents: none + deployments: none + id-token: none + issues: read + discussions: read + packages: none + pages: none + pull-requests: read + repository-projects: none + security-events: none + statuses: none + +jobs: + test_pr: + # Look up the images for each selected compose + name: "Test Pull Request" + uses: golang-fips/release/.github/workflows/test-ubi-centos.yml@main + with: + go_fips_ref: ${{ github.event.pull_request.head.sha }} + composes: "ubi7,ubi8,ubi9,c8s,c9s" From 6f622e2d395de8b5c3288ca32aeb1274427f9d49 Mon Sep 17 00:00:00 2001 From: Derek Parker Date: Thu, 12 Oct 2023 15:39:17 -0400 Subject: [PATCH 2/2] h2-bundle: fix CVE-2023-39325 Backport of https://github.com/golang/net/commit/b225e7ca6dde1ef5a5ae5ce922861bda011cfabd --- src/net/http/h2_bundle.go | 62 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go index 06f8808dc62..86c4932c7c0 100644 --- a/src/net/http/h2_bundle.go +++ b/src/net/http/h2_bundle.go @@ -4087,9 +4087,11 @@ type http2serverConn struct { advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client curClientStreams uint32 // number of open streams initiated by the client curPushedStreams uint32 // number of open streams initiated by server push + curHandlers uint32 // number of running handler goroutines maxClientStreamID uint32 // max ever seen from client (odd), or 0 if there have been no client requests maxPushPromiseID uint32 // ID of the last push promise (even), or 0 if there have been no pushes streams map[uint32]*http2stream + unstartedHandlers []http2unstartedHandler initialStreamSendWindowSize int32 maxFrameSize int32 headerTableSize uint32 @@ -4470,6 +4472,8 @@ func (sc *http2serverConn) serve() { return case http2gracefulShutdownMsg: sc.startGracefulShutdownInternal() + case http2handlerDoneMsg: + sc.handlerDone() default: panic("unknown timer") } @@ -4515,6 +4519,7 @@ var ( http2idleTimerMsg = new(http2serverMessage) http2shutdownTimerMsg = new(http2serverMessage) http2gracefulShutdownMsg = new(http2serverMessage) + http2handlerDoneMsg = new(http2serverMessage) ) func (sc *http2serverConn) onSettingsTimer() { sc.sendServeMsg(http2settingsTimerMsg) } @@ -5458,8 +5463,7 @@ func (sc *http2serverConn) processHeaders(f *http2MetaHeadersFrame) error { sc.conn.SetReadDeadline(time.Time{}) } - go sc.runHandler(rw, req, handler) - return nil + return sc.scheduleHandler(id, rw, req, handler) } func (st *http2stream) processTrailerHeaders(f *http2MetaHeadersFrame) error { @@ -5704,6 +5708,7 @@ func (sc *http2serverConn) newWriterAndRequestNoBody(st *http2stream, rp http2re // Run on its own goroutine. func (sc *http2serverConn) runHandler(rw *http2responseWriter, req *Request, handler func(ResponseWriter, *Request)) { + defer sc.sendServeMsg(http2handlerDoneMsg) didPanic := true defer func() { rw.rws.stream.cancelCtx() @@ -10309,3 +10314,56 @@ func (ws *http2randomWriteScheduler) Pop() (http2FrameWriteRequest, bool) { } return http2FrameWriteRequest{}, false } + +type http2unstartedHandler struct { + streamID uint32 + rw *http2responseWriter + req *Request + handler func(ResponseWriter, *Request) +} + +// scheduleHandler starts a handler goroutine, +// or schedules one to start as soon as an existing handler finishes. +func (sc *http2serverConn) scheduleHandler(streamID uint32, rw *http2responseWriter, req *Request, handler func(ResponseWriter, *Request)) error { + sc.serveG.check() + maxHandlers := sc.advMaxStreams + if sc.curHandlers < maxHandlers { + sc.curHandlers++ + go sc.runHandler(rw, req, handler) + return nil + } + if len(sc.unstartedHandlers) > int(4*sc.advMaxStreams) { + return http2ConnectionError(http2ErrCodeEnhanceYourCalm) + } + sc.unstartedHandlers = append(sc.unstartedHandlers, http2unstartedHandler{ + streamID: streamID, + rw: rw, + req: req, + handler: handler, + }) + return nil +} + +func (sc *http2serverConn) handlerDone() { + sc.serveG.check() + sc.curHandlers-- + i := 0 + maxHandlers := sc.advMaxStreams + for ; i < len(sc.unstartedHandlers); i++ { + u := sc.unstartedHandlers[i] + if sc.streams[u.streamID] == nil { + // This stream was reset before its goroutine had a chance to start. + continue + } + if sc.curHandlers >= maxHandlers { + break + } + sc.curHandlers++ + go sc.runHandler(u.rw, u.req, u.handler) + sc.unstartedHandlers[i] = http2unstartedHandler{} // don't retain references + } + sc.unstartedHandlers = sc.unstartedHandlers[i:] + if len(sc.unstartedHandlers) == 0 { + sc.unstartedHandlers = nil + } +}