summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/go/go-1.14/CVE-2023-24536_2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/go/go-1.14/CVE-2023-24536_2.patch')
-rw-r--r--meta/recipes-devtools/go/go-1.14/CVE-2023-24536_2.patch184
1 files changed, 184 insertions, 0 deletions
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2023-24536_2.patch b/meta/recipes-devtools/go/go-1.14/CVE-2023-24536_2.patch
new file mode 100644
index 0000000000..9ba5114c82
--- /dev/null
+++ b/meta/recipes-devtools/go/go-1.14/CVE-2023-24536_2.patch
@@ -0,0 +1,184 @@
1From 7a359a651c7ebdb29e0a1c03102fce793e9f58f0 Mon Sep 17 00:00:00 2001
2From: Damien Neil <dneil@google.com>
3Date: Thu, 16 Mar 2023 16:56:12 -0700
4Subject: [PATCH] [release-branch.go1.19] net/textproto, mime/multipart:
5 improve accounting of non-file data
6
7For requests containing large numbers of small parts,
8memory consumption of a parsed form could be about 250%
9over the estimated size.
10
11When considering the size of parsed forms, account for the size of
12FileHeader structs and increase the estimate of memory consumed by
13map entries.
14
15Thanks to Jakob Ackermann (@das7pad) for reporting this issue.
16
17For CVE-2023-24536
18For #59153
19For #59269
20
21Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802454
22Run-TryBot: Damien Neil <dneil@google.com>
23Reviewed-by: Roland Shoemaker <bracewell@google.com>
24Reviewed-by: Julie Qiu <julieqiu@google.com>
25Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802396
26Run-TryBot: Roland Shoemaker <bracewell@google.com>
27Reviewed-by: Damien Neil <dneil@google.com>
28Change-Id: I31bc50e9346b4eee6fbe51a18c3c57230cc066db
29Reviewed-on: https://go-review.googlesource.com/c/go/+/481984
30Reviewed-by: Matthew Dempsky <mdempsky@google.com>
31Auto-Submit: Michael Knyszek <mknyszek@google.com>
32TryBot-Result: Gopher Robot <gobot@golang.org>
33Run-TryBot: Michael Knyszek <mknyszek@google.com>
34
35Upstream-Status: Backport [https://github.com/golang/go/commit/7a359a651c7ebdb29e0a1c03102fce793e9f58f0]
36CVE: CVE-2023-24536
37Signed-off-by: Vijay Anusuri <vanusuri@mvista.com>
38---
39 src/mime/multipart/formdata.go | 9 +++--
40 src/mime/multipart/formdata_test.go | 55 ++++++++++++-----------------
41 src/net/textproto/reader.go | 8 ++++-
42 3 files changed, 37 insertions(+), 35 deletions(-)
43
44diff --git a/src/mime/multipart/formdata.go b/src/mime/multipart/formdata.go
45index 975dcb6b26db4..3f6ff697ca608 100644
46--- a/src/mime/multipart/formdata.go
47+++ b/src/mime/multipart/formdata.go
48@@ -103,8 +103,9 @@ func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) {
49 // Multiple values for the same key (one map entry, longer slice) are cheaper
50 // than the same number of values for different keys (many map entries), but
51 // using a consistent per-value cost for overhead is simpler.
52+ const mapEntryOverhead = 200
53 maxMemoryBytes -= int64(len(name))
54- maxMemoryBytes -= 100 // map overhead
55+ maxMemoryBytes -= mapEntryOverhead
56 if maxMemoryBytes < 0 {
57 // We can't actually take this path, since nextPart would already have
58 // rejected the MIME headers for being too large. Check anyway.
59@@ -128,7 +129,10 @@ func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) {
60 }
61
62 // file, store in memory or on disk
63+ const fileHeaderSize = 100
64 maxMemoryBytes -= mimeHeaderSize(p.Header)
65+ maxMemoryBytes -= mapEntryOverhead
66+ maxMemoryBytes -= fileHeaderSize
67 if maxMemoryBytes < 0 {
68 return nil, ErrMessageTooLarge
69 }
70@@ -183,9 +187,10 @@ func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) {
71 }
72
73 func mimeHeaderSize(h textproto.MIMEHeader) (size int64) {
74+ size = 400
75 for k, vs := range h {
76 size += int64(len(k))
77- size += 100 // map entry overhead
78+ size += 200 // map entry overhead
79 for _, v := range vs {
80 size += int64(len(v))
81 }
82diff --git a/src/mime/multipart/formdata_test.go b/src/mime/multipart/formdata_test.go
83index f5b56083b2377..8ed26e0c34081 100644
84--- a/src/mime/multipart/formdata_test.go
85+++ b/src/mime/multipart/formdata_test.go
86@@ -192,10 +192,10 @@ func (r *failOnReadAfterErrorReader) Read(p []byte) (n int, err error) {
87 // TestReadForm_NonFileMaxMemory asserts that the ReadForm maxMemory limit is applied
88 // while processing non-file form data as well as file form data.
89 func TestReadForm_NonFileMaxMemory(t *testing.T) {
90- n := 10<<20 + 25
91 if testing.Short() {
92- n = 10<<10 + 25
93+ t.Skip("skipping in -short mode")
94 }
95+ n := 10 << 20
96 largeTextValue := strings.Repeat("1", n)
97 message := `--MyBoundary
98 Content-Disposition: form-data; name="largetext"
99@@ -203,38 +203,29 @@ Content-Disposition: form-data; name="largetext"
100 ` + largeTextValue + `
101 --MyBoundary--
102 `
103-
104 testBody := strings.ReplaceAll(message, "\n", "\r\n")
105- testCases := []struct {
106- name string
107- maxMemory int64
108- err error
109- }{
110- {"smaller", 50 + int64(len("largetext")) + 100, nil},
111- {"exact-fit", 25 + int64(len("largetext")) + 100, nil},
112- {"too-large", 0, ErrMessageTooLarge},
113- }
114- for _, tc := range testCases {
115- t.Run(tc.name, func(t *testing.T) {
116- if tc.maxMemory == 0 && testing.Short() {
117- t.Skip("skipping in -short mode")
118- }
119- b := strings.NewReader(testBody)
120- r := NewReader(b, boundary)
121- f, err := r.ReadForm(tc.maxMemory)
122- if err == nil {
123- defer f.RemoveAll()
124- }
125- if tc.err != err {
126- t.Fatalf("ReadForm error - got: %v; expected: %v", err, tc.err)
127- }
128- if err == nil {
129- if g := f.Value["largetext"][0]; g != largeTextValue {
130- t.Errorf("largetext mismatch: got size: %v, expected size: %v", len(g), len(largeTextValue))
131- }
132- }
133- })
134+ // Try parsing the form with increasing maxMemory values.
135+ // Changes in how we account for non-file form data may cause the exact point
136+ // where we change from rejecting the form as too large to accepting it to vary,
137+ // but we should see both successes and failures.
138+ const failWhenMaxMemoryLessThan = 128
139+ for maxMemory := int64(0); maxMemory < failWhenMaxMemoryLessThan*2; maxMemory += 16 {
140+ b := strings.NewReader(testBody)
141+ r := NewReader(b, boundary)
142+ f, err := r.ReadForm(maxMemory)
143+ if err != nil {
144+ continue
145+ }
146+ if g := f.Value["largetext"][0]; g != largeTextValue {
147+ t.Errorf("largetext mismatch: got size: %v, expected size: %v", len(g), len(largeTextValue))
148+ }
149+ f.RemoveAll()
150+ if maxMemory < failWhenMaxMemoryLessThan {
151+ t.Errorf("ReadForm(%v): no error, expect to hit memory limit when maxMemory < %v", maxMemory, failWhenMaxMemoryLessThan)
152+ }
153+ return
154 }
155+ t.Errorf("ReadForm(x) failed for x < 1024, expect success")
156 }
157
158 // TestReadForm_MetadataTooLarge verifies that we account for the size of field names,
159diff --git a/src/net/textproto/reader.go b/src/net/textproto/reader.go
160index 9a21777df8be0..c1284fde25eb7 100644
161--- a/src/net/textproto/reader.go
162+++ b/src/net/textproto/reader.go
163@@ -503,6 +503,12 @@ func readMIMEHeader(r *Reader, lim int64) (MIMEHeader, error) {
164
165 m := make(MIMEHeader, hint)
166
167+ // Account for 400 bytes of overhead for the MIMEHeader, plus 200 bytes per entry.
168+ // Benchmarking map creation as of go1.20, a one-entry MIMEHeader is 416 bytes and large
169+ // MIMEHeaders average about 200 bytes per entry.
170+ lim -= 400
171+ const mapEntryOverhead = 200
172+
173 // The first line cannot start with a leading space.
174 if buf, err := r.R.Peek(1); err == nil && (buf[0] == ' ' || buf[0] == '\t') {
175 line, err := r.readLineSlice()
176@@ -538,7 +544,7 @@ func readMIMEHeader(r *Reader, lim int64) (MIMEHeader, error) {
177 vv := m[key]
178 if vv == nil {
179 lim -= int64(len(key))
180- lim -= 100 // map entry overhead
181+ lim -= mapEntryOverhead
182 }
183 lim -= int64(len(value))
184 if lim < 0 {