Skip to content

Commit 42df5d1

Browse files
CBL-Mariner-BotCamelronrikenm1
authored
[AUTO-CHERRYPICK] Patch moby-buildx CVES CVE-2021-43565 CVE-2022-28948 CVE-2022-41723 - branch main (#9891)
Co-authored-by: Cameron E Baird <cameronbaird@microsoft.com> Co-authored-by: Riken Maharjan <106988478+rikenm1@users.noreply.github.com>
1 parent f9abe25 commit 42df5d1

4 files changed

Lines changed: 246 additions & 2 deletions

File tree

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
From 49e152b4523c7e9ebdf0c0720c79cca78078a8c4 Mon Sep 17 00:00:00 2001
2+
From: Cameron Baird <cameronbaird@microsoft.com>
3+
Date: Fri, 12 Jul 2024 20:23:19 +0000
4+
Subject: [PATCH 1/3] CVE-2021-43565
5+
6+
Upstream fix: 5770296d904e90f15f38f77dfc2e43fdf5efc083
7+
ssh: don't assume packet plaintext size
8+
When reading GCM and ChaChaPoly1305 packets, don't make assumptions
9+
about the size of the enciphered plaintext. This fixes two panics
10+
caused by standards non-compliant malformed packets.
11+
---
12+
vendor/golang.org/x/crypto/ssh/cipher.go | 8 ++++++++
13+
1 file changed, 8 insertions(+)
14+
15+
diff --git a/vendor/golang.org/x/crypto/ssh/cipher.go b/vendor/golang.org/x/crypto/ssh/cipher.go
16+
index 8bd6b3d..ccd82bc 100644
17+
--- a/vendor/golang.org/x/crypto/ssh/cipher.go
18+
+++ b/vendor/golang.org/x/crypto/ssh/cipher.go
19+
@@ -394,6 +394,10 @@ func (c *gcmCipher) readCipherPacket(seqNum uint32, r io.Reader) ([]byte, error)
20+
}
21+
c.incIV()
22+
23+
+ if len(plain) == 0 {
24+
+ return nil, errors.New("ssh: empty packet")
25+
+ }
26+
+
27+
padding := plain[0]
28+
if padding < 4 {
29+
// padding is a byte, so it automatically satisfies
30+
@@ -710,6 +714,10 @@ func (c *chacha20Poly1305Cipher) readCipherPacket(seqNum uint32, r io.Reader) ([
31+
plain := c.buf[4:contentEnd]
32+
s.XORKeyStream(plain, plain)
33+
34+
+ if len(plain) == 0 {
35+
+ return nil, errors.New("ssh: empty packet")
36+
+ }
37+
+
38+
padding := plain[0]
39+
if padding < 4 {
40+
// padding is a byte, so it automatically satisfies
41+
--
42+
2.34.1
43+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
From 6d8040e5ae88d74d619980a0115a4eb91e47c405 Mon Sep 17 00:00:00 2001
2+
From: Cameron Baird <cameronbaird@microsoft.com>
3+
Date: Fri, 12 Jul 2024 20:37:35 +0000
4+
Subject: [PATCH 2/3] CVE-2022-28948
5+
6+
Upstream fix: 8f96da9f5d5eff988554c1aae1784627c4bf6754
7+
8+
Explicitly check the parser for errors on peek
9+
It's curious choice from the underlying API to generally return a
10+
positive result on success, but on this case return true in an error
11+
scenario.
12+
---
13+
vendor/gopkg.in/yaml.v2/decode.go | 5 ++++-
14+
vendor/gopkg.in/yaml.v3/decode.go | 5 ++++-
15+
2 files changed, 8 insertions(+), 2 deletions(-)
16+
17+
diff --git a/vendor/gopkg.in/yaml.v2/decode.go b/vendor/gopkg.in/yaml.v2/decode.go
18+
index 129bc2a..7473d4b 100644
19+
--- a/vendor/gopkg.in/yaml.v2/decode.go
20+
+++ b/vendor/gopkg.in/yaml.v2/decode.go
21+
@@ -102,7 +102,10 @@ func (p *parser) peek() yaml_event_type_t {
22+
if p.event.typ != yaml_NO_EVENT {
23+
return p.event.typ
24+
}
25+
- if !yaml_parser_parse(&p.parser, &p.event) {
26+
+ // It's curious choice from the underlying API to generally return a
27+
+ // positive result on success, but on this case return true in an error
28+
+ // scenario. This was the source of bugs in the past (issue #666).
29+
+ if !yaml_parser_parse(&p.parser, &p.event) || p.parser.error != yaml_NO_ERROR {
30+
p.fail()
31+
}
32+
return p.event.typ
33+
diff --git a/vendor/gopkg.in/yaml.v3/decode.go b/vendor/gopkg.in/yaml.v3/decode.go
34+
index df36e3a..f316f51 100644
35+
--- a/vendor/gopkg.in/yaml.v3/decode.go
36+
+++ b/vendor/gopkg.in/yaml.v3/decode.go
37+
@@ -100,7 +100,10 @@ func (p *parser) peek() yaml_event_type_t {
38+
if p.event.typ != yaml_NO_EVENT {
39+
return p.event.typ
40+
}
41+
- if !yaml_parser_parse(&p.parser, &p.event) {
42+
+ // It's curious choice from the underlying API to generally return a
43+
+ // positive result on success, but on this case return true in an error
44+
+ // scenario. This was the source of bugs in the past (issue #666).
45+
+ if !yaml_parser_parse(&p.parser, &p.event) || p.parser.error != yaml_NO_ERROR {
46+
p.fail()
47+
}
48+
return p.event.typ
49+
--
50+
2.34.1
51+
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
From 04646b47d5f03ab96a681931a1b93cd12209e6bf Mon Sep 17 00:00:00 2001
2+
From: Cameron Baird <cameronbaird@microsoft.com>
3+
Date: Fri, 12 Jul 2024 20:49:14 +0000
4+
Subject: [PATCH 3/3] CVE-2022-41723
5+
6+
Upstream fix: I58a743df450a4a4923dddd5cf6bb0592b0a7bdf3
7+
http2/hpack: avoid quadratic complexity in hpack decoding
8+
9+
When parsing a field literal containing two Huffman-encoded strings,
10+
don't decode the first string until verifying all data is present.
11+
Avoids forced quadratic complexity when repeatedly parsing a partial
12+
field, repeating the Huffman decoding of the string on each iteration.
13+
---
14+
vendor/golang.org/x/net/http2/hpack/hpack.go | 79 ++++++++++++--------
15+
1 file changed, 49 insertions(+), 30 deletions(-)
16+
17+
diff --git a/vendor/golang.org/x/net/http2/hpack/hpack.go b/vendor/golang.org/x/net/http2/hpack/hpack.go
18+
index 85f18a2..02e80e3 100644
19+
--- a/vendor/golang.org/x/net/http2/hpack/hpack.go
20+
+++ b/vendor/golang.org/x/net/http2/hpack/hpack.go
21+
@@ -359,6 +359,7 @@ func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
22+
23+
var hf HeaderField
24+
wantStr := d.emitEnabled || it.indexed()
25+
+ var undecodedName undecodedString
26+
if nameIdx > 0 {
27+
ihf, ok := d.at(nameIdx)
28+
if !ok {
29+
@@ -366,15 +367,27 @@ func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error {
30+
}
31+
hf.Name = ihf.Name
32+
} else {
33+
- hf.Name, buf, err = d.readString(buf, wantStr)
34+
+ undecodedName, buf, err = d.readString(buf)
35+
if err != nil {
36+
return err
37+
}
38+
}
39+
- hf.Value, buf, err = d.readString(buf, wantStr)
40+
+ undecodedValue, buf, err := d.readString(buf)
41+
if err != nil {
42+
return err
43+
}
44+
+ if wantStr {
45+
+ if nameIdx <= 0 {
46+
+ hf.Name, err = d.decodeString(undecodedName)
47+
+ if err != nil {
48+
+ return err
49+
+ }
50+
+ }
51+
+ hf.Value, err = d.decodeString(undecodedValue)
52+
+ if err != nil {
53+
+ return err
54+
+ }
55+
+ }
56+
d.buf = buf
57+
if it.indexed() {
58+
d.dynTab.add(hf)
59+
@@ -459,46 +472,52 @@ func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) {
60+
return 0, origP, errNeedMore
61+
}
62+
63+
-// readString decodes an hpack string from p.
64+
+// readString reads an hpack string from p.
65+
//
66+
-// wantStr is whether s will be used. If false, decompression and
67+
-// []byte->string garbage are skipped if s will be ignored
68+
-// anyway. This does mean that huffman decoding errors for non-indexed
69+
-// strings past the MAX_HEADER_LIST_SIZE are ignored, but the server
70+
-// is returning an error anyway, and because they're not indexed, the error
71+
-// won't affect the decoding state.
72+
-func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain []byte, err error) {
73+
+// It returns a reference to the encoded string data to permit deferring decode costs
74+
+// until after the caller verifies all data is present.
75+
+func (d *Decoder) readString(p []byte) (u undecodedString, remain []byte, err error) {
76+
if len(p) == 0 {
77+
- return "", p, errNeedMore
78+
+ return u, p, errNeedMore
79+
}
80+
isHuff := p[0]&128 != 0
81+
strLen, p, err := readVarInt(7, p)
82+
if err != nil {
83+
- return "", p, err
84+
+ return u, p, err
85+
}
86+
if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) {
87+
- return "", nil, ErrStringLength
88+
+ // Returning an error here means Huffman decoding errors
89+
+ // for non-indexed strings past the maximum string length
90+
+ // are ignored, but the server is returning an error anyway
91+
+ // and because the string is not indexed the error will not
92+
+ // affect the decoding state.
93+
+ return u, nil, ErrStringLength
94+
}
95+
if uint64(len(p)) < strLen {
96+
- return "", p, errNeedMore
97+
- }
98+
- if !isHuff {
99+
- if wantStr {
100+
- s = string(p[:strLen])
101+
- }
102+
- return s, p[strLen:], nil
103+
+ return u, p, errNeedMore
104+
}
105+
+ u.isHuff = isHuff
106+
+ u.b = p[:strLen]
107+
+ return u, p[strLen:], nil
108+
+}
109+
110+
- if wantStr {
111+
- buf := bufPool.Get().(*bytes.Buffer)
112+
- buf.Reset() // don't trust others
113+
- defer bufPool.Put(buf)
114+
- if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != nil {
115+
- buf.Reset()
116+
- return "", nil, err
117+
- }
118+
+type undecodedString struct {
119+
+ isHuff bool
120+
+ b []byte
121+
+}
122+
+
123+
+func (d *Decoder) decodeString(u undecodedString) (string, error) {
124+
+ if !u.isHuff {
125+
+ return string(u.b), nil
126+
+ }
127+
+ buf := bufPool.Get().(*bytes.Buffer)
128+
+ buf.Reset() // don't trust others
129+
+ var s string
130+
+ err := huffmanDecode(buf, d.maxStrLen, u.b)
131+
+ if err == nil {
132+
s = buf.String()
133+
- buf.Reset() // be nice to GC
134+
}
135+
- return s, p[strLen:], nil
136+
+ buf.Reset() // be nice to GC
137+
+ bufPool.Put(buf)
138+
+ return s, err
139+
}
140+
--
141+
2.34.1
142+

SPECS/moby-buildx/moby-buildx.spec

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Summary: A Docker CLI plugin for extended build capabilities with BuildKi
55
Name: moby-%{upstream_name}
66
# update "commit_hash" above when upgrading version
77
Version: 0.7.1
8-
Release: 20%{?dist}
8+
Release: 21%{?dist}
99
License: ASL 2.0
1010
Group: Tools/Container
1111
Vendor: Microsoft Corporation
@@ -16,6 +16,9 @@ Source0: https://github.com/docker/buildx/archive/refs/tags/v%{version}.t
1616
Patch0: CVE-2022-21698.patch
1717
Patch1: CVE-2023-44487.patch
1818
Patch2: CVE-2021-44716.patch
19+
Patch3: CVE-2021-43565.patch
20+
Patch4: CVE-2022-28948.patch
21+
Patch5: CVE-2022-41723.patch
1922

2023
BuildRequires: bash
2124
BuildRequires: golang
@@ -46,9 +49,14 @@ cp -aT buildx "%{buildroot}/%{_libexecdir}/docker/cli-plugins/docker-buildx"
4649
%{_libexecdir}/docker/cli-plugins/docker-buildx
4750

4851
%changelog
49-
* Wed Jul 17 2024 Muhammad Falak R Wani <mwani@microsoft.com> - 0.7.1-20
52+
* Wed Jul 17 2024 Muhammad Falak R Wani <mwani@microsoft.com> - 0.7.1-21
5053
- Drop requirement on a specific version of golang
5154

55+
* Mon Jul 15 2024 Cameron Baird <cameronbaird@microsoft.com> - 0.7.1-20
56+
- Address CVE-2021-43565 by patching vendored golang.org/x/crypto/ssh
57+
- Address CVE-2022-28948 by patching vendored gopkg.in/yaml
58+
- Address CVE-2022-41723 by patching vendored golang.org/x/net/http2
59+
5260
* Thu Jun 06 2024 CBL-Mariner Servicing Account <cblmargh@microsoft.com> - 0.7.1-19
5361
- Bump release to rebuild with go 1.21.11
5462

0 commit comments

Comments
 (0)