diff options
| -rw-r--r-- | meta/recipes-devtools/go/go-1.22.12.inc | 1 | ||||
| -rw-r--r-- | meta/recipes-devtools/go/go/CVE-2025-47906.patch | 183 |
2 files changed, 184 insertions, 0 deletions
diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc index d0ce333117..a364e1aae8 100644 --- a/meta/recipes-devtools/go/go-1.22.12.inc +++ b/meta/recipes-devtools/go/go-1.22.12.inc | |||
| @@ -20,6 +20,7 @@ SRC_URI += "\ | |||
| 20 | file://CVE-2025-4674.patch \ | 20 | file://CVE-2025-4674.patch \ |
| 21 | file://CVE-2025-47907-pre.patch \ | 21 | file://CVE-2025-47907-pre.patch \ |
| 22 | file://CVE-2025-47907.patch \ | 22 | file://CVE-2025-47907.patch \ |
| 23 | file://CVE-2025-47906.patch \ | ||
| 23 | " | 24 | " |
| 24 | SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71" | 25 | SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71" |
| 25 | 26 | ||
diff --git a/meta/recipes-devtools/go/go/CVE-2025-47906.patch b/meta/recipes-devtools/go/go/CVE-2025-47906.patch new file mode 100644 index 0000000000..88895f496d --- /dev/null +++ b/meta/recipes-devtools/go/go/CVE-2025-47906.patch | |||
| @@ -0,0 +1,183 @@ | |||
| 1 | From 8fa31a2d7d9e60c50a3a94080c097b6e65773f4b Mon Sep 17 00:00:00 2001 | ||
| 2 | From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= <olivier.mengue@gmail.com> | ||
| 3 | Date: Mon, 30 Jun 2025 16:58:59 +0200 | ||
| 4 | Subject: [PATCH] [release-branch.go1.23] os/exec: fix incorrect expansion of | ||
| 5 | "", "." and ".." in LookPath Fix incorrect expansion of "" and "." when $PATH | ||
| 6 | contains an executable file or, on Windows, a parent directory of a %PATH% | ||
| 7 | element contains an file with the same name as the %PATH% element but with | ||
| 8 | one of the %PATHEXT% extension (ex: C:\utils\bin is in PATH, and | ||
| 9 | C:\utils\bin.exe exists). | ||
| 10 | |||
| 11 | Fix incorrect expansion of ".." when $PATH contains an element which is | ||
| 12 | an the concatenation of the path to an executable file (or on Windows | ||
| 13 | a path that can be expanded to an executable by appending a %PATHEXT% | ||
| 14 | extension), a path separator and a name. | ||
| 15 | |||
| 16 | "", "." and ".." are now rejected early with ErrNotFound. | ||
| 17 | |||
| 18 | Fixes CVE-2025-47906 | ||
| 19 | Fixes #74803 | ||
| 20 | |||
| 21 | Change-Id: Ie50cc0a660fce8fbdc952a7f2e05c36062dcb50e | ||
| 22 | Reviewed-on: https://go-review.googlesource.com/c/go/+/685755 | ||
| 23 | LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> | ||
| 24 | Auto-Submit: Damien Neil <dneil@google.com> | ||
| 25 | Reviewed-by: Roland Shoemaker <roland@golang.org> | ||
| 26 | Reviewed-by: Damien Neil <dneil@google.com> | ||
| 27 | (cherry picked from commit e0b07dc) | ||
| 28 | Reviewed-on: https://go-review.googlesource.com/c/go/+/691855 | ||
| 29 | Reviewed-by: Michael Knyszek <mknyszek@google.com> | ||
| 30 | |||
| 31 | CVE: CVE-2025-47906 | ||
| 32 | |||
| 33 | Upstream-Status: Backport [https://github.com/golang/go/commit/8fa31a2d7d9e60c50a3a94080c097b6e65773f4b] | ||
| 34 | |||
| 35 | Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com> | ||
| 36 | --- | ||
| 37 | src/os/exec/dot_test.go | 56 +++++++++++++++++++++++++++++++++++++++ | ||
| 38 | src/os/exec/exec.go | 10 +++++++ | ||
| 39 | src/os/exec/lp_plan9.go | 4 +++ | ||
| 40 | src/os/exec/lp_unix.go | 4 +++ | ||
| 41 | src/os/exec/lp_windows.go | 7 +++++ | ||
| 42 | 5 files changed, 81 insertions(+) | ||
| 43 | |||
| 44 | diff --git a/src/os/exec/dot_test.go b/src/os/exec/dot_test.go | ||
| 45 | index ed4bad2..86e9cbb 100644 | ||
| 46 | --- a/src/os/exec/dot_test.go | ||
| 47 | +++ b/src/os/exec/dot_test.go | ||
| 48 | @@ -178,4 +178,60 @@ func TestLookPath(t *testing.T) { | ||
| 49 | } | ||
| 50 | } | ||
| 51 | }) | ||
| 52 | + | ||
| 53 | + checker := func(test string) func(t *testing.T) { | ||
| 54 | + return func(t *testing.T) { | ||
| 55 | + t.Helper() | ||
| 56 | + t.Logf("PATH=%s", os.Getenv("PATH")) | ||
| 57 | + p, err := LookPath(test) | ||
| 58 | + if err == nil { | ||
| 59 | + t.Errorf("%q: error expected, got nil", test) | ||
| 60 | + } | ||
| 61 | + if p != "" { | ||
| 62 | + t.Errorf("%q: path returned should be \"\". Got %q", test, p) | ||
| 63 | + } | ||
| 64 | + } | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + // Reference behavior for the next test | ||
| 68 | + t.Run(pathVar+"=$OTHER2", func(t *testing.T) { | ||
| 69 | + t.Run("empty", checker("")) | ||
| 70 | + t.Run("dot", checker(".")) | ||
| 71 | + t.Run("dotdot1", checker("abc/..")) | ||
| 72 | + t.Run("dotdot2", checker("..")) | ||
| 73 | + }) | ||
| 74 | + | ||
| 75 | + // Test the behavior when PATH contains an executable file which is not a directory | ||
| 76 | + t.Run(pathVar+"=exe", func(t *testing.T) { | ||
| 77 | + // Inject an executable file (not a directory) in PATH. | ||
| 78 | + // Use our own binary os.Args[0]. | ||
| 79 | + testenv.MustHaveExec(t) | ||
| 80 | + exe, err := os.Executable() | ||
| 81 | + if err != nil { | ||
| 82 | + t.Fatal(err) | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + t.Setenv(pathVar, exe) | ||
| 86 | + t.Run("empty", checker("")) | ||
| 87 | + t.Run("dot", checker(".")) | ||
| 88 | + t.Run("dotdot1", checker("abc/..")) | ||
| 89 | + t.Run("dotdot2", checker("..")) | ||
| 90 | + }) | ||
| 91 | + | ||
| 92 | + // Test the behavior when PATH contains an executable file which is not a directory | ||
| 93 | + t.Run(pathVar+"=exe/xx", func(t *testing.T) { | ||
| 94 | + // Inject an executable file (not a directory) in PATH. | ||
| 95 | + // Use our own binary os.Args[0]. | ||
| 96 | + testenv.MustHaveExec(t) | ||
| 97 | + exe, err := os.Executable() | ||
| 98 | + if err != nil { | ||
| 99 | + t.Fatal(err) | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + t.Setenv(pathVar, filepath.Join(exe, "xx")) | ||
| 103 | + t.Run("empty", checker("")) | ||
| 104 | + t.Run("dot", checker(".")) | ||
| 105 | + t.Run("dotdot1", checker("abc/..")) | ||
| 106 | + t.Run("dotdot2", checker("..")) | ||
| 107 | + }) | ||
| 108 | } | ||
| 109 | diff --git a/src/os/exec/exec.go b/src/os/exec/exec.go | ||
| 110 | index b8ef5a0..2c7f510 100644 | ||
| 111 | --- a/src/os/exec/exec.go | ||
| 112 | +++ b/src/os/exec/exec.go | ||
| 113 | @@ -1310,3 +1310,13 @@ func addCriticalEnv(env []string) []string { | ||
| 114 | // Code should use errors.Is(err, ErrDot), not err == ErrDot, | ||
| 115 | // to test whether a returned error err is due to this condition. | ||
| 116 | var ErrDot = errors.New("cannot run executable found relative to current directory") | ||
| 117 | + | ||
| 118 | +// validateLookPath excludes paths that can't be valid | ||
| 119 | +// executable names. See issue #74466 and CVE-2025-47906. | ||
| 120 | +func validateLookPath(s string) error { | ||
| 121 | + switch s { | ||
| 122 | + case "", ".", "..": | ||
| 123 | + return ErrNotFound | ||
| 124 | + } | ||
| 125 | + return nil | ||
| 126 | +} | ||
| 127 | diff --git a/src/os/exec/lp_plan9.go b/src/os/exec/lp_plan9.go | ||
| 128 | index dffdbac..39f3d33 100644 | ||
| 129 | --- a/src/os/exec/lp_plan9.go | ||
| 130 | +++ b/src/os/exec/lp_plan9.go | ||
| 131 | @@ -36,6 +36,10 @@ func findExecutable(file string) error { | ||
| 132 | // As of Go 1.19, LookPath will instead return that path along with an error satisfying | ||
| 133 | // errors.Is(err, ErrDot). See the package documentation for more details. | ||
| 134 | func LookPath(file string) (string, error) { | ||
| 135 | + if err := validateLookPath(file); err != nil { | ||
| 136 | + return "", &Error{file, err} | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | // skip the path lookup for these prefixes | ||
| 140 | skip := []string{"/", "#", "./", "../"} | ||
| 141 | |||
| 142 | diff --git a/src/os/exec/lp_unix.go b/src/os/exec/lp_unix.go | ||
| 143 | index 3787132..2543525 100644 | ||
| 144 | --- a/src/os/exec/lp_unix.go | ||
| 145 | +++ b/src/os/exec/lp_unix.go | ||
| 146 | @@ -54,6 +54,10 @@ func LookPath(file string) (string, error) { | ||
| 147 | // (only bypass the path if file begins with / or ./ or ../) | ||
| 148 | // but that would not match all the Unix shells. | ||
| 149 | |||
| 150 | + if err := validateLookPath(file); err != nil { | ||
| 151 | + return "", &Error{file, err} | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | if strings.Contains(file, "/") { | ||
| 155 | err := findExecutable(file) | ||
| 156 | if err == nil { | ||
| 157 | diff --git a/src/os/exec/lp_windows.go b/src/os/exec/lp_windows.go | ||
| 158 | index 698a97c..e0b74e3 100644 | ||
| 159 | --- a/src/os/exec/lp_windows.go | ||
| 160 | +++ b/src/os/exec/lp_windows.go | ||
| 161 | @@ -68,6 +68,9 @@ func findExecutable(file string, exts []string) (string, error) { | ||
| 162 | // As of Go 1.19, LookPath will instead return that path along with an error satisfying | ||
| 163 | // errors.Is(err, ErrDot). See the package documentation for more details. | ||
| 164 | func LookPath(file string) (string, error) { | ||
| 165 | + if err := validateLookPath(file); err != nil { | ||
| 166 | + return "", &Error{file, err} | ||
| 167 | + } | ||
| 168 | return lookPath(file, pathExt()) | ||
| 169 | } | ||
| 170 | |||
| 171 | @@ -81,6 +84,10 @@ func LookPath(file string) (string, error) { | ||
| 172 | // "C:\foo\example.com" would be returned as-is even if the | ||
| 173 | // program is actually "C:\foo\example.com.exe". | ||
| 174 | func lookExtensions(path, dir string) (string, error) { | ||
| 175 | + if err := validateLookPath(path); err != nil { | ||
| 176 | + return "", &Error{path, err} | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | if filepath.Base(path) == path { | ||
| 180 | path = "." + string(filepath.Separator) + path | ||
| 181 | } | ||
| 182 | -- | ||
| 183 | 2.40.0 | ||
