Skip to content

Commit 7fa8c05

Browse files
[AUTO-CHERRYPICK] cdi: CVE-2022-41717, CVE-2022-32149, CVE-2024-28180 - branch main (#10342)
Co-authored-by: bfjelds <bfjelds@microsoft.com>
1 parent 38841ec commit 7fa8c05

4 files changed

Lines changed: 318 additions & 1 deletion

File tree

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
From 434eadcdbc3b0256971992e8c70027278364c72c Mon Sep 17 00:00:00 2001
2+
From: Roland Shoemaker <bracewell@google.com>
3+
Date: Fri, 2 Sep 2022 09:35:37 -0700
4+
Subject: [PATCH] language: reject excessively large Accept-Language strings
5+
6+
The BCP 47 tag parser has quadratic time complexity due to inherent
7+
aspects of its design. Since the parser is, by design, exposed to
8+
untrusted user input, this can be leveraged to force a program to
9+
consume significant time parsing Accept-Language headers.
10+
11+
The parser cannot be easily rewritten to fix this behavior for
12+
various reasons. Instead the solution implemented in this CL is to
13+
limit the total complexity of tags passed into ParseAcceptLanguage
14+
by limiting the number of dashes in the string to 1000. This should
15+
be more than enough for the majority of real world use cases, where
16+
the number of tags being sent is likely to be in the single digits.
17+
18+
Thanks to the OSS-Fuzz project for discovering this issue and to Adam
19+
Korczynski (ADA Logics) for writing the fuzz case and for reporting the
20+
issue.
21+
22+
Fixes CVE-2022-32149
23+
Fixes golang/go#56152
24+
25+
Change-Id: I7bda1d84cee2b945039c203f26869d58ee9374ae
26+
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1565112
27+
Reviewed-by: Damien Neil <dneil@google.com>
28+
Reviewed-by: Tatiana Bradley <tatianabradley@google.com>
29+
Reviewed-on: https://go-review.googlesource.com/c/text/+/442235
30+
TryBot-Result: Gopher Robot <gobot@golang.org>
31+
Auto-Submit: Roland Shoemaker <roland@golang.org>
32+
Run-TryBot: Roland Shoemaker <roland@golang.org>
33+
---
34+
vendor/golang.org/x/text/language/parse.go | 5 +++++
35+
1 files changed, 5 insertions(+)
36+
37+
diff --git a/vendor/golang.org/x/text/language/parse.go b/vendor/golang.org/x/text/language/parse.go
38+
index 59b04100..b982d9e4 100644
39+
--- a/vendor/golang.org/x/text/language/parse.go
40+
+++ b/vendor/golang.org/x/text/language/parse.go
41+
@@ -147,6 +147,7 @@ func update(b *language.Builder, part ...interface{}) (err error) {
42+
}
43+
44+
var errInvalidWeight = errors.New("ParseAcceptLanguage: invalid weight")
45+
+var errTagListTooLarge = errors.New("tag list exceeds max length")
46+
47+
// ParseAcceptLanguage parses the contents of an Accept-Language header as
48+
// defined in http://www.ietf.org/rfc/rfc2616.txt and returns a list of Tags and
49+
@@ -164,6 +165,10 @@ func ParseAcceptLanguage(s string) (tag []Tag, q []float32, err error) {
50+
}
51+
}()
52+
53+
+ if strings.Count(s, "-") > 1000 {
54+
+ return nil, nil, errTagListTooLarge
55+
+ }
56+
+
57+
var entry string
58+
for s != "" {
59+
if entry, s = split(s, ','); entry == "" {
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
From 1e63c2f08a10a150fa02c50ece89b340ae64efe4 Mon Sep 17 00:00:00 2001
2+
From: Damien Neil <dneil@google.com>
3+
Date: Tue, 06 Dec 2022 11:57:53 -0800
4+
Subject: [PATCH] http2: limit canonical header cache by bytes, not entries
5+
6+
The canonical header cache is a per-connection cache mapping header
7+
keys to their canonicalized form. (For example, "foo-bar" => "Foo-Bar").
8+
We limit the number of entries in the cache to prevent an attacker
9+
from consuming unbounded amounts of memory by sending many unique
10+
keys, but a small number of very large keys can still consume an
11+
unreasonable amount of memory.
12+
13+
Track the amount of memory consumed by the cache and limit it based
14+
on memory rather than number of entries.
15+
16+
Thanks to Josselin Costanzi for reporting this issue.
17+
18+
For golang/go#56350
19+
20+
Change-Id: I41db4c9823ed5bf371a9881accddff1268489b16
21+
Reviewed-on: https://go-review.googlesource.com/c/net/+/455635
22+
Reviewed-by: Jenny Rakoczy <jenny@golang.org>
23+
Run-TryBot: Damien Neil <dneil@google.com>
24+
TryBot-Result: Gopher Robot <gobot@golang.org>
25+
---
26+
27+
diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
28+
index e35a76c..4eb7617 100644
29+
--- a/vendor/golang.org/x/net/http2/server.go
30+
+++ b/vendor/golang.org/x/net/http2/server.go
31+
@@ -527,6 +527,7 @@
32+
headerTableSize uint32
33+
peerMaxHeaderListSize uint32 // zero means unknown (default)
34+
canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case
35+
+ canonHeaderKeysSize int // canonHeader keys size in bytes
36+
writingFrame bool // started writing a frame (on serve goroutine or separate)
37+
writingFrameAsync bool // started a frame on its own goroutine but haven't heard back on wroteFrameCh
38+
needsFrameFlush bool // last frame write wasn't a flush
39+
@@ -766,6 +767,13 @@
40+
}
41+
}
42+
43+
+// maxCachedCanonicalHeadersKeysSize is an arbitrarily-chosen limit on the size
44+
+// of the entries in the canonHeader cache.
45+
+// This should be larger than the size of unique, uncommon header keys likely to
46+
+// be sent by the peer, while not so high as to permit unreasonable memory usage
47+
+// if the peer sends an unbounded number of unique header keys.
48+
+const maxCachedCanonicalHeadersKeysSize = 2048
49+
+
50+
func (sc *serverConn) canonicalHeader(v string) string {
51+
sc.serveG.check()
52+
buildCommonHeaderMapsOnce()
53+
@@ -781,14 +789,10 @@
54+
sc.canonHeader = make(map[string]string)
55+
}
56+
cv = http.CanonicalHeaderKey(v)
57+
- // maxCachedCanonicalHeaders is an arbitrarily-chosen limit on the number of
58+
- // entries in the canonHeader cache. This should be larger than the number
59+
- // of unique, uncommon header keys likely to be sent by the peer, while not
60+
- // so high as to permit unreasonable memory usage if the peer sends an unbounded
61+
- // number of unique header keys.
62+
- const maxCachedCanonicalHeaders = 32
63+
- if len(sc.canonHeader) < maxCachedCanonicalHeaders {
64+
+ size := 100 + len(v)*2 // 100 bytes of map overhead + key + value
65+
+ if sc.canonHeaderKeysSize+size <= maxCachedCanonicalHeadersKeysSize {
66+
sc.canonHeader[v] = cv
67+
+ sc.canonHeaderKeysSize += size
68+
}
69+
return cv
70+
}
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
From 0dd4dd541c665fb292d664f77604ba694726f298 Mon Sep 17 00:00:00 2001
2+
From: Jacob Hoffman-Andrews <github@hoffman-andrews.com>
3+
Date: Thu, 7 Mar 2024 14:25:21 -0800
4+
Subject: [PATCH] v2: backport decompression limit fix (#109)
5+
6+
Backport from #107.
7+
---
8+
CHANGELOG.md | 84 ++++++++++++++++++++++++++++++++++++++++++++++++
9+
crypter.go | 6 ++++
10+
encoding.go | 21 +++++++++---
11+
encoding_test.go | 34 ++++++++++++++++++++
12+
4 files changed, 141 insertions(+), 4 deletions(-)
13+
create mode 100644 CHANGELOG.md
14+
15+
diff --git a/CHANGELOG.md b/CHANGELOG.md
16+
new file mode 100644
17+
index 0000000..8e6e913
18+
--- /dev/null
19+
+++ b/CHANGELOG.md
20+
@@ -0,0 +1,84 @@
21+
+# v4.0.1
22+
+
23+
+## Fixed
24+
+
25+
+ - An attacker could send a JWE containing compressed data that used large
26+
+ amounts of memory and CPU when decompressed by `Decrypt` or `DecryptMulti`.
27+
+ Those functions now return an error if the decompressed data would exceed
28+
+ 250kB or 10x the compressed size (whichever is larger). Thanks to
29+
+ Enze Wang@Alioth and Jianjun Chen@Zhongguancun Lab (@zer0yu and @chenjj)
30+
+ for reporting.
31+
+
32+
+# v4.0.0
33+
+
34+
+This release makes some breaking changes in order to more thoroughly
35+
+address the vulnerabilities discussed in [Three New Attacks Against JSON Web
36+
+Tokens][1], "Sign/encrypt confusion", "Billion hash attack", and "Polyglot
37+
+token".
38+
+
39+
+## Changed
40+
+
41+
+ - Limit JWT encryption types (exclude password or public key types) (#78)
42+
+ - Enforce minimum length for HMAC keys (#85)
43+
+ - jwt: match any audience in a list, rather than requiring all audiences (#81)
44+
+ - jwt: accept only Compact Serialization (#75)
45+
+ - jws: Add expected algorithms for signatures (#74)
46+
+ - Require specifying expected algorithms for ParseEncrypted,
47+
+ ParseSigned, ParseDetached, jwt.ParseEncrypted, jwt.ParseSigned,
48+
+ jwt.ParseSignedAndEncrypted (#69, #74)
49+
+ - Usually there is a small, known set of appropriate algorithms for a program
50+
+ to use and it's a mistake to allow unexpected algorithms. For instance the
51+
+ "billion hash attack" relies in part on programs accepting the PBES2
52+
+ encryption algorithm and doing the necessary work even if they weren't
53+
+ specifically configured to allow PBES2.
54+
+ - Revert "Strip padding off base64 strings" (#82)
55+
+ - The specs require base64url encoding without padding.
56+
+ - Minimum supported Go version is now 1.21
57+
+
58+
+## Added
59+
+
60+
+ - ParseSignedCompact, ParseSignedJSON, ParseEncryptedCompact, ParseEncryptedJSON.
61+
+ - These allow parsing a specific serialization, as opposed to ParseSigned and
62+
+ ParseEncrypted, which try to automatically detect which serialization was
63+
+ provided. It's common to require a specific serialization for a specific
64+
+ protocol - for instance JWT requires Compact serialization.
65+
+
66+
+[1]: https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
67+
+
68+
+# v3.0.3
69+
+
70+
+## Fixed
71+
+
72+
+ - Limit decompression output size to prevent a DoS. Backport from v4.0.1.
73+
+
74+
+# v3.0.2
75+
+
76+
+## Fixed
77+
+
78+
+ - DecryptMulti: handle decompression error (#19)
79+
+
80+
+## Changed
81+
+
82+
+ - jwe/CompactSerialize: improve performance (#67)
83+
+ - Increase the default number of PBKDF2 iterations to 600k (#48)
84+
+ - Return the proper algorithm for ECDSA keys (#45)
85+
+
86+
+## Added
87+
+
88+
+ - Add Thumbprint support for opaque signers (#38)
89+
+
90+
+# v3.0.1
91+
+
92+
+## Fixed
93+
+
94+
+ - Security issue: an attacker specifying a large "p2c" value can cause
95+
+ JSONWebEncryption.Decrypt and JSONWebEncryption.DecryptMulti to consume large
96+
+ amounts of CPU, causing a DoS. Thanks to Matt Schwager (@mschwager) for the
97+
+ disclosure and to Tom Tervoort for originally publishing the category of attack.
98+
+ https://i.blackhat.com/BH-US-23/Presentations/US-23-Tervoort-Three-New-Attacks-Against-JSON-Web-Tokens.pdf
99+
+
100+
+# v2.6.3
101+
+
102+
+## Fixed
103+
+
104+
+ - Limit decompression output size to prevent a DoS. Backport from v4.0.1.
105+
diff --git a/vendor/gopkg.in/square/go-jose.v2/crypter.go b/vendor/gopkg.in/square/go-jose.v2/crypter.go
106+
index 73aab0f..0ae2e5e 100644
107+
--- a/vendor/gopkg.in/square/go-jose.v2/crypter.go
108+
+++ b/vendor/gopkg.in/square/go-jose.v2/crypter.go
109+
@@ -406,6 +406,9 @@ func (ctx *genericEncrypter) Options() EncrypterOptions {
110+
// Decrypt and validate the object and return the plaintext. Note that this
111+
// function does not support multi-recipient, if you desire multi-recipient
112+
// decryption use DecryptMulti instead.
113+
+//
114+
+// Automatically decompresses plaintext, but returns an error if the decompressed
115+
+// data would be >250kB or >10x the size of the compressed data, whichever is larger.
116+
func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error) {
117+
headers := obj.mergedHeaders(nil)
118+
119+
@@ -470,6 +473,9 @@ func (obj JSONWebEncryption) Decrypt(decryptionKey interface{}) ([]byte, error)
120+
// with support for multiple recipients. It returns the index of the recipient
121+
// for which the decryption was successful, the merged headers for that recipient,
122+
// and the plaintext.
123+
+//
124+
+// Automatically decompresses plaintext, but returns an error if the decompressed
125+
+// data would be >250kB or >3x the size of the compressed data, whichever is larger.
126+
func (obj JSONWebEncryption) DecryptMulti(decryptionKey interface{}) (int, Header, []byte, error) {
127+
globalHeaders := obj.mergedHeaders(nil)
128+
129+
diff --git a/vendor/gopkg.in/square/go-jose.v2/encoding.go b/vendor/gopkg.in/square/go-jose.v2/encoding.go
130+
index 40b688b..636f6c8 100644
131+
--- a/vendor/gopkg.in/square/go-jose.v2/encoding.go
132+
+++ b/vendor/gopkg.in/square/go-jose.v2/encoding.go
133+
@@ -21,6 +21,7 @@ import (
134+
"compress/flate"
135+
"encoding/base64"
136+
"encoding/binary"
137+
+ "fmt"
138+
"io"
139+
"math/big"
140+
"strings"
141+
@@ -85,7 +86,7 @@ func decompress(algorithm CompressionAlgorithm, input []byte) ([]byte, error) {
142+
}
143+
}
144+
145+
-// Compress with DEFLATE
146+
+// deflate compresses the input.
147+
func deflate(input []byte) ([]byte, error) {
148+
output := new(bytes.Buffer)
149+
150+
@@ -97,15 +98,27 @@ func deflate(input []byte) ([]byte, error) {
151+
return output.Bytes(), err
152+
}
153+
154+
-// Decompress with DEFLATE
155+
+// inflate decompresses the input.
156+
+//
157+
+// Errors if the decompressed data would be >250kB or >10x the size of the
158+
+// compressed data, whichever is larger.
159+
func inflate(input []byte) ([]byte, error) {
160+
output := new(bytes.Buffer)
161+
reader := flate.NewReader(bytes.NewBuffer(input))
162+
163+
- _, err := io.Copy(output, reader)
164+
- if err != nil {
165+
+ maxCompressedSize := 10 * int64(len(input))
166+
+ if maxCompressedSize < 250000 {
167+
+ maxCompressedSize = 250000
168+
+ }
169+
+
170+
+ limit := maxCompressedSize + 1
171+
+ n, err := io.CopyN(output, reader, limit)
172+
+ if err != nil && err != io.EOF {
173+
return nil, err
174+
}
175+
+ if n == limit {
176+
+ return nil, fmt.Errorf("uncompressed data would be too large (>%d bytes)", maxCompressedSize)
177+
+ }
178+
179+
err = reader.Close()
180+
return output.Bytes(), err

SPECS/containerized-data-importer/containerized-data-importer.spec

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
Summary: Container native virtualization
1919
Name: containerized-data-importer
2020
Version: 1.55.0
21-
Release: 19%{?dist}
21+
Release: 20%{?dist}
2222
License: ASL 2.0
2323
Vendor: Microsoft Corporation
2424
Distribution: Mariner
@@ -35,6 +35,9 @@ Provides: cdi = %{version}-%{release}
3535
ExclusiveArch: x86_64 aarch64
3636
Patch0: CVE-2023-44487.patch
3737
Patch1: CVE-2024-3727.patch
38+
Patch2: CVE-2022-41717.patch
39+
Patch3: CVE-2022-32149.patch
40+
Patch4: CVE-2024-28180.patch
3841

3942
%description
4043
Containerized-Data-Importer (CDI) is a persistent storage management add-on for Kubernetes
@@ -202,6 +205,11 @@ install -m 0644 _out/manifests/release/cdi-cr.yaml %{buildroot}%{_datadir}/cdi/m
202205
%{_datadir}/cdi/manifests
203206

204207
%changelog
208+
* Wed Aug 06 2024 Brian Fjeldstad <bfjelds@microsoft.com> - 1.55.0-20
209+
- Address CVE-2022-41717
210+
- Address CVE-2022-32149
211+
- Address CVE-2024-28180
212+
205213
* Thu Jun 06 2024 Brian Fjeldstad <bfjelds@microsoft.com> - 1.55.0-19
206214
- Address CVE-2024-3727 by patching vendored github.com/containers/image
207215

0 commit comments

Comments
 (0)