-
Notifications
You must be signed in to change notification settings - Fork 590
[HIGH] Patch golang 1.22.7 for CVE-2025-4674 #14427
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
Draft
archana25-ms
wants to merge
3
commits into
microsoft:fasttrack/2.0
Choose a base branch
from
archana25-ms:golang-1.22.7-2.0
base: fasttrack/2.0
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+333
−1
Draft
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,327 @@ | ||
From e9d2c032b14c17083be0f8f0c822565199d2994f Mon Sep 17 00:00:00 2001 | ||
From: Roland Shoemaker <[email protected]> | ||
Date: Mon, 9 Jun 2025 11:23:46 -0700 | ||
Subject: [PATCH] [release-branch.go1.23] cmd/go: disable support for multiple | ||
vcs in one module | ||
Upstream Patch Reference: https://github.com/golang/go/commit/e9d2c032b14c17083be0f8f0c822565199d2994f | ||
|
||
Removes the somewhat redundant vcs.FromDir, "allowNesting" argument, | ||
which was always enabled, and disallow multiple VCS metadata folders | ||
being present in a single directory. This makes VCS injection attacks | ||
much more difficult. | ||
|
||
Also adds a GODEBUG, allowmultiplevcs, which re-enables this behavior. | ||
|
||
Thanks to RyotaK (https://ryotak.net) of GMO Flatt Security Inc for | ||
reporting this issue. | ||
|
||
Updates #74380 | ||
Fixes #74382 | ||
Fixes CVE-2025-4674 | ||
|
||
Change-Id: I2db79f2baacfacfec331ee7c6978c4057d483eba | ||
Reviewed-on: https://go-review.googlesource.com/c/go/+/686337 | ||
LUCI-TryBot-Result: Go LUCI <[email protected]> | ||
Reviewed-by: David Chase <[email protected]> | ||
Reviewed-by: Carlos Amedee <[email protected]> | ||
Commit-Queue: Carlos Amedee <[email protected]> | ||
--- | ||
doc/godebug.md | 3 +++ | ||
src/cmd/go/internal/load/pkg.go | 14 ++--- | ||
src/cmd/go/internal/vcs/vcs.go | 28 ++++++---- | ||
src/cmd/go/internal/vcs/vcs_test.go | 2 +- | ||
src/cmd/go/testdata/script/test_multivcs.txt | 54 +++++++++++++++++++ | ||
.../script/version_buildvcs_nested.txt | 20 +++++-- | ||
src/internal/godebugs/godebugs_test.go | 3 +- | ||
src/internal/godebugs/table.go | 1 + | ||
src/runtime/metrics/doc.go | 5 ++ | ||
9 files changed, 108 insertions(+), 23 deletions(-) | ||
create mode 100644 src/cmd/go/testdata/script/test_multivcs.txt | ||
|
||
diff --git a/doc/godebug.md b/doc/godebug.md | ||
index b3a43664c42cd4..9d3c810cdc227d 100644 | ||
--- a/doc/godebug.md | ||
+++ b/doc/godebug.md | ||
@@ -193,6 +193,9 @@ not used during marshaling. It can be used to marshal these larger OIDs, instead | ||
of the existing PolicyIdentifiers field, by using the | ||
[`x509usepolicies` setting.](/pkg/crypto/x509/#CreateCertificate). | ||
|
||
+Go 1.22.7 disabled build information stamping when multiple VCS are detected due | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although this is not an issue here as it is just text - We would probably not want to change this. From what I recall Go 1.23.11 disabled build information stamping, and not 1.22 :) |
||
+to concerns around VCS injection attacks. This behavior can be renabled with the | ||
+setting `allowmultiplevcs=1`. | ||
|
||
### Go 1.21 | ||
|
||
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go | ||
index 7c402b419ea0ca..d45b29659942e6 100644 | ||
--- a/src/cmd/go/internal/load/pkg.go | ||
+++ b/src/cmd/go/internal/load/pkg.go | ||
@@ -2409,7 +2409,6 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) { | ||
var repoDir string | ||
var vcsCmd *vcs.Cmd | ||
var err error | ||
- const allowNesting = true | ||
|
||
wantVCS := false | ||
switch cfg.BuildBuildvcs { | ||
@@ -2429,7 +2428,7 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) { | ||
// (so the bootstrap toolchain packages don't even appear to be in GOROOT). | ||
goto omitVCS | ||
} | ||
- repoDir, vcsCmd, err = vcs.FromDir(base.Cwd(), "", allowNesting) | ||
+ repoDir, vcsCmd, err = vcs.FromDir(base.Cwd(), "") | ||
if err != nil && !errors.Is(err, os.ErrNotExist) { | ||
setVCSError(err) | ||
return | ||
@@ -2452,10 +2451,11 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) { | ||
} | ||
if repoDir != "" && vcsCmd.Status != nil { | ||
// Check that the current directory, package, and module are in the same | ||
- // repository. vcs.FromDir allows nested Git repositories, but nesting | ||
- // is not allowed for other VCS tools. The current directory may be outside | ||
- // p.Module.Dir when a workspace is used. | ||
- pkgRepoDir, _, err := vcs.FromDir(p.Dir, "", allowNesting) | ||
+ // repository. vcs.FromDir disallows nested VCS and multiple VCS in the | ||
+ // same repository, unless the GODEBUG allowmultiplevcs is set. The | ||
+ // current directory may be outside p.Module.Dir when a workspace is | ||
+ // used. | ||
+ pkgRepoDir, _, err := vcs.FromDir(p.Dir, "") | ||
if err != nil { | ||
setVCSError(err) | ||
return | ||
@@ -2467,7 +2467,7 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) { | ||
} | ||
goto omitVCS | ||
} | ||
- modRepoDir, _, err := vcs.FromDir(p.Module.Dir, "", allowNesting) | ||
+ modRepoDir, _, err := vcs.FromDir(p.Module.Dir, "") | ||
if err != nil { | ||
setVCSError(err) | ||
return | ||
diff --git a/src/cmd/go/internal/vcs/vcs.go b/src/cmd/go/internal/vcs/vcs.go | ||
index 19a6a5ef6b0b7c..f2f362b57c2973 100644 | ||
--- a/src/cmd/go/internal/vcs/vcs.go | ||
+++ b/src/cmd/go/internal/vcs/vcs.go | ||
@@ -8,6 +8,7 @@ import ( | ||
"bytes" | ||
"errors" | ||
"fmt" | ||
+ "internal/godebug" | ||
"internal/lazyregexp" | ||
"internal/singleflight" | ||
"io/fs" | ||
@@ -831,11 +832,13 @@ type vcsPath struct { | ||
schemelessRepo bool // if true, the repo pattern lacks a scheme | ||
} | ||
|
||
+var allowmultiplevcs = godebug.New("allowmultiplevcs") | ||
+ | ||
// FromDir inspects dir and its parents to determine the | ||
// version control system and code repository to use. | ||
// If no repository is found, FromDir returns an error | ||
// equivalent to os.ErrNotExist. | ||
-func FromDir(dir, srcRoot string, allowNesting bool) (repoDir string, vcsCmd *Cmd, err error) { | ||
+func FromDir(dir, srcRoot string) (repoDir string, vcsCmd *Cmd, err error) { | ||
// Clean and double-check that dir is in (a subdirectory of) srcRoot. | ||
dir = filepath.Clean(dir) | ||
if srcRoot != "" { | ||
@@ -849,21 +852,28 @@ func FromDir(dir, srcRoot string, allowNesting bool) (repoDir string, vcsCmd *Cm | ||
for len(dir) > len(srcRoot) { | ||
for _, vcs := range vcsList { | ||
if isVCSRoot(dir, vcs.RootNames) { | ||
- // Record first VCS we find. | ||
- // If allowNesting is false (as it is in GOPATH), keep looking for | ||
- // repositories in parent directories and report an error if one is | ||
- // found to mitigate VCS injection attacks. | ||
if vcsCmd == nil { | ||
+ // Record first VCS we find. | ||
vcsCmd = vcs | ||
repoDir = dir | ||
- if allowNesting { | ||
+ if allowmultiplevcs.Value() == "1" { | ||
+ allowmultiplevcs.IncNonDefault() | ||
return repoDir, vcsCmd, nil | ||
} | ||
+ // If allowmultiplevcs is not set, keep looking for | ||
+ // repositories in current and parent directories and report | ||
+ // an error if one is found to mitigate VCS injection | ||
+ // attacks. | ||
+ continue | ||
+ } | ||
+ if vcsCmd == vcsGit && vcs == vcsGit { | ||
+ // Nested Git is allowed, as this is how things like | ||
+ // submodules work. Git explicitly protects against | ||
+ // injection against itself. | ||
continue | ||
} | ||
- // Otherwise, we have one VCS inside a different VCS. | ||
- return "", nil, fmt.Errorf("directory %q uses %s, but parent %q uses %s", | ||
- repoDir, vcsCmd.Cmd, dir, vcs.Cmd) | ||
+ return "", nil, fmt.Errorf("multiple VCS detected: %s in %q, and %s in %q", | ||
+ vcsCmd.Cmd, repoDir, vcs.Cmd, dir) | ||
} | ||
} | ||
|
||
diff --git a/src/cmd/go/internal/vcs/vcs_test.go b/src/cmd/go/internal/vcs/vcs_test.go | ||
index 2ce85ea210967f..06e63c29528f2f 100644 | ||
--- a/src/cmd/go/internal/vcs/vcs_test.go | ||
+++ b/src/cmd/go/internal/vcs/vcs_test.go | ||
@@ -239,7 +239,7 @@ func TestFromDir(t *testing.T) { | ||
} | ||
|
||
wantRepoDir := filepath.Dir(dir) | ||
- gotRepoDir, gotVCS, err := FromDir(dir, tempDir, false) | ||
+ gotRepoDir, gotVCS, err := FromDir(dir, tempDir) | ||
if err != nil { | ||
t.Errorf("FromDir(%q, %q): %v", dir, tempDir, err) | ||
continue | ||
diff --git a/src/cmd/go/testdata/script/test_multivcs.txt b/src/cmd/go/testdata/script/test_multivcs.txt | ||
new file mode 100644 | ||
index 00000000000000..538cbf700b4585 | ||
--- /dev/null | ||
+++ b/src/cmd/go/testdata/script/test_multivcs.txt | ||
@@ -0,0 +1,54 @@ | ||
+# To avoid VCS injection attacks, we should not accept multiple different VCS metadata | ||
+# folders within a single module (either in the same directory, or nested in different | ||
+# directories.) | ||
+# | ||
+# This behavior should be disabled by setting the allowmultiplevcs GODEBUG. | ||
+ | ||
+[short] skip | ||
+[!git] skip | ||
+ | ||
+cd samedir | ||
+ | ||
+exec git init . | ||
+ | ||
+# Without explicitly requesting buildvcs, the go command should silently continue | ||
+# without determining the correct VCS. | ||
+go test -c -o $devnull . | ||
+ | ||
+# If buildvcs is explicitly requested, we expect the go command to fail | ||
+! go test -buildvcs -c -o $devnull . | ||
+stderr '^error obtaining VCS status: multiple VCS detected:' | ||
+ | ||
+env GODEBUG=allowmultiplevcs=1 | ||
+go test -buildvcs -c -o $devnull . | ||
+ | ||
+env GODEBUG= | ||
+cd ../nested | ||
+exec git init . | ||
+# cd a | ||
+go test -c -o $devnull ./a | ||
+! go test -buildvcs -c -o $devnull ./a | ||
+stderr '^error obtaining VCS status: multiple VCS detected:' | ||
+# allowmultiplevcs doesn't disable the check that the current directory, package, and | ||
+# module are in the same repository. | ||
+env GODEBUG=allowmultiplevcs=1 | ||
+! go test -buildvcs -c -o $devnull ./a | ||
+stderr '^error obtaining VCS status: main package is in repository' | ||
+ | ||
+-- samedir/go.mod -- | ||
+module example | ||
+ | ||
+go 1.18 | ||
+-- samedir/example.go -- | ||
+package main | ||
+-- samedir/.bzr/test -- | ||
+hello | ||
+ | ||
+-- nested/go.mod -- | ||
+module example | ||
+ | ||
+go 1.18 | ||
+-- nested/a/example.go -- | ||
+package main | ||
+-- nested/a/.bzr/test -- | ||
+hello | ||
diff --git a/src/cmd/go/testdata/script/version_buildvcs_nested.txt b/src/cmd/go/testdata/script/version_buildvcs_nested.txt | ||
index 6dab8474b59d44..22cd71c454b712 100644 | ||
--- a/src/cmd/go/testdata/script/version_buildvcs_nested.txt | ||
+++ b/src/cmd/go/testdata/script/version_buildvcs_nested.txt | ||
@@ -9,25 +9,35 @@ cd root | ||
go mod init example.com/root | ||
exec git init | ||
|
||
-# Nesting repositories in parent directories are ignored, as the current | ||
-# directory main package, and containing main module are in the same repository. | ||
-# This is an error in GOPATH mode (to prevent VCS injection), but for modules, | ||
-# we assume users have control over repositories they've checked out. | ||
+ | ||
+# Nesting repositories in parent directories are an error, to prevent VCS injection. | ||
+# This can be disabled with the allowmultiplevcs GODEBUG. | ||
mkdir hgsub | ||
cd hgsub | ||
exec hg init | ||
cp ../../main.go main.go | ||
! go build | ||
+stderr '^error obtaining VCS status: multiple VCS detected: hg in ".*hgsub", and git in ".*root"$' | ||
+stderr '^\tUse -buildvcs=false to disable VCS stamping.$' | ||
+env GODEBUG=allowmultiplevcs=1 | ||
+! go build | ||
stderr '^error obtaining VCS status: main module is in repository ".*root" but current directory is in repository ".*hgsub"$' | ||
stderr '^\tUse -buildvcs=false to disable VCS stamping.$' | ||
go build -buildvcs=false | ||
+env GODEBUG= | ||
go mod init example.com/root/hgsub | ||
+! go build | ||
+stderr '^error obtaining VCS status: multiple VCS detected: hg in ".*hgsub", and git in ".*root"$' | ||
+stderr '^\tUse -buildvcs=false to disable VCS stamping.$' | ||
+env GODEBUG=allowmultiplevcs=1 | ||
go build | ||
+env GODEBUG= | ||
cd .. | ||
|
||
# It's an error to build a package from a nested Git repository if the package | ||
# is in a separate repository from the current directory or from the module | ||
-# root directory. | ||
+# root directory. Otherwise nested Git repositories are allowed, as this is | ||
+# how Git implements submodules (and protects against Git based VCS injection.) | ||
mkdir gitsub | ||
cd gitsub | ||
exec git init | ||
diff --git a/src/internal/godebugs/godebugs_test.go b/src/internal/godebugs/godebugs_test.go | ||
index 046193b5c6b13b..168acc134aa753 100644 | ||
--- a/src/internal/godebugs/godebugs_test.go | ||
+++ b/src/internal/godebugs/godebugs_test.go | ||
@@ -46,7 +46,8 @@ func TestAll(t *testing.T) { | ||
if info.Old != "" && info.Changed == 0 { | ||
t.Errorf("Name=%s has Old, missing Changed", info.Name) | ||
} | ||
- if !strings.Contains(doc, "`"+info.Name+"`") { | ||
+ if !strings.Contains(doc, "`"+info.Name+"`") && | ||
+ !strings.Contains(doc, "`"+info.Name+"=") { | ||
t.Errorf("Name=%s not documented in doc/godebug.md", info.Name) | ||
} | ||
} | ||
diff --git a/src/internal/godebugs/table.go b/src/internal/godebugs/table.go | ||
index 473a0992df8967..f5831bc54cc114 100644 | ||
--- a/src/internal/godebugs/table.go | ||
+++ b/src/internal/godebugs/table.go | ||
@@ -25,6 +25,7 @@ type Info struct { | ||
// Note: After adding entries to this table, update the list in doc/godebug.md as well. | ||
// (Otherwise the test in this package will fail.) | ||
var All = []Info{ | ||
+ {Name: "allowmultiplevcs", Package: "cmd/go"}, | ||
{Name: "execerrdot", Package: "os/exec"}, | ||
{Name: "gocachehash", Package: "cmd/go"}, | ||
{Name: "gocachetest", Package: "cmd/go"}, | ||
diff --git a/src/runtime/metrics/doc.go b/src/runtime/metrics/doc.go | ||
index da3d956d480beb..3575ca02d89cad 100644 | ||
--- a/src/runtime/metrics/doc.go | ||
+++ b/src/runtime/metrics/doc.go | ||
@@ -230,6 +230,11 @@ Below is the full list of supported metrics, ordered lexicographically. | ||
/gc/stack/starting-size:bytes | ||
The stack size of new goroutines. | ||
|
||
+ /godebug/non-default-behavior/allowmultiplevcs:events | ||
+ The number of non-default behaviors executed by the cmd/go | ||
+ package due to a non-default GODEBUG=allowmultiplevcs=... | ||
+ setting. | ||
+ | ||
/godebug/non-default-behavior/execerrdot:events | ||
The number of non-default behaviors executed by the os/exec | ||
package due to a non-default GODEBUG=execerrdot=... setting. | ||
-- | ||
2.45.4 | ||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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-4674.patch | ||
Obsoletes: %{name} < %{version} | ||
Provides: %{name} = %{version} | ||
Provides: go = %{version}-%{release} | ||
|
@@ -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. | ||
|
@@ -164,6 +166,9 @@ fi | |
%{_bindir}/* | ||
|
||
%changelog | ||
* Fri Aug 01 2025 Archana Shettigar <[email protected]> - 1.22.7-5 | ||
- Address CVE-2025-4674 using an upstream patch. | ||
|
||
* Thu May 08 2025 Archana Shettigar <[email protected]> - 1.22.7-4 | ||
- Address CVE-2025-22870 using an upstream patch. | ||
|
||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Patch Applies Cleanly
Slight back port for this patch was needed
Patch looks good to me apart from a slight change which is text only.
Signed-Off By: Muhammad Falak