From 79fe0a7963b242994653a257dcb7e62538421fc5 Mon Sep 17 00:00:00 2001 From: CBL-Mariner-Bot <75509084+CBL-Mariner-Bot@users.noreply.github.com> Date: Thu, 1 Feb 2024 16:51:15 -0800 Subject: [PATCH] [AUTO-CHERRYPICK] Fix coredns CVE-2023-44487 by patching vendor tar - branch main (#7628) Co-authored-by: Daniel McIlvaney --- SPECS/coredns/CVE-2023-44487.patch | 152 ++++++++++++++++++++++++++ SPECS/coredns/coredns.signatures.json | 2 +- SPECS/coredns/coredns.spec | 22 +++- 3 files changed, 173 insertions(+), 3 deletions(-) create mode 100644 SPECS/coredns/CVE-2023-44487.patch diff --git a/SPECS/coredns/CVE-2023-44487.patch b/SPECS/coredns/CVE-2023-44487.patch new file mode 100644 index 0000000000..e8c1d32753 --- /dev/null +++ b/SPECS/coredns/CVE-2023-44487.patch @@ -0,0 +1,152 @@ +From b225e7ca6dde1ef5a5ae5ce922861bda011cfabd Mon Sep 17 00:00:00 2001 +From: Damien Neil +Date: Fri, 6 Oct 2023 09:51:19 -0700 +Subject: [PATCH] http2: limit maximum handler goroutines to + MaxConcurrentStreams + +When the peer opens a new stream while we have MaxConcurrentStreams +handler goroutines running, defer starting a handler until one +of the existing handlers exits. + +Fixes golang/go#63417 +Fixes CVE-2023-39325 + +Change-Id: If0531e177b125700f3e24c5ebd24b1023098fa6d +Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/2045854 +TryBot-Result: Security TryBots +Reviewed-by: Ian Cottrell +Reviewed-by: Tatiana Bradley +Run-TryBot: Damien Neil +Reviewed-on: https://go-review.googlesource.com/c/net/+/534215 +Reviewed-by: Michael Pratt +Reviewed-by: Dmitri Shuralyov +LUCI-TryBot-Result: Go LUCI +Auto-Submit: Dmitri Shuralyov +Reviewed-by: Damien Neil + +Modified to apply to vendored code by: Daniel McIlvaney + - Adjusted paths + - Removed reference to server_test.go +--- + + vendor/golang.org/x/net/http2/server.go | 66 ++++++++++++++++++++++++- + vendor/golang.org/x/net/http2/server_test.go | 113 +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 177 insertions(+), 2 deletions(-) + +diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go +index de60fa88f..02c88b6b3 100644 +--- a/vendor/golang.org/x/net/http2/server.go ++++ b/vendor/golang.org/x/net/http2/server.go +@@ -581,9 +581,11 @@ type serverConn 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]*stream ++ unstartedHandlers []unstartedHandler + initialStreamSendWindowSize int32 + maxFrameSize int32 + peerMaxHeaderListSize uint32 // zero means unknown (default) +@@ -981,6 +983,8 @@ func (sc *serverConn) serve() { + return + case gracefulShutdownMsg: + sc.startGracefulShutdownInternal() ++ case handlerDoneMsg: ++ sc.handlerDone() + default: + panic("unknown timer") + } +@@ -1020,6 +1024,7 @@ var ( + idleTimerMsg = new(serverMessage) + shutdownTimerMsg = new(serverMessage) + gracefulShutdownMsg = new(serverMessage) ++ handlerDoneMsg = new(serverMessage) + ) + + func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) } +@@ -2017,8 +2022,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error { + st.readDeadline = time.AfterFunc(sc.hs.ReadTimeout, st.onReadTimeout) + } + +- go sc.runHandler(rw, req, handler) +- return nil ++ return sc.scheduleHandler(id, rw, req, handler) + } + + func (sc *serverConn) upgradeRequest(req *http.Request) { +@@ -2038,6 +2042,10 @@ func (sc *serverConn) upgradeRequest(req *http.Request) { + sc.conn.SetReadDeadline(time.Time{}) + } + ++ // This is the first request on the connection, ++ // so start the handler directly rather than going ++ // through scheduleHandler. ++ sc.curHandlers++ + go sc.runHandler(rw, req, sc.handler.ServeHTTP) + } + +@@ -2278,8 +2286,62 @@ func (sc *serverConn) newResponseWriter(st *stream, req *http.Request) *response + return &responseWriter{rws: rws} + } + ++type unstartedHandler struct { ++ streamID uint32 ++ rw *responseWriter ++ req *http.Request ++ handler func(http.ResponseWriter, *http.Request) ++} ++ ++// scheduleHandler starts a handler goroutine, ++// or schedules one to start as soon as an existing handler finishes. ++func (sc *serverConn) scheduleHandler(streamID uint32, rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.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 sc.countError("too_many_early_resets", ConnectionError(ErrCodeEnhanceYourCalm)) ++ } ++ sc.unstartedHandlers = append(sc.unstartedHandlers, unstartedHandler{ ++ streamID: streamID, ++ rw: rw, ++ req: req, ++ handler: handler, ++ }) ++ return nil ++} ++ ++func (sc *serverConn) 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] = unstartedHandler{} // don't retain references ++ } ++ sc.unstartedHandlers = sc.unstartedHandlers[i:] ++ if len(sc.unstartedHandlers) == 0 { ++ sc.unstartedHandlers = nil ++ } ++} ++ + // Run on its own goroutine. + func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) { ++ defer sc.sendServeMsg(handlerDoneMsg) + didPanic := true + defer func() { + rw.rws.stream.cancelCtx() diff --git a/SPECS/coredns/coredns.signatures.json b/SPECS/coredns/coredns.signatures.json index 9104f96f89..86eb2d8f4d 100644 --- a/SPECS/coredns/coredns.signatures.json +++ b/SPECS/coredns/coredns.signatures.json @@ -3,4 +3,4 @@ "coredns-1.11.1.tar.gz": "4e1cde1759d1705baa9375127eb405cd2f5031f9152947bb958a51fee5898d8c", "coredns-1.11.1-vendor.tar.gz": "f6713fb6bdb6da88bab4c93a53317907991fa2e304cc2f224bfee88df6c26846" } -} \ No newline at end of file +} diff --git a/SPECS/coredns/coredns.spec b/SPECS/coredns/coredns.spec index df018f3d6c..45551362be 100644 --- a/SPECS/coredns/coredns.spec +++ b/SPECS/coredns/coredns.spec @@ -3,7 +3,7 @@ Summary: Fast and flexible DNS server Name: coredns Version: 1.11.1 -Release: 1%{?dist} +Release: 2%{?dist} License: Apache License 2.0 Vendor: Microsoft Corporation Distribution: Mariner @@ -32,22 +32,37 @@ Source0: %{name}-%{version}.tar.gz Source1: %{name}-%{version}-vendor.tar.gz Patch0: makefile-buildoption-commitnb.patch +# Patch for old x/net/http2 vendored code, apply after vendored code is extracted. +Patch1000: CVE-2023-44487.patch + BuildRequires: golang >= 1.12 %description CoreDNS is a fast and flexible DNS server. %prep -%autosetup -p1 +%autosetup -N +%autopatch -p1 -M 999 %build # create vendor folder from the vendor tarball and set vendor mode tar -xf %{SOURCE1} --no-same-owner +patch -p1 < %{PATCH1000} export BUILDOPTS="-mod=vendor -v" # set commit number that correspond to the github tag for that version export GITCOMMIT="ae2bbc29be1aaae0b3ded5d188968a6c97bb3144" make +%check +# From go.test.yml +go install github.com/fatih/faillint@latest && \ +(cd request && go test -v -race ./...) && \ +(cd core && go test -v -race ./...) && \ +(cd coremain && go test -v -race ./...) && \ +(cd plugin && go test -v -race ./...) && \ +(cd test && go test -v -race ./...) && \ +./coredns -version + %install install -m 755 -d %{buildroot}%{_bindir} install -p -m 755 -t %{buildroot}%{_bindir} %{name} @@ -58,6 +73,9 @@ install -p -m 755 -t %{buildroot}%{_bindir} %{name} %{_bindir}/%{name} %changelog +* Mon Jan 29 2024 Daniel McIlvaney - 1.11.1-2 +- Address CVE-2023-44487 by patching vendored golang.org/x/net + * Tue Oct 18 2023 Nicolas Guibourge - 1.11.1-1 - Upgrade to 1.11.1 to match version required by kubernetes