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 | |||
