diff options
| -rw-r--r-- | meta/recipes-devtools/go/go-1.20.5.inc | 2 | ||||
| -rw-r--r-- | meta/recipes-devtools/go/go/CVE-2023-24531_1.patch | 266 | ||||
| -rw-r--r-- | meta/recipes-devtools/go/go/CVE-2023-24531_2.patch | 47 |
3 files changed, 315 insertions, 0 deletions
diff --git a/meta/recipes-devtools/go/go-1.20.5.inc b/meta/recipes-devtools/go/go-1.20.5.inc index 4e4e57d5cb..9cc79a8073 100644 --- a/meta/recipes-devtools/go/go-1.20.5.inc +++ b/meta/recipes-devtools/go/go-1.20.5.inc | |||
| @@ -14,5 +14,7 @@ SRC_URI += "\ | |||
| 14 | file://0007-exec.go-do-not-write-linker-flags-into-buildids.patch \ | 14 | file://0007-exec.go-do-not-write-linker-flags-into-buildids.patch \ |
| 15 | file://0008-src-cmd-dist-buildgo.go-do-not-hardcode-host-compile.patch \ | 15 | file://0008-src-cmd-dist-buildgo.go-do-not-hardcode-host-compile.patch \ |
| 16 | file://0009-go-Filter-build-paths-on-staticly-linked-arches.patch \ | 16 | file://0009-go-Filter-build-paths-on-staticly-linked-arches.patch \ |
| 17 | file://CVE-2023-24531_1.patch \ | ||
| 18 | file://CVE-2023-24531_2.patch \ | ||
| 17 | " | 19 | " |
| 18 | SRC_URI[main.sha256sum] = "9a15c133ba2cfafe79652f4815b62e7cfc267f68df1b9454c6ab2a3ca8b96a88" | 20 | SRC_URI[main.sha256sum] = "9a15c133ba2cfafe79652f4815b62e7cfc267f68df1b9454c6ab2a3ca8b96a88" |
diff --git a/meta/recipes-devtools/go/go/CVE-2023-24531_1.patch b/meta/recipes-devtools/go/go/CVE-2023-24531_1.patch new file mode 100644 index 0000000000..9de701b64b --- /dev/null +++ b/meta/recipes-devtools/go/go/CVE-2023-24531_1.patch | |||
| @@ -0,0 +1,266 @@ | |||
| 1 | From c5463ec922a57d8b175c6639186ba9cbe15e6bc1 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 | src/cmd/go/testdata/script/work_env.txt | 2 +- | ||
| 32 | 4 files changed, 158 insertions(+), 3 deletions(-) | ||
| 33 | create mode 100644 src/cmd/go/internal/envcmd/env_test.go | ||
| 34 | create mode 100644 src/cmd/go/testdata/script/env_sanitize.txt | ||
| 35 | |||
| 36 | diff --git a/src/cmd/go/internal/envcmd/env.go b/src/cmd/go/internal/envcmd/env.go | ||
| 37 | index fb7448a..5b52fad 100644 | ||
| 38 | --- a/src/cmd/go/internal/envcmd/env.go | ||
| 39 | +++ b/src/cmd/go/internal/envcmd/env.go | ||
| 40 | @@ -6,6 +6,7 @@ | ||
| 41 | package envcmd | ||
| 42 | |||
| 43 | import ( | ||
| 44 | + "bytes" | ||
| 45 | "context" | ||
| 46 | "encoding/json" | ||
| 47 | "fmt" | ||
| 48 | @@ -17,6 +18,7 @@ import ( | ||
| 49 | "runtime" | ||
| 50 | "sort" | ||
| 51 | "strings" | ||
| 52 | + "unicode" | ||
| 53 | "unicode/utf8" | ||
| 54 | |||
| 55 | "cmd/go/internal/base" | ||
| 56 | @@ -413,9 +415,12 @@ func checkBuildConfig(add map[string]string, del map[string]bool) error { | ||
| 57 | func PrintEnv(w io.Writer, env []cfg.EnvVar) { | ||
| 58 | for _, e := range env { | ||
| 59 | if e.Name != "TERM" { | ||
| 60 | + if runtime.GOOS != "plan9" && bytes.Contains([]byte(e.Value), []byte{0}) { | ||
| 61 | + base.Fatalf("go: internal error: encountered null byte in environment variable %s on non-plan9 platform", e.Name) | ||
| 62 | + } | ||
| 63 | switch runtime.GOOS { | ||
| 64 | default: | ||
| 65 | - fmt.Fprintf(w, "%s=\"%s\"\n", e.Name, e.Value) | ||
| 66 | + fmt.Fprintf(w, "%s=%s\n", e.Name, shellQuote(e.Value)) | ||
| 67 | case "plan9": | ||
| 68 | if strings.IndexByte(e.Value, '\x00') < 0 { | ||
| 69 | fmt.Fprintf(w, "%s='%s'\n", e.Name, strings.ReplaceAll(e.Value, "'", "''")) | ||
| 70 | @@ -426,17 +431,68 @@ func PrintEnv(w io.Writer, env []cfg.EnvVar) { | ||
| 71 | if x > 0 { | ||
| 72 | fmt.Fprintf(w, " ") | ||
| 73 | } | ||
| 74 | + // TODO(#59979): Does this need to be quoted like above? | ||
| 75 | fmt.Fprintf(w, "%s", s) | ||
| 76 | } | ||
| 77 | fmt.Fprintf(w, ")\n") | ||
| 78 | } | ||
| 79 | case "windows": | ||
| 80 | - fmt.Fprintf(w, "set %s=%s\n", e.Name, e.Value) | ||
| 81 | + if hasNonGraphic(e.Value) { | ||
| 82 | + base.Errorf("go: stripping unprintable or unescapable characters from %%%q%%", e.Name) | ||
| 83 | + } | ||
| 84 | + fmt.Fprintf(w, "set %s=%s\n", e.Name, batchEscape(e.Value)) | ||
| 85 | } | ||
| 86 | } | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | +func hasNonGraphic(s string) bool { | ||
| 91 | + for _, c := range []byte(s) { | ||
| 92 | + if c == '\r' || c == '\n' || (!unicode.IsGraphic(rune(c)) && !unicode.IsSpace(rune(c))) { | ||
| 93 | + return true | ||
| 94 | + } | ||
| 95 | + } | ||
| 96 | + return false | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | +func shellQuote(s string) string { | ||
| 100 | + var b bytes.Buffer | ||
| 101 | + b.WriteByte('\'') | ||
| 102 | + for _, x := range []byte(s) { | ||
| 103 | + if x == '\'' { | ||
| 104 | + // Close the single quoted string, add an escaped single quote, | ||
| 105 | + // and start another single quoted string. | ||
| 106 | + b.WriteString(`'\''`) | ||
| 107 | + } else { | ||
| 108 | + b.WriteByte(x) | ||
| 109 | + } | ||
| 110 | + } | ||
| 111 | + b.WriteByte('\'') | ||
| 112 | + return b.String() | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +func batchEscape(s string) string { | ||
| 116 | + var b bytes.Buffer | ||
| 117 | + for _, x := range []byte(s) { | ||
| 118 | + if x == '\r' || x == '\n' || (!unicode.IsGraphic(rune(x)) && !unicode.IsSpace(rune(x))) { | ||
| 119 | + b.WriteRune(unicode.ReplacementChar) | ||
| 120 | + continue | ||
| 121 | + } | ||
| 122 | + switch x { | ||
| 123 | + case '%': | ||
| 124 | + b.WriteString("%%") | ||
| 125 | + case '<', '>', '|', '&', '^': | ||
| 126 | + // These are special characters that need to be escaped with ^. See | ||
| 127 | + // https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/set_1. | ||
| 128 | + b.WriteByte('^') | ||
| 129 | + b.WriteByte(x) | ||
| 130 | + default: | ||
| 131 | + b.WriteByte(x) | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + return b.String() | ||
| 135 | +} | ||
| 136 | + | ||
| 137 | func printEnvAsJSON(env []cfg.EnvVar) { | ||
| 138 | m := make(map[string]string) | ||
| 139 | for _, e := range env { | ||
| 140 | diff --git a/src/cmd/go/internal/envcmd/env_test.go b/src/cmd/go/internal/envcmd/env_test.go | ||
| 141 | new file mode 100644 | ||
| 142 | index 0000000..32d99fd | ||
| 143 | --- /dev/null | ||
| 144 | +++ b/src/cmd/go/internal/envcmd/env_test.go | ||
| 145 | @@ -0,0 +1,94 @@ | ||
| 146 | +// Copyright 2022 The Go Authors. All rights reserved. | ||
| 147 | +// Use of this source code is governed by a BSD-style | ||
| 148 | +// license that can be found in the LICENSE file. | ||
| 149 | + | ||
| 150 | +//go:build unix || windows | ||
| 151 | + | ||
| 152 | +package envcmd | ||
| 153 | + | ||
| 154 | +import ( | ||
| 155 | + "bytes" | ||
| 156 | + "cmd/go/internal/cfg" | ||
| 157 | + "fmt" | ||
| 158 | + "internal/testenv" | ||
| 159 | + "os" | ||
| 160 | + "os/exec" | ||
| 161 | + "path/filepath" | ||
| 162 | + "runtime" | ||
| 163 | + "testing" | ||
| 164 | + "unicode" | ||
| 165 | +) | ||
| 166 | + | ||
| 167 | +func FuzzPrintEnvEscape(f *testing.F) { | ||
| 168 | + f.Add(`$(echo 'cc"'; echo 'OOPS="oops')`) | ||
| 169 | + f.Add("$(echo shell expansion 1>&2)") | ||
| 170 | + f.Add("''") | ||
| 171 | + f.Add(`C:\"Program Files"\`) | ||
| 172 | + f.Add(`\\"Quoted Host"\\share`) | ||
| 173 | + f.Add("\xfb") | ||
| 174 | + f.Add("0") | ||
| 175 | + f.Add("") | ||
| 176 | + f.Add("''''''''") | ||
| 177 | + f.Add("\r") | ||
| 178 | + f.Add("\n") | ||
| 179 | + f.Add("E,%") | ||
| 180 | + f.Fuzz(func(t *testing.T, s string) { | ||
| 181 | + t.Parallel() | ||
| 182 | + | ||
| 183 | + for _, c := range []byte(s) { | ||
| 184 | + if c == 0 { | ||
| 185 | + t.Skipf("skipping %q: contains a null byte. Null bytes can't occur in the environment"+ | ||
| 186 | + " outside of Plan 9, which has different code path than Windows and Unix that this test"+ | ||
| 187 | + " isn't testing.", s) | ||
| 188 | + } | ||
| 189 | + if c > unicode.MaxASCII { | ||
| 190 | + t.Skipf("skipping %#q: contains a non-ASCII character %q", s, c) | ||
| 191 | + } | ||
| 192 | + if !unicode.IsGraphic(rune(c)) && !unicode.IsSpace(rune(c)) { | ||
| 193 | + t.Skipf("skipping %#q: contains non-graphic character %q", s, c) | ||
| 194 | + } | ||
| 195 | + if runtime.GOOS == "windows" && c == '\r' || c == '\n' { | ||
| 196 | + t.Skipf("skipping %#q on Windows: contains unescapable character %q", s, c) | ||
| 197 | + } | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + var b bytes.Buffer | ||
| 201 | + if runtime.GOOS == "windows" { | ||
| 202 | + b.WriteString("@echo off\n") | ||
| 203 | + } | ||
| 204 | + PrintEnv(&b, []cfg.EnvVar{{Name: "var", Value: s}}) | ||
| 205 | + var want string | ||
| 206 | + if runtime.GOOS == "windows" { | ||
| 207 | + fmt.Fprintf(&b, "echo \"%%var%%\"\n") | ||
| 208 | + want += "\"" + s + "\"\r\n" | ||
| 209 | + } else { | ||
| 210 | + fmt.Fprintf(&b, "printf '%%s\\n' \"$var\"\n") | ||
| 211 | + want += s + "\n" | ||
| 212 | + } | ||
| 213 | + scriptfilename := "script.sh" | ||
| 214 | + if runtime.GOOS == "windows" { | ||
| 215 | + scriptfilename = "script.bat" | ||
| 216 | + } | ||
| 217 | + scriptfile := filepath.Join(t.TempDir(), scriptfilename) | ||
| 218 | + if err := os.WriteFile(scriptfile, b.Bytes(), 0777); err != nil { | ||
| 219 | + t.Fatal(err) | ||
| 220 | + } | ||
| 221 | + t.Log(b.String()) | ||
| 222 | + var cmd *exec.Cmd | ||
| 223 | + if runtime.GOOS == "windows" { | ||
| 224 | + cmd = testenv.Command(t, "cmd.exe", "/C", scriptfile) | ||
| 225 | + } else { | ||
| 226 | + cmd = testenv.Command(t, "sh", "-c", scriptfile) | ||
| 227 | + } | ||
| 228 | + out, err := cmd.Output() | ||
| 229 | + t.Log(string(out)) | ||
| 230 | + if err != nil { | ||
| 231 | + t.Fatal(err) | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + if string(out) != want { | ||
| 235 | + t.Fatalf("output of running PrintEnv script and echoing variable: got: %q, want: %q", | ||
| 236 | + string(out), want) | ||
| 237 | + } | ||
| 238 | + }) | ||
| 239 | +} | ||
| 240 | diff --git a/src/cmd/go/testdata/script/env_sanitize.txt b/src/cmd/go/testdata/script/env_sanitize.txt | ||
| 241 | new file mode 100644 | ||
| 242 | index 0000000..cc4d23a | ||
| 243 | --- /dev/null | ||
| 244 | +++ b/src/cmd/go/testdata/script/env_sanitize.txt | ||
| 245 | @@ -0,0 +1,5 @@ | ||
| 246 | +env GOFLAGS='$(echo ''cc"''; echo ''OOPS="oops'')' | ||
| 247 | +go env | ||
| 248 | +[GOOS:darwin] stdout 'GOFLAGS=''\$\(echo ''\\''''cc"''\\''''; echo ''\\''''OOPS="oops''\\''''\)''' | ||
| 249 | +[GOOS:linux] stdout 'GOFLAGS=''\$\(echo ''\\''''cc"''\\''''; echo ''\\''''OOPS="oops''\\''''\)''' | ||
| 250 | +[GOOS:windows] stdout 'set GOFLAGS=\$\(echo ''cc"''; echo ''OOPS="oops''\)' | ||
| 251 | diff --git a/src/cmd/go/testdata/script/work_env.txt b/src/cmd/go/testdata/script/work_env.txt | ||
| 252 | index 511bb4e..8b1779e 100644 | ||
| 253 | --- a/src/cmd/go/testdata/script/work_env.txt | ||
| 254 | +++ b/src/cmd/go/testdata/script/work_env.txt | ||
| 255 | @@ -1,7 +1,7 @@ | ||
| 256 | go env GOWORK | ||
| 257 | stdout '^'$GOPATH'[\\/]src[\\/]go.work$' | ||
| 258 | go env | ||
| 259 | -stdout '^(set )?GOWORK="?'$GOPATH'[\\/]src[\\/]go.work"?$' | ||
| 260 | +stdout '^(set )?GOWORK=''?'$GOPATH'[\\/]src[\\/]go.work''?$' | ||
| 261 | |||
| 262 | cd .. | ||
| 263 | go env GOWORK | ||
| 264 | -- | ||
| 265 | 2.39.0 | ||
| 266 | |||
diff --git a/meta/recipes-devtools/go/go/CVE-2023-24531_2.patch b/meta/recipes-devtools/go/go/CVE-2023-24531_2.patch new file mode 100644 index 0000000000..dec36f9d42 --- /dev/null +++ b/meta/recipes-devtools/go/go/CVE-2023-24531_2.patch | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | From 24f1def536c5344e0067a3119790b83ee6224058 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 5b52fad..d4fc399 100644 | ||
| 33 | --- a/src/cmd/go/internal/envcmd/env.go | ||
| 34 | +++ b/src/cmd/go/internal/envcmd/env.go | ||
| 35 | @@ -431,8 +431,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.39.0 | ||
| 47 | |||
