diff options
author | Sakib Sajal <sakib.sajal@windriver.com> | 2023-08-01 17:18:12 -0700 |
---|---|---|
committer | Steve Sakoman <steve@sakoman.com> | 2023-08-07 04:40:44 -1000 |
commit | 1aae734721c24ce8df40e7e76af409ab507f72dc (patch) | |
tree | 06c951219642e2c8edefb4a3675905d43c7dc8af | |
parent | 1ba43f2c8858ffb0a05644b455daf5ea75aa2fe5 (diff) | |
download | poky-1aae734721c24ce8df40e7e76af409ab507f72dc.tar.gz |
go: fix CVE-2023-24531
Backport required patches from go1.21 to fix CVE-2023-24531.
(From OE-Core rev: 6d892c52bd5806507a05e8b6f749c54bbd9e9da6)
Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r-- | meta/recipes-devtools/go/go-1.17.13.inc | 4 | ||||
-rw-r--r-- | meta/recipes-devtools/go/go-1.21/CVE-2023-24531_1.patch | 252 | ||||
-rw-r--r-- | meta/recipes-devtools/go/go-1.21/CVE-2023-24531_2.patch | 47 |
3 files changed, 302 insertions, 1 deletions
diff --git a/meta/recipes-devtools/go/go-1.17.13.inc b/meta/recipes-devtools/go/go-1.17.13.inc index 53e09a545c..e0f02f3e28 100644 --- a/meta/recipes-devtools/go/go-1.17.13.inc +++ b/meta/recipes-devtools/go/go-1.17.13.inc | |||
@@ -1,6 +1,6 @@ | |||
1 | require go-common.inc | 1 | require go-common.inc |
2 | 2 | ||
3 | FILESEXTRAPATHS:prepend := "${FILE_DIRNAME}/go-1.19:${FILE_DIRNAME}/go-1.18:" | 3 | FILESEXTRAPATHS:prepend := "${FILE_DIRNAME}/go-1.21:${FILE_DIRNAME}/go-1.19:${FILE_DIRNAME}/go-1.18:" |
4 | 4 | ||
5 | LIC_FILES_CHKSUM = "file://LICENSE;md5=5d4950ecb7b26d2c5e4e7b4e0dd74707" | 5 | LIC_FILES_CHKSUM = "file://LICENSE;md5=5d4950ecb7b26d2c5e4e7b4e0dd74707" |
6 | 6 | ||
@@ -40,6 +40,8 @@ SRC_URI += "\ | |||
40 | file://CVE-2023-24536_1.patch \ | 40 | file://CVE-2023-24536_1.patch \ |
41 | file://CVE-2023-24536_2.patch \ | 41 | file://CVE-2023-24536_2.patch \ |
42 | file://CVE-2023-24536_3.patch \ | 42 | file://CVE-2023-24536_3.patch \ |
43 | file://CVE-2023-24531_1.patch \ | ||
44 | file://CVE-2023-24531_2.patch \ | ||
43 | " | 45 | " |
44 | SRC_URI[main.sha256sum] = "a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784ada0cd300fd" | 46 | SRC_URI[main.sha256sum] = "a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784ada0cd300fd" |
45 | 47 | ||
diff --git a/meta/recipes-devtools/go/go-1.21/CVE-2023-24531_1.patch b/meta/recipes-devtools/go/go-1.21/CVE-2023-24531_1.patch new file mode 100644 index 0000000000..5f6d7e16a8 --- /dev/null +++ b/meta/recipes-devtools/go/go-1.21/CVE-2023-24531_1.patch | |||
@@ -0,0 +1,252 @@ | |||
1 | From 0f717b5f7d32bb660c01ec0366bd53c9b4c5ab5d Mon Sep 17 00:00:00 2001 | ||
2 | From: Michael Matloob <matloob@golang.org> | ||
3 | Date: Mon, 24 Apr 2023 16:57:28 -0400 | ||
4 | Subject: [PATCH 1/2] cmd/go: sanitize go env outputs | ||
5 | |||
6 | go env, without any arguments, outputs the environment variables in | ||
7 | the form of a script that can be run on the host OS. On Unix, single | ||
8 | quote the strings and place single quotes themselves outside the | ||
9 | single quoted strings. On windows use the set "var=val" syntax with | ||
10 | the quote starting before the variable. | ||
11 | |||
12 | Fixes #58508 | ||
13 | |||
14 | Change-Id: Iecd379a4af7285ea9b2024f0202250c74fd9a2bd | ||
15 | Reviewed-on: https://go-review.googlesource.com/c/go/+/488375 | ||
16 | TryBot-Result: Gopher Robot <gobot@golang.org> | ||
17 | Reviewed-by: Michael Matloob <matloob@golang.org> | ||
18 | Reviewed-by: Damien Neil <dneil@google.com> | ||
19 | Run-TryBot: Michael Matloob <matloob@golang.org> | ||
20 | Reviewed-by: Bryan Mills <bcmills@google.com> | ||
21 | Reviewed-by: Quim Muntal <quimmuntal@gmail.com> | ||
22 | |||
23 | CVE: CVE-2023-24531 | ||
24 | Upstream-Status: Backport [f379e78951a405e7e99a60fb231eeedbf976c108] | ||
25 | |||
26 | Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com> | ||
27 | --- | ||
28 | src/cmd/go/internal/envcmd/env.go | 60 ++++++++++++- | ||
29 | src/cmd/go/internal/envcmd/env_test.go | 94 +++++++++++++++++++++ | ||
30 | src/cmd/go/testdata/script/env_sanitize.txt | 5 ++ | ||
31 | 3 files changed, 157 insertions(+), 2 deletions(-) | ||
32 | create mode 100644 src/cmd/go/internal/envcmd/env_test.go | ||
33 | create mode 100644 src/cmd/go/testdata/script/env_sanitize.txt | ||
34 | |||
35 | diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go | ||
36 | index 43b94e7..0ce8843 100644 | ||
37 | --- a/src/cmd/go/internal/envcmd/env.go | ||
38 | +++ b/src/cmd/go/internal/envcmd/env.go | ||
39 | @@ -6,6 +6,7 @@ | ||
40 | package envcmd | ||
41 | |||
42 | import ( | ||
43 | + "bytes" | ||
44 | "context" | ||
45 | "encoding/json" | ||
46 | "fmt" | ||
47 | @@ -17,6 +18,7 @@ import ( | ||
48 | "runtime" | ||
49 | "sort" | ||
50 | "strings" | ||
51 | + "unicode" | ||
52 | "unicode/utf8" | ||
53 | |||
54 | "cmd/go/internal/base" | ||
55 | @@ -379,9 +381,12 @@ func checkBuildConfig(add map[string]string, del map[string]bool) error { | ||
56 | func PrintEnv(w io.Writer, env []cfg.EnvVar) { | ||
57 | for _, e := range env { | ||
58 | if e.Name != "TERM" { | ||
59 | + if runtime.GOOS != "plan9" && bytes.Contains([]byte(e.Value), []byte{0}) { | ||
60 | + base.Fatalf("go: internal error: encountered null byte in environment variable %s on non-plan9 platform", e.Name) | ||
61 | + } | ||
62 | switch runtime.GOOS { | ||
63 | default: | ||
64 | - fmt.Fprintf(w, "%s=\"%s\"\n", e.Name, e.Value) | ||
65 | + fmt.Fprintf(w, "%s=%s\n", e.Name, shellQuote(e.Value)) | ||
66 | case "plan9": | ||
67 | if strings.IndexByte(e.Value, '\x00') < 0 { | ||
68 | fmt.Fprintf(w, "%s='%s'\n", e.Name, strings.ReplaceAll(e.Value, "'", "''")) | ||
69 | @@ -392,17 +397,68 @@ func PrintEnv(w io.Writer, env []cfg.EnvVar) { | ||
70 | if x > 0 { | ||
71 | fmt.Fprintf(w, " ") | ||
72 | } | ||
73 | + // TODO(#59979): Does this need to be quoted like above? | ||
74 | fmt.Fprintf(w, "%s", s) | ||
75 | } | ||
76 | fmt.Fprintf(w, ")\n") | ||
77 | } | ||
78 | case "windows": | ||
79 | - fmt.Fprintf(w, "set %s=%s\n", e.Name, e.Value) | ||
80 | + if hasNonGraphic(e.Value) { | ||
81 | + base.Errorf("go: stripping unprintable or unescapable characters from %%%q%%", e.Name) | ||
82 | + } | ||
83 | + fmt.Fprintf(w, "set %s=%s\n", e.Name, batchEscape(e.Value)) | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | } | ||
88 | |||
89 | +func hasNonGraphic(s string) bool { | ||
90 | + for _, c := range []byte(s) { | ||
91 | + if c == '\r' || c == '\n' || (!unicode.IsGraphic(rune(c)) && !unicode.IsSpace(rune(c))) { | ||
92 | + return true | ||
93 | + } | ||
94 | + } | ||
95 | + return false | ||
96 | +} | ||
97 | + | ||
98 | +func shellQuote(s string) string { | ||
99 | + var b bytes.Buffer | ||
100 | + b.WriteByte('\'') | ||
101 | + for _, x := range []byte(s) { | ||
102 | + if x == '\'' { | ||
103 | + // Close the single quoted string, add an escaped single quote, | ||
104 | + // and start another single quoted string. | ||
105 | + b.WriteString(`'\''`) | ||
106 | + } else { | ||
107 | + b.WriteByte(x) | ||
108 | + } | ||
109 | + } | ||
110 | + b.WriteByte('\'') | ||
111 | + return b.String() | ||
112 | +} | ||
113 | + | ||
114 | +func batchEscape(s string) string { | ||
115 | + var b bytes.Buffer | ||
116 | + for _, x := range []byte(s) { | ||
117 | + if x == '\r' || x == '\n' || (!unicode.IsGraphic(rune(x)) && !unicode.IsSpace(rune(x))) { | ||
118 | + b.WriteRune(unicode.ReplacementChar) | ||
119 | + continue | ||
120 | + } | ||
121 | + switch x { | ||
122 | + case '%': | ||
123 | + b.WriteString("%%") | ||
124 | + case '<', '>', '|', '&', '^': | ||
125 | + // These are special characters that need to be escaped with ^. See | ||
126 | + // https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/set_1. | ||
127 | + b.WriteByte('^') | ||
128 | + b.WriteByte(x) | ||
129 | + default: | ||
130 | + b.WriteByte(x) | ||
131 | + } | ||
132 | + } | ||
133 | + return b.String() | ||
134 | +} | ||
135 | + | ||
136 | func printEnvAsJSON(env []cfg.EnvVar) { | ||
137 | m := make(map[string]string) | ||
138 | for _, e := range env { | ||
139 | diff --git a/src/cmd/go/internal/envcmd/env_test.go b/src/cmd/go/internal/envcmd/env_test.go | ||
140 | new file mode 100644 | ||
141 | index 0000000..32d99fd | ||
142 | --- /dev/null | ||
143 | +++ b/src/cmd/go/internal/envcmd/env_test.go | ||
144 | @@ -0,0 +1,94 @@ | ||
145 | +// Copyright 2022 The Go Authors. All rights reserved. | ||
146 | +// Use of this source code is governed by a BSD-style | ||
147 | +// license that can be found in the LICENSE file. | ||
148 | + | ||
149 | +//go:build unix || windows | ||
150 | + | ||
151 | +package envcmd | ||
152 | + | ||
153 | +import ( | ||
154 | + "bytes" | ||
155 | + "cmd/go/internal/cfg" | ||
156 | + "fmt" | ||
157 | + "internal/testenv" | ||
158 | + "os" | ||
159 | + "os/exec" | ||
160 | + "path/filepath" | ||
161 | + "runtime" | ||
162 | + "testing" | ||
163 | + "unicode" | ||
164 | +) | ||
165 | + | ||
166 | +func FuzzPrintEnvEscape(f *testing.F) { | ||
167 | + f.Add(`$(echo 'cc"'; echo 'OOPS="oops')`) | ||
168 | + f.Add("$(echo shell expansion 1>&2)") | ||
169 | + f.Add("''") | ||
170 | + f.Add(`C:\"Program Files"\`) | ||
171 | + f.Add(`\\"Quoted Host"\\share`) | ||
172 | + f.Add("\xfb") | ||
173 | + f.Add("0") | ||
174 | + f.Add("") | ||
175 | + f.Add("''''''''") | ||
176 | + f.Add("\r") | ||
177 | + f.Add("\n") | ||
178 | + f.Add("E,%") | ||
179 | + f.Fuzz(func(t *testing.T, s string) { | ||
180 | + t.Parallel() | ||
181 | + | ||
182 | + for _, c := range []byte(s) { | ||
183 | + if c == 0 { | ||
184 | + t.Skipf("skipping %q: contains a null byte. Null bytes can't occur in the environment"+ | ||
185 | + " outside of Plan 9, which has different code path than Windows and Unix that this test"+ | ||
186 | + " isn't testing.", s) | ||
187 | + } | ||
188 | + if c > unicode.MaxASCII { | ||
189 | + t.Skipf("skipping %#q: contains a non-ASCII character %q", s, c) | ||
190 | + } | ||
191 | + if !unicode.IsGraphic(rune(c)) && !unicode.IsSpace(rune(c)) { | ||
192 | + t.Skipf("skipping %#q: contains non-graphic character %q", s, c) | ||
193 | + } | ||
194 | + if runtime.GOOS == "windows" && c == '\r' || c == '\n' { | ||
195 | + t.Skipf("skipping %#q on Windows: contains unescapable character %q", s, c) | ||
196 | + } | ||
197 | + } | ||
198 | + | ||
199 | + var b bytes.Buffer | ||
200 | + if runtime.GOOS == "windows" { | ||
201 | + b.WriteString("@echo off\n") | ||
202 | + } | ||
203 | + PrintEnv(&b, []cfg.EnvVar{{Name: "var", Value: s}}) | ||
204 | + var want string | ||
205 | + if runtime.GOOS == "windows" { | ||
206 | + fmt.Fprintf(&b, "echo \"%%var%%\"\n") | ||
207 | + want += "\"" + s + "\"\r\n" | ||
208 | + } else { | ||
209 | + fmt.Fprintf(&b, "printf '%%s\\n' \"$var\"\n") | ||
210 | + want += s + "\n" | ||
211 | + } | ||
212 | + scriptfilename := "script.sh" | ||
213 | + if runtime.GOOS == "windows" { | ||
214 | + scriptfilename = "script.bat" | ||
215 | + } | ||
216 | + scriptfile := filepath.Join(t.TempDir(), scriptfilename) | ||
217 | + if err := os.WriteFile(scriptfile, b.Bytes(), 0777); err != nil { | ||
218 | + t.Fatal(err) | ||
219 | + } | ||
220 | + t.Log(b.String()) | ||
221 | + var cmd *exec.Cmd | ||
222 | + if runtime.GOOS == "windows" { | ||
223 | + cmd = testenv.Command(t, "cmd.exe", "/C", scriptfile) | ||
224 | + } else { | ||
225 | + cmd = testenv.Command(t, "sh", "-c", scriptfile) | ||
226 | + } | ||
227 | + out, err := cmd.Output() | ||
228 | + t.Log(string(out)) | ||
229 | + if err != nil { | ||
230 | + t.Fatal(err) | ||
231 | + } | ||
232 | + | ||
233 | + if string(out) != want { | ||
234 | + t.Fatalf("output of running PrintEnv script and echoing variable: got: %q, want: %q", | ||
235 | + string(out), want) | ||
236 | + } | ||
237 | + }) | ||
238 | +} | ||
239 | diff --git a/src/cmd/go/testdata/script/env_sanitize.txt b/src/cmd/go/testdata/script/env_sanitize.txt | ||
240 | new file mode 100644 | ||
241 | index 0000000..cc4d23a | ||
242 | --- /dev/null | ||
243 | +++ b/src/cmd/go/testdata/script/env_sanitize.txt | ||
244 | @@ -0,0 +1,5 @@ | ||
245 | +env GOFLAGS='$(echo ''cc"''; echo ''OOPS="oops'')' | ||
246 | +go env | ||
247 | +[GOOS:darwin] stdout 'GOFLAGS=''\$\(echo ''\\''''cc"''\\''''; echo ''\\''''OOPS="oops''\\''''\)''' | ||
248 | +[GOOS:linux] stdout 'GOFLAGS=''\$\(echo ''\\''''cc"''\\''''; echo ''\\''''OOPS="oops''\\''''\)''' | ||
249 | +[GOOS:windows] stdout 'set GOFLAGS=\$\(echo ''cc"''; echo ''OOPS="oops''\)' | ||
250 | -- | ||
251 | 2.35.5 | ||
252 | |||
diff --git a/meta/recipes-devtools/go/go-1.21/CVE-2023-24531_2.patch b/meta/recipes-devtools/go/go-1.21/CVE-2023-24531_2.patch new file mode 100644 index 0000000000..eecc04c2e3 --- /dev/null +++ b/meta/recipes-devtools/go/go-1.21/CVE-2023-24531_2.patch | |||
@@ -0,0 +1,47 @@ | |||
1 | From b2624f973692ca093348395c2418d1c422f2a162 Mon Sep 17 00:00:00 2001 | ||
2 | From: miller <millerresearch@gmail.com> | ||
3 | Date: Mon, 8 May 2023 16:56:21 +0100 | ||
4 | Subject: [PATCH 2/2] cmd/go: quote entries in list-valued variables for go env | ||
5 | in plan9 | ||
6 | |||
7 | When 'go env' without an argument prints environment variables as | ||
8 | a script which can be executed by the shell, variables with a | ||
9 | list value in Plan 9 (such as GOPATH) need to be printed with each | ||
10 | element enclosed in single quotes in case it contains characters | ||
11 | significant to the Plan 9 shell (such as ' ' or '='). | ||
12 | |||
13 | For #58508 | ||
14 | |||
15 | Change-Id: Ia30f51307cc6d07a7e3ada6bf9d60bf9951982ff | ||
16 | Reviewed-on: https://go-review.googlesource.com/c/go/+/493535 | ||
17 | Run-TryBot: Cherry Mui <cherryyz@google.com> | ||
18 | Reviewed-by: Cherry Mui <cherryyz@google.com> | ||
19 | Reviewed-by: Russ Cox <rsc@golang.org> | ||
20 | TryBot-Result: Gopher Robot <gobot@golang.org> | ||
21 | Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org> | ||
22 | |||
23 | CVE: CVE-2023-24531 | ||
24 | Upstream-Status: Backport [05cc9e55876874462a4726ca0101c970838c80e5] | ||
25 | |||
26 | Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com> | ||
27 | --- | ||
28 | src/cmd/go/internal/envcmd/env.go | 3 +-- | ||
29 | 1 file changed, 1 insertion(+), 2 deletions(-) | ||
30 | |||
31 | diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go | ||
32 | index 0ce8843..b48d0bd 100644 | ||
33 | --- a/src/cmd/go/internal/envcmd/env.go | ||
34 | +++ b/src/cmd/go/internal/envcmd/env.go | ||
35 | @@ -397,8 +397,7 @@ func PrintEnv(w io.Writer, env []cfg.EnvVar) { | ||
36 | if x > 0 { | ||
37 | fmt.Fprintf(w, " ") | ||
38 | } | ||
39 | - // TODO(#59979): Does this need to be quoted like above? | ||
40 | - fmt.Fprintf(w, "%s", s) | ||
41 | + fmt.Fprintf(w, "'%s'", strings.ReplaceAll(s, "'", "''")) | ||
42 | } | ||
43 | fmt.Fprintf(w, ")\n") | ||
44 | } | ||
45 | -- | ||
46 | 2.35.5 | ||
47 | |||