Skip to content

[AutoPR- Security] Patch golang for CVE-2025-47906 [HIGH] #14463

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: fasttrack/2.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 183 additions & 0 deletions SPECS/golang/CVE-2025-47906.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
From 3d0a24c57c8a16cea02a02ca8498f4645d93737f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Olivier=20Mengu=C3=A9?= <[email protected]>
Date: Mon, 30 Jun 2025 16:58:59 +0200
Subject: [PATCH] os/exec: fix incorrect expansion of "", "." and ".." in
LookPath

Fix incorrect expansion of "" and "." when $PATH contains an executable
file or, on Windows, a parent directory of a %PATH% element contains an
file with the same name as the %PATH% element but with one of the
%PATHEXT% extension (ex: C:\utils\bin is in PATH, and C:\utils\bin.exe
exists).

Fix incorrect expansion of ".." when $PATH contains an element which is
an the concatenation of the path to an executable file (or on Windows
a path that can be expanded to an executable by appending a %PATHEXT%
extension), a path separator and a name.

"", "." and ".." are now rejected early with ErrNotFound.

Fixes CVE-2025-47906
Fixes #74803

Change-Id: Ie50cc0a660fce8fbdc952a7f2e05c36062dcb50e
Reviewed-on: https://go-review.googlesource.com/c/go/+/685755
LUCI-TryBot-Result: Go LUCI <[email protected]>
Auto-Submit: Damien Neil <[email protected]>
Reviewed-by: Roland Shoemaker <[email protected]>
Reviewed-by: Damien Neil <[email protected]>
(cherry picked from commit e0b07dc22eaab1b003d98ad6d63cdfacc76c5c70)
Reviewed-on: https://go-review.googlesource.com/c/go/+/691855
Reviewed-by: Michael Knyszek <[email protected]>
Signed-off-by: Azure Linux Security Servicing Account <[email protected]>
Upstream-reference: https://github.com/golang/go/commit/8fa31a2d7d9e60c50a3a94080c097b6e65773f4b.patch
---
src/os/exec/dot_test.go | 56 +++++++++++++++++++++++++++++++++++++++
src/os/exec/exec.go | 10 +++++++
src/os/exec/lp_plan9.go | 4 +++
src/os/exec/lp_unix.go | 4 +++
src/os/exec/lp_windows.go | 8 ++++++
5 files changed, 82 insertions(+)

diff --git a/src/os/exec/dot_test.go b/src/os/exec/dot_test.go
index ed4bad2..86e9cbb 100644
--- a/src/os/exec/dot_test.go
+++ b/src/os/exec/dot_test.go
@@ -178,4 +178,60 @@ func TestLookPath(t *testing.T) {
}
}
})
+
+ checker := func(test string) func(t *testing.T) {
+ return func(t *testing.T) {
+ t.Helper()
+ t.Logf("PATH=%s", os.Getenv("PATH"))
+ p, err := LookPath(test)
+ if err == nil {
+ t.Errorf("%q: error expected, got nil", test)
+ }
+ if p != "" {
+ t.Errorf("%q: path returned should be \"\". Got %q", test, p)
+ }
+ }
+ }
+
+ // Reference behavior for the next test
+ t.Run(pathVar+"=$OTHER2", func(t *testing.T) {
+ t.Run("empty", checker(""))
+ t.Run("dot", checker("."))
+ t.Run("dotdot1", checker("abc/.."))
+ t.Run("dotdot2", checker(".."))
+ })
+
+ // Test the behavior when PATH contains an executable file which is not a directory
+ t.Run(pathVar+"=exe", func(t *testing.T) {
+ // Inject an executable file (not a directory) in PATH.
+ // Use our own binary os.Args[0].
+ testenv.MustHaveExec(t)
+ exe, err := os.Executable()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ t.Setenv(pathVar, exe)
+ t.Run("empty", checker(""))
+ t.Run("dot", checker("."))
+ t.Run("dotdot1", checker("abc/.."))
+ t.Run("dotdot2", checker(".."))
+ })
+
+ // Test the behavior when PATH contains an executable file which is not a directory
+ t.Run(pathVar+"=exe/xx", func(t *testing.T) {
+ // Inject an executable file (not a directory) in PATH.
+ // Use our own binary os.Args[0].
+ testenv.MustHaveExec(t)
+ exe, err := os.Executable()
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ t.Setenv(pathVar, filepath.Join(exe, "xx"))
+ t.Run("empty", checker(""))
+ t.Run("dot", checker("."))
+ t.Run("dotdot1", checker("abc/.."))
+ t.Run("dotdot2", checker(".."))
+ })
}
diff --git a/src/os/exec/exec.go b/src/os/exec/exec.go
index b8ef5a0..2c7f510 100644
--- a/src/os/exec/exec.go
+++ b/src/os/exec/exec.go
@@ -1310,3 +1310,13 @@ func addCriticalEnv(env []string) []string {
// Code should use errors.Is(err, ErrDot), not err == ErrDot,
// to test whether a returned error err is due to this condition.
var ErrDot = errors.New("cannot run executable found relative to current directory")
+
+// validateLookPath excludes paths that can't be valid
+// executable names. See issue #74466 and CVE-2025-47906.
+func validateLookPath(s string) error {
+ switch s {
+ case "", ".", "..":
+ return ErrNotFound
+ }
+ return nil
+}
diff --git a/src/os/exec/lp_plan9.go b/src/os/exec/lp_plan9.go
index dffdbac..39f3d33 100644
--- a/src/os/exec/lp_plan9.go
+++ b/src/os/exec/lp_plan9.go
@@ -36,6 +36,10 @@ func findExecutable(file string) error {
// As of Go 1.19, LookPath will instead return that path along with an error satisfying
// errors.Is(err, ErrDot). See the package documentation for more details.
func LookPath(file string) (string, error) {
+ if err := validateLookPath(file); err != nil {
+ return "", &Error{file, err}
+ }
+
// skip the path lookup for these prefixes
skip := []string{"/", "#", "./", "../"}

diff --git a/src/os/exec/lp_unix.go b/src/os/exec/lp_unix.go
index 3787132..2543525 100644
--- a/src/os/exec/lp_unix.go
+++ b/src/os/exec/lp_unix.go
@@ -54,6 +54,10 @@ func LookPath(file string) (string, error) {
// (only bypass the path if file begins with / or ./ or ../)
// but that would not match all the Unix shells.

+ if err := validateLookPath(file); err != nil {
+ return "", &Error{file, err}
+ }
+
if strings.Contains(file, "/") {
err := findExecutable(file)
if err == nil {
diff --git a/src/os/exec/lp_windows.go b/src/os/exec/lp_windows.go
index 698a97c..6b87661 100644
--- a/src/os/exec/lp_windows.go
+++ b/src/os/exec/lp_windows.go
@@ -68,6 +68,10 @@ func findExecutable(file string, exts []string) (string, error) {
// As of Go 1.19, LookPath will instead return that path along with an error satisfying
// errors.Is(err, ErrDot). See the package documentation for more details.
func LookPath(file string) (string, error) {
+ if err := validateLookPath(file); err != nil {
+ return "", &Error{file, err}
+ }
+
return lookPath(file, pathExt())
}

@@ -81,6 +85,10 @@ func LookPath(file string) (string, error) {
// "C:\foo\example.com" would be returned as-is even if the
// program is actually "C:\foo\example.com.exe".
func lookExtensions(path, dir string) (string, error) {
+ if err := validateLookPath(path); err != nil {
+ return "", &Error{path, err}
+ }
+
if filepath.Base(path) == path {
path = "." + string(filepath.Separator) + path
}
--
2.45.4

7 changes: 6 additions & 1 deletion SPECS/golang/golang.spec
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
Summary: Go
Name: golang
Version: 1.22.7
Release: 4%{?dist}
Release: 5%{?dist}
License: BSD-3-Clause
Vendor: Microsoft Corporation
Distribution: Mariner
Expand All @@ -30,6 +30,7 @@ Patch1: CVE-2024-45336.patch
Patch2: CVE-2024-45341.patch
Patch3: CVE-2025-22871.patch
Patch4: CVE-2025-22870.patch
Patch5: CVE-2025-47906.patch
Obsoletes: %{name} < %{version}
Provides: %{name} = %{version}
Provides: go = %{version}-%{release}
Expand All @@ -49,6 +50,7 @@ mv -v go go-bootstrap
%patch 2 -p1
%patch 3 -p1
%patch 4 -p1
%patch 5 -p1

%build
# Go 1.22 requires the final point release of Go 1.20 or later for bootstrap.
Expand Down Expand Up @@ -164,6 +166,9 @@ fi
%{_bindir}/*

%changelog
* Fri Aug 08 2025 Azure Linux Security Servicing Account <[email protected]> - 1.22.7-5
- Patch for CVE-2025-47906

* Thu May 08 2025 Archana Shettigar <[email protected]> - 1.22.7-4
- Address CVE-2025-22870 using an upstream patch.

Expand Down
Loading