diff options
Diffstat (limited to 'meta/recipes-devtools/go/go-1.14/CVE-2023-24536_1.patch')
-rw-r--r-- | meta/recipes-devtools/go/go-1.14/CVE-2023-24536_1.patch | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/meta/recipes-devtools/go/go-1.14/CVE-2023-24536_1.patch b/meta/recipes-devtools/go/go-1.14/CVE-2023-24536_1.patch new file mode 100644 index 0000000000..39e1304fbd --- /dev/null +++ b/meta/recipes-devtools/go/go-1.14/CVE-2023-24536_1.patch | |||
@@ -0,0 +1,134 @@ | |||
1 | From ef41a4e2face45e580c5836eaebd51629fc23f15 Mon Sep 17 00:00:00 2001 | ||
2 | From: Damien Neil <dneil@google.com> | ||
3 | Date: Thu, 16 Mar 2023 14:18:04 -0700 | ||
4 | Subject: [PATCH] [release-branch.go1.19] mime/multipart: avoid excessive copy | ||
5 | buffer allocations in ReadForm | ||
6 | |||
7 | When copying form data to disk with io.Copy, | ||
8 | allocate only one copy buffer and reuse it rather than | ||
9 | creating two buffers per file (one from io.multiReader.WriteTo, | ||
10 | and a second one from os.File.ReadFrom). | ||
11 | |||
12 | Thanks to Jakob Ackermann (@das7pad) for reporting this issue. | ||
13 | |||
14 | For CVE-2023-24536 | ||
15 | For #59153 | ||
16 | For #59269 | ||
17 | |||
18 | Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802453 | ||
19 | Run-TryBot: Damien Neil <dneil@google.com> | ||
20 | Reviewed-by: Julie Qiu <julieqiu@google.com> | ||
21 | Reviewed-by: Roland Shoemaker <bracewell@google.com> | ||
22 | Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1802395 | ||
23 | Run-TryBot: Roland Shoemaker <bracewell@google.com> | ||
24 | Reviewed-by: Damien Neil <dneil@google.com> | ||
25 | Change-Id: Ie405470c92abffed3356913b37d813e982c96c8b | ||
26 | Reviewed-on: https://go-review.googlesource.com/c/go/+/481983 | ||
27 | Run-TryBot: Michael Knyszek <mknyszek@google.com> | ||
28 | TryBot-Result: Gopher Robot <gobot@golang.org> | ||
29 | Auto-Submit: Michael Knyszek <mknyszek@google.com> | ||
30 | Reviewed-by: Matthew Dempsky <mdempsky@google.com> | ||
31 | |||
32 | Upstream-Status: Backport [https://github.com/golang/go/commit/ef41a4e2face45e580c5836eaebd51629fc23f15] | ||
33 | CVE: CVE-2023-24536 | ||
34 | Signed-off-by: Vijay Anusuri <vanusuri@mvista.com> | ||
35 | --- | ||
36 | src/mime/multipart/formdata.go | 15 +++++++-- | ||
37 | src/mime/multipart/formdata_test.go | 49 +++++++++++++++++++++++++++++ | ||
38 | 2 files changed, 61 insertions(+), 3 deletions(-) | ||
39 | |||
40 | diff --git a/src/mime/multipart/formdata.go b/src/mime/multipart/formdata.go | ||
41 | index a7d4ca97f0484..975dcb6b26db4 100644 | ||
42 | --- a/src/mime/multipart/formdata.go | ||
43 | +++ b/src/mime/multipart/formdata.go | ||
44 | @@ -84,6 +84,7 @@ func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) { | ||
45 | maxMemoryBytes = math.MaxInt64 | ||
46 | } | ||
47 | } | ||
48 | + var copyBuf []byte | ||
49 | for { | ||
50 | p, err := r.nextPart(false, maxMemoryBytes) | ||
51 | if err == io.EOF { | ||
52 | @@ -147,14 +148,22 @@ func (r *Reader) readForm(maxMemory int64) (_ *Form, err error) { | ||
53 | } | ||
54 | } | ||
55 | numDiskFiles++ | ||
56 | - size, err := io.Copy(file, io.MultiReader(&b, p)) | ||
57 | + if _, err := file.Write(b.Bytes()); err != nil { | ||
58 | + return nil, err | ||
59 | + } | ||
60 | + if copyBuf == nil { | ||
61 | + copyBuf = make([]byte, 32*1024) // same buffer size as io.Copy uses | ||
62 | + } | ||
63 | + // os.File.ReadFrom will allocate its own copy buffer if we let io.Copy use it. | ||
64 | + type writerOnly struct{ io.Writer } | ||
65 | + remainingSize, err := io.CopyBuffer(writerOnly{file}, p, copyBuf) | ||
66 | if err != nil { | ||
67 | return nil, err | ||
68 | } | ||
69 | fh.tmpfile = file.Name() | ||
70 | - fh.Size = size | ||
71 | + fh.Size = int64(b.Len()) + remainingSize | ||
72 | fh.tmpoff = fileOff | ||
73 | - fileOff += size | ||
74 | + fileOff += fh.Size | ||
75 | if !combineFiles { | ||
76 | if err := file.Close(); err != nil { | ||
77 | return nil, err | ||
78 | diff --git a/src/mime/multipart/formdata_test.go b/src/mime/multipart/formdata_test.go | ||
79 | index 5cded7170c6b8..f5b56083b2377 100644 | ||
80 | --- a/src/mime/multipart/formdata_test.go | ||
81 | +++ b/src/mime/multipart/formdata_test.go | ||
82 | @@ -368,3 +368,52 @@ func testReadFormManyFiles(t *testing.T, distinct bool) { | ||
83 | t.Fatalf("temp dir contains %v files; want 0", len(names)) | ||
84 | } | ||
85 | } | ||
86 | + | ||
87 | +func BenchmarkReadForm(b *testing.B) { | ||
88 | + for _, test := range []struct { | ||
89 | + name string | ||
90 | + form func(fw *Writer, count int) | ||
91 | + }{{ | ||
92 | + name: "fields", | ||
93 | + form: func(fw *Writer, count int) { | ||
94 | + for i := 0; i < count; i++ { | ||
95 | + w, _ := fw.CreateFormField(fmt.Sprintf("field%v", i)) | ||
96 | + fmt.Fprintf(w, "value %v", i) | ||
97 | + } | ||
98 | + }, | ||
99 | + }, { | ||
100 | + name: "files", | ||
101 | + form: func(fw *Writer, count int) { | ||
102 | + for i := 0; i < count; i++ { | ||
103 | + w, _ := fw.CreateFormFile(fmt.Sprintf("field%v", i), fmt.Sprintf("file%v", i)) | ||
104 | + fmt.Fprintf(w, "value %v", i) | ||
105 | + } | ||
106 | + }, | ||
107 | + }} { | ||
108 | + b.Run(test.name, func(b *testing.B) { | ||
109 | + for _, maxMemory := range []int64{ | ||
110 | + 0, | ||
111 | + 1 << 20, | ||
112 | + } { | ||
113 | + var buf bytes.Buffer | ||
114 | + fw := NewWriter(&buf) | ||
115 | + test.form(fw, 10) | ||
116 | + if err := fw.Close(); err != nil { | ||
117 | + b.Fatal(err) | ||
118 | + } | ||
119 | + b.Run(fmt.Sprintf("maxMemory=%v", maxMemory), func(b *testing.B) { | ||
120 | + b.ReportAllocs() | ||
121 | + for i := 0; i < b.N; i++ { | ||
122 | + fr := NewReader(bytes.NewReader(buf.Bytes()), fw.Boundary()) | ||
123 | + form, err := fr.ReadForm(maxMemory) | ||
124 | + if err != nil { | ||
125 | + b.Fatal(err) | ||
126 | + } | ||
127 | + form.RemoveAll() | ||
128 | + } | ||
129 | + | ||
130 | + }) | ||
131 | + } | ||
132 | + }) | ||
133 | + } | ||
134 | +} | ||