Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AUTO-CHERRYPICK] Patch CVE-2023-44487 in vendored golang - branch main #7804

Merged
merged 5 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions SPECS/application-gateway-kubernetes-ingress/CVE-2022-21698.patch
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ Differences:
- Removed some comments that don't merge
- Line numbers and such

Modified to apply to vendored code by: Daniel McIlvaney <damcilva@microsoft.com>
- Adjusted paths to work for vendored version

Based on:

From 9075cdf61646b5adf54d3ba77a0e4f6c65cb4fd7 Mon Sep 17 00:00:00 2001
Expand Down Expand Up @@ -37,16 +40,16 @@ Signed-off-by: Kemal Akkoyun <kakkoyun@gmail.com>

Signed-off-by: Kemal Akkoyun <kakkoyun@gmail.com>
---
prometheus/promhttp/instrument_client.go | 28 ++++++--
prometheus/promhttp/instrument_server.go | 82 ++++++++++++++++++------
prometheus/promhttp/option.go | 31 +++++++++
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go | 28 ++++++--
vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go | 82 ++++++++++++++++++------
vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go | 31 +++++++++
3 files changed, 116 insertions(+), 25 deletions(-)
create mode 100644 prometheus/promhttp/option.go
create mode 100644 vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go

diff --git a/prometheus/promhttp/instrument_client.go b/prometheus/promhttp/instrument_client.go
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
index 83c49b6..861b4d2 100644
--- a/prometheus/promhttp/instrument_client.go
+++ b/prometheus/promhttp/instrument_client.go
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_client.go
@@ -49,7 +49,10 @@ func InstrumentRoundTripperInFlight(gauge prometheus.Gauge, next http.RoundTripp
// http.RoundTripper to observe the request result with the provided CounterVec.
// The CounterVec must have zero, one, or two non-const non-curried labels. For
Expand Down Expand Up @@ -114,10 +117,10 @@ index 83c49b6..861b4d2 100644
}
return resp, err
})
diff --git a/prometheus/promhttp/instrument_server.go b/prometheus/promhttp/instrument_server.go
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
index 9db2438..91802f8 100644
--- a/prometheus/promhttp/instrument_server.go
+++ b/prometheus/promhttp/instrument_server.go
--- a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/instrument_server.go
@@ -58,7 +58,12 @@ func InstrumentHandlerInFlight(g prometheus.Gauge, next http.Handler) http.Handl
//
// Note that this method is only guaranteed to never observe negative durations
Expand Down Expand Up @@ -322,11 +325,11 @@ index 9db2438..91802f8 100644
+ return "unknown"
}
}
diff --git a/prometheus/promhttp/option.go b/prometheus/promhttp/option.go
diff --git a/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go
new file mode 100644
index 0000000..35e41bd
--- /dev/null
+++ b/prometheus/promhttp/option.go
+++ b/vendor/github.com/prometheus/client_golang/prometheus/promhttp/option.go
@@ -0,0 +1,31 @@
+// Copyright 2022 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
143 changes: 143 additions & 0 deletions SPECS/application-gateway-kubernetes-ingress/CVE-2023-44487.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
From 6e577d297aa8b47651c1a5c3ebfbf3f2d769be96 Mon Sep 17 00:00:00 2001
From: Damien Neil <dneil@google.com>
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 <security-trybots@go-security-trybots.iam.gserviceaccount.com>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-on: https://go-review.googlesource.com/c/net/+/534215
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>

Modified to apply to vendored code by: Daniel McIlvaney <damcilva@microsoft.com>
- Adjusted paths
- Removed reference to server_test.go
- Removed reference to upgradeRequest() which is not in old versions of the vendored code
- Removed reference to countError() which is not in old versions of the vendored code
---
vendor/golang.org/x/net/http2/server.go | 62 ++++++++++++++++++++++++-
1 file changed, 60 insertions(+), 2 deletions(-)

diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
index de31d72..daa01a7 100644
--- a/vendor/golang.org/x/net/http2/server.go
+++ b/vendor/golang.org/x/net/http2/server.go
@@ -521,9 +521,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
headerTableSize uint32
@@ -895,6 +897,8 @@ func (sc *serverConn) serve() {
return
case gracefulShutdownMsg:
sc.startGracefulShutdownInternal()
+ case handlerDoneMsg:
+ sc.handlerDone()
default:
panic("unknown timer")
}
@@ -940,6 +944,7 @@ var (
idleTimerMsg = new(serverMessage)
shutdownTimerMsg = new(serverMessage)
gracefulShutdownMsg = new(serverMessage)
+ handlerDoneMsg = new(serverMessage)
)

func (sc *serverConn) onSettingsTimer() { sc.sendServeMsg(settingsTimerMsg) }
@@ -1880,8 +1885,7 @@ func (sc *serverConn) processHeaders(f *MetaHeadersFrame) error {
sc.conn.SetReadDeadline(time.Time{})
}

- go sc.runHandler(rw, req, handler)
- return nil
+ return sc.scheduleHandler(id, rw, req, handler)
}

func (st *stream) processTrailerHeaders(f *MetaHeadersFrame) error {
@@ -2124,8 +2128,62 @@ func (sc *serverConn) newWriterAndRequestNoBody(st *stream, rp requestParam) (*r
return rw, req, nil
}

+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 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()
--
2.33.8
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Summary: Application Gateway Ingress Controller
Name: application-gateway-kubernetes-ingress
Version: 1.4.0
Release: 17%{?dist}
Release: 18%{?dist}
License: MIT
Vendor: Microsoft Corporation
Distribution: Mariner
Expand All @@ -26,35 +26,48 @@ Source0: %{name}-%{version}.tar.gz
Source1: %{name}-%{version}-vendor.tar.gz
# If upstream ever upgrades client_goland to 1.11.1, we can get rid of this patch.
Patch0: CVE-2022-21698.patch
Patch1: CVE-2023-44487.patch
BuildRequires: golang >= 1.13
%if %{with_check}
BuildRequires: helm
%endif

%description
This is an ingress controller that can be run on Azure Kubernetes Service (AKS) to allow an Azure Application Gateway
to act as the ingress for an AKS cluster.
This is an ingress controller that can be run on Azure Kubernetes Service (AKS) to allow an Azure Application Gateway
to act as the ingress for an AKS cluster.

%prep
%autosetup -N
rm -rf vendor
tar -xf %{SOURCE1} --no-same-owner
%patch 0 -p1 -d vendor/github.com/prometheus/client_golang
%autopatch -p1

%build
export VERSION=%{version}
export VERSION_PATH=github.com/Azure/application-gateway-kubernetes-ingress/pkg/version

go build -ldflags "-s -X $VERSION_PATH.Version=$VERSION" -mod=vendor -v -o appgw-ingress ./cmd/appgw-ingress

%check
export VERSION=%{version}
export VERSION_PATH=github.com/Azure/application-gateway-kubernetes-ingress/pkg/version
# Helm chart generation is slightly off, skip these tests
go test -ldflags "-s -X $VERSION_PATH.Version=$VERSION" -mod=vendor -v -tags unittest -skip 'TestChart' ./...

%install
mkdir -p %{buildroot}%{_bindir}
cp appgw-ingress %{buildroot}%{_bindir}/


%files
%defattr(-,root,root)
%license LICENSE
%{_bindir}/appgw-ingress

%changelog
* Thu Feb 01 2024 Daniel McIlvaney <damcilva@microsoft.com> - 1.4.0-18
- Address CVE-2023-44487 by patching vendored golang.org/x/net
- Add check section

* Mon Jan 01 2024 Tobias Brick <tobiasb@microsoft.com> - 1.4.0-17
- Patch for CVE-2022-21698
- Moved vendored tarball extraction into %prep and changed from %autosetup to %setup
Expand Down
Loading
Loading