summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArchana Polampalli <archana.polampalli@windriver.com>2025-08-20 12:28:12 +0530
committerSteve Sakoman <steve@sakoman.com>2025-09-01 08:30:56 -0700
commitb4135ab2542ae30eb45e387c344e432a98a46e12 (patch)
treea617c55af242f458710e9a04dc707826ff0f4147
parentec220ae083dba35c279192b2249ad03fe238446e (diff)
downloadpoky-b4135ab2542ae30eb45e387c344e432a98a46e12.tar.gz
go: fix CVE-2025-4674
The go command may execute unexpected commands when operating in untrusted VCS repositories. This occurs when possibly dangerous VCS configuration is present in repositories. This can happen when a repository was fetched via one VCS (e.g. Git), but contains metadata for another VCS (e.g. Mercurial). Modules which are retrieved using the go command line, i.e. via "go get", are not affected. (From OE-Core rev: efdc4920571677c9051d4402eaa801672eeb24e3) Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com> Signed-off-by: Steve Sakoman <steve@sakoman.com>
-rw-r--r--meta/recipes-devtools/go/go-1.22.12.inc1
-rw-r--r--meta/recipes-devtools/go/go/CVE-2025-4674.patch332
2 files changed, 333 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 ea57b23c3e..12d7539017 100644
--- a/meta/recipes-devtools/go/go-1.22.12.inc
+++ b/meta/recipes-devtools/go/go-1.22.12.inc
@@ -17,6 +17,7 @@ SRC_URI += "\
17 file://CVE-2025-22870.patch \ 17 file://CVE-2025-22870.patch \
18 file://CVE-2025-22871.patch \ 18 file://CVE-2025-22871.patch \
19 file://CVE-2025-4673.patch \ 19 file://CVE-2025-4673.patch \
20 file://CVE-2025-4674.patch \
20" 21"
21SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71" 22SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71"
22 23
diff --git a/meta/recipes-devtools/go/go/CVE-2025-4674.patch b/meta/recipes-devtools/go/go/CVE-2025-4674.patch
new file mode 100644
index 0000000000..bc6e438652
--- /dev/null
+++ b/meta/recipes-devtools/go/go/CVE-2025-4674.patch
@@ -0,0 +1,332 @@
1From e9d2c032b14c17083be0f8f0c822565199d2994f Mon Sep 17 00:00:00 2001
2From: Roland Shoemaker <bracewell@google.com>
3Date: Mon, 9 Jun 2025 11:23:46 -0700
4Subject: [PATCH] [release-branch.go1.23] cmd/go: disable support for multiple
5 vcs in one module
6
7Removes the somewhat redundant vcs.FromDir, "allowNesting" argument,
8which was always enabled, and disallow multiple VCS metadata folders
9being present in a single directory. This makes VCS injection attacks
10much more difficult.
11
12Also adds a GODEBUG, allowmultiplevcs, which re-enables this behavior.
13
14Thanks to RyotaK (https://ryotak.net) of GMO Flatt Security Inc for
15reporting this issue.
16
17Updates #74380
18Fixes #74382
19Fixes CVE-2025-4674
20
21CVE: CVE-2025-4674
22
23Upstream-Status: Backport [https://github.com/golang/go/commit/e9d2c032b14c17083be0f8f0c822565199d2994f]
24
25Change-Id: I2db79f2baacfacfec331ee7c6978c4057d483eba
26Reviewed-on: https://go-review.googlesource.com/c/go/+/686337
27LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
28Reviewed-by: David Chase <drchase@google.com>
29Reviewed-by: Carlos Amedee <carlos@golang.org>
30Commit-Queue: Carlos Amedee <carlos@golang.org>
31
32Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
33---
34 doc/godebug.md | 4 ++
35 src/cmd/go/internal/load/pkg.go | 14 ++---
36 src/cmd/go/internal/vcs/vcs.go | 28 ++++++----
37 src/cmd/go/internal/vcs/vcs_test.go | 2 +-
38 src/cmd/go/testdata/script/test_multivcs.txt | 54 +++++++++++++++++++
39 .../script/version_buildvcs_nested.txt | 20 +++++--
40 src/internal/godebugs/godebugs_test.go | 3 +-
41 src/internal/godebugs/table.go | 1 +
42 src/runtime/metrics/doc.go | 5 ++
43 9 files changed, 108 insertions(+), 23 deletions(-)
44 create mode 100644 src/cmd/go/testdata/script/test_multivcs.txt
45
46diff --git a/doc/godebug.md b/doc/godebug.md
47index fb3f32f..ae4f057 100644
48--- a/doc/godebug.md
49+++ b/doc/godebug.md
50@@ -126,6 +126,10 @@ for example,
51 see the [runtime documentation](/pkg/runtime#hdr-Environment_Variables)
52 and the [go command documentation](/cmd/go#hdr-Build_and_test_caching).
53
54+Go 1.23.11 disabled build information stamping when multiple VCS are detected due
55+to concerns around VCS injection attacks. This behavior can be renabled with the
56+setting `allowmultiplevcs=1`.
57+
58 ### Go 1.22
59
60 Go 1.22 adds a configurable limit to control the maximum acceptable RSA key size
61diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
62index f41fb2c..428780e 100644
63--- a/src/cmd/go/internal/load/pkg.go
64+++ b/src/cmd/go/internal/load/pkg.go
65@@ -2465,7 +2465,6 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) {
66 var repoDir string
67 var vcsCmd *vcs.Cmd
68 var err error
69- const allowNesting = true
70
71 wantVCS := false
72 switch cfg.BuildBuildvcs {
73@@ -2485,7 +2484,7 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) {
74 // (so the bootstrap toolchain packages don't even appear to be in GOROOT).
75 goto omitVCS
76 }
77- repoDir, vcsCmd, err = vcs.FromDir(base.Cwd(), "", allowNesting)
78+ repoDir, vcsCmd, err = vcs.FromDir(base.Cwd(), "")
79 if err != nil && !errors.Is(err, os.ErrNotExist) {
80 setVCSError(err)
81 return
82@@ -2508,10 +2507,11 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) {
83 }
84 if repoDir != "" && vcsCmd.Status != nil {
85 // Check that the current directory, package, and module are in the same
86- // repository. vcs.FromDir allows nested Git repositories, but nesting
87- // is not allowed for other VCS tools. The current directory may be outside
88- // p.Module.Dir when a workspace is used.
89- pkgRepoDir, _, err := vcs.FromDir(p.Dir, "", allowNesting)
90+ // repository. vcs.FromDir disallows nested VCS and multiple VCS in the
91+ // same repository, unless the GODEBUG allowmultiplevcs is set. The
92+ // current directory may be outside p.Module.Dir when a workspace is
93+ // used.
94+ pkgRepoDir, _, err := vcs.FromDir(p.Dir, "")
95 if err != nil {
96 setVCSError(err)
97 return
98@@ -2523,7 +2523,7 @@ func (p *Package) setBuildInfo(ctx context.Context, autoVCS bool) {
99 }
100 goto omitVCS
101 }
102- modRepoDir, _, err := vcs.FromDir(p.Module.Dir, "", allowNesting)
103+ modRepoDir, _, err := vcs.FromDir(p.Module.Dir, "")
104 if err != nil {
105 setVCSError(err)
106 return
107diff --git a/src/cmd/go/internal/vcs/vcs.go b/src/cmd/go/internal/vcs/vcs.go
108index 8550f2a..89d9f0e 100644
109--- a/src/cmd/go/internal/vcs/vcs.go
110+++ b/src/cmd/go/internal/vcs/vcs.go
111@@ -8,6 +8,7 @@ import (
112 "bytes"
113 "errors"
114 "fmt"
115+ "internal/godebug"
116 "internal/lazyregexp"
117 "internal/singleflight"
118 "io/fs"
119@@ -831,11 +832,13 @@ type vcsPath struct {
120 schemelessRepo bool // if true, the repo pattern lacks a scheme
121 }
122
123+var allowmultiplevcs = godebug.New("allowmultiplevcs")
124+
125 // FromDir inspects dir and its parents to determine the
126 // version control system and code repository to use.
127 // If no repository is found, FromDir returns an error
128 // equivalent to os.ErrNotExist.
129-func FromDir(dir, srcRoot string, allowNesting bool) (repoDir string, vcsCmd *Cmd, err error) {
130+func FromDir(dir, srcRoot string) (repoDir string, vcsCmd *Cmd, err error) {
131 // Clean and double-check that dir is in (a subdirectory of) srcRoot.
132 dir = filepath.Clean(dir)
133 if srcRoot != "" {
134@@ -849,21 +852,28 @@ func FromDir(dir, srcRoot string, allowNesting bool) (repoDir string, vcsCmd *Cm
135 for len(dir) > len(srcRoot) {
136 for _, vcs := range vcsList {
137 if isVCSRoot(dir, vcs.RootNames) {
138- // Record first VCS we find.
139- // If allowNesting is false (as it is in GOPATH), keep looking for
140- // repositories in parent directories and report an error if one is
141- // found to mitigate VCS injection attacks.
142 if vcsCmd == nil {
143+ // Record first VCS we find.
144 vcsCmd = vcs
145 repoDir = dir
146- if allowNesting {
147+ if allowmultiplevcs.Value() == "1" {
148+ allowmultiplevcs.IncNonDefault()
149 return repoDir, vcsCmd, nil
150 }
151+ // If allowmultiplevcs is not set, keep looking for
152+ // repositories in current and parent directories and report
153+ // an error if one is found to mitigate VCS injection
154+ // attacks.
155+ continue
156+ }
157+ if vcsCmd == vcsGit && vcs == vcsGit {
158+ // Nested Git is allowed, as this is how things like
159+ // submodules work. Git explicitly protects against
160+ // injection against itself.
161 continue
162 }
163- // Otherwise, we have one VCS inside a different VCS.
164- return "", nil, fmt.Errorf("directory %q uses %s, but parent %q uses %s",
165- repoDir, vcsCmd.Cmd, dir, vcs.Cmd)
166+ return "", nil, fmt.Errorf("multiple VCS detected: %s in %q, and %s in %q",
167+ vcsCmd.Cmd, repoDir, vcs.Cmd, dir)
168 }
169 }
170
171diff --git a/src/cmd/go/internal/vcs/vcs_test.go b/src/cmd/go/internal/vcs/vcs_test.go
172index 2ce85ea..06e63c2 100644
173--- a/src/cmd/go/internal/vcs/vcs_test.go
174+++ b/src/cmd/go/internal/vcs/vcs_test.go
175@@ -239,7 +239,7 @@ func TestFromDir(t *testing.T) {
176 }
177
178 wantRepoDir := filepath.Dir(dir)
179- gotRepoDir, gotVCS, err := FromDir(dir, tempDir, false)
180+ gotRepoDir, gotVCS, err := FromDir(dir, tempDir)
181 if err != nil {
182 t.Errorf("FromDir(%q, %q): %v", dir, tempDir, err)
183 continue
184diff --git a/src/cmd/go/testdata/script/test_multivcs.txt b/src/cmd/go/testdata/script/test_multivcs.txt
185new file mode 100644
186index 0000000..538cbf7
187--- /dev/null
188+++ b/src/cmd/go/testdata/script/test_multivcs.txt
189@@ -0,0 +1,54 @@
190+# To avoid VCS injection attacks, we should not accept multiple different VCS metadata
191+# folders within a single module (either in the same directory, or nested in different
192+# directories.)
193+#
194+# This behavior should be disabled by setting the allowmultiplevcs GODEBUG.
195+
196+[short] skip
197+[!git] skip
198+
199+cd samedir
200+
201+exec git init .
202+
203+# Without explicitly requesting buildvcs, the go command should silently continue
204+# without determining the correct VCS.
205+go test -c -o $devnull .
206+
207+# If buildvcs is explicitly requested, we expect the go command to fail
208+! go test -buildvcs -c -o $devnull .
209+stderr '^error obtaining VCS status: multiple VCS detected:'
210+
211+env GODEBUG=allowmultiplevcs=1
212+go test -buildvcs -c -o $devnull .
213+
214+env GODEBUG=
215+cd ../nested
216+exec git init .
217+# cd a
218+go test -c -o $devnull ./a
219+! go test -buildvcs -c -o $devnull ./a
220+stderr '^error obtaining VCS status: multiple VCS detected:'
221+# allowmultiplevcs doesn't disable the check that the current directory, package, and
222+# module are in the same repository.
223+env GODEBUG=allowmultiplevcs=1
224+! go test -buildvcs -c -o $devnull ./a
225+stderr '^error obtaining VCS status: main package is in repository'
226+
227+-- samedir/go.mod --
228+module example
229+
230+go 1.18
231+-- samedir/example.go --
232+package main
233+-- samedir/.bzr/test --
234+hello
235+
236+-- nested/go.mod --
237+module example
238+
239+go 1.18
240+-- nested/a/example.go --
241+package main
242+-- nested/a/.bzr/test --
243+hello
244diff --git a/src/cmd/go/testdata/script/version_buildvcs_nested.txt b/src/cmd/go/testdata/script/version_buildvcs_nested.txt
245index 6dab847..22cd71c 100644
246--- a/src/cmd/go/testdata/script/version_buildvcs_nested.txt
247+++ b/src/cmd/go/testdata/script/version_buildvcs_nested.txt
248@@ -9,25 +9,35 @@ cd root
249 go mod init example.com/root
250 exec git init
251
252-# Nesting repositories in parent directories are ignored, as the current
253-# directory main package, and containing main module are in the same repository.
254-# This is an error in GOPATH mode (to prevent VCS injection), but for modules,
255-# we assume users have control over repositories they've checked out.
256+
257+# Nesting repositories in parent directories are an error, to prevent VCS injection.
258+# This can be disabled with the allowmultiplevcs GODEBUG.
259 mkdir hgsub
260 cd hgsub
261 exec hg init
262 cp ../../main.go main.go
263 ! go build
264+stderr '^error obtaining VCS status: multiple VCS detected: hg in ".*hgsub", and git in ".*root"$'
265+stderr '^\tUse -buildvcs=false to disable VCS stamping.$'
266+env GODEBUG=allowmultiplevcs=1
267+! go build
268 stderr '^error obtaining VCS status: main module is in repository ".*root" but current directory is in repository ".*hgsub"$'
269 stderr '^\tUse -buildvcs=false to disable VCS stamping.$'
270 go build -buildvcs=false
271+env GODEBUG=
272 go mod init example.com/root/hgsub
273+! go build
274+stderr '^error obtaining VCS status: multiple VCS detected: hg in ".*hgsub", and git in ".*root"$'
275+stderr '^\tUse -buildvcs=false to disable VCS stamping.$'
276+env GODEBUG=allowmultiplevcs=1
277 go build
278+env GODEBUG=
279 cd ..
280
281 # It's an error to build a package from a nested Git repository if the package
282 # is in a separate repository from the current directory or from the module
283-# root directory.
284+# root directory. Otherwise nested Git repositories are allowed, as this is
285+# how Git implements submodules (and protects against Git based VCS injection.)
286 mkdir gitsub
287 cd gitsub
288 exec git init
289diff --git a/src/internal/godebugs/godebugs_test.go b/src/internal/godebugs/godebugs_test.go
290index a1cb8d4..b3784eb 100644
291--- a/src/internal/godebugs/godebugs_test.go
292+++ b/src/internal/godebugs/godebugs_test.go
293@@ -39,7 +39,8 @@ func TestAll(t *testing.T) {
294 if info.Old != "" && info.Changed == 0 {
295 t.Errorf("Name=%s has Old, missing Changed", info.Name)
296 }
297- if !strings.Contains(doc, "`"+info.Name+"`") {
298+ if !strings.Contains(doc, "`"+info.Name+"`") &&
299+ !strings.Contains(doc, "`"+info.Name+"=") {
300 t.Errorf("Name=%s not documented in doc/godebug.md", info.Name)
301 }
302 }
303diff --git a/src/internal/godebugs/table.go b/src/internal/godebugs/table.go
304index 11c5b7d..33dcd81 100644
305--- a/src/internal/godebugs/table.go
306+++ b/src/internal/godebugs/table.go
307@@ -25,6 +25,7 @@ type Info struct {
308 // Note: After adding entries to this table, update the list in doc/godebug.md as well.
309 // (Otherwise the test in this package will fail.)
310 var All = []Info{
311+ {Name: "allowmultiplevcs", Package: "cmd/go"},
312 {Name: "execerrdot", Package: "os/exec"},
313 {Name: "gocachehash", Package: "cmd/go"},
314 {Name: "gocachetest", Package: "cmd/go"},
315diff --git a/src/runtime/metrics/doc.go b/src/runtime/metrics/doc.go
316index 85f256d..517ec0e 100644
317--- a/src/runtime/metrics/doc.go
318+++ b/src/runtime/metrics/doc.go
319@@ -230,6 +230,11 @@ Below is the full list of supported metrics, ordered lexicographically.
320 /gc/stack/starting-size:bytes
321 The stack size of new goroutines.
322
323+ /godebug/non-default-behavior/allowmultiplevcs:events
324+ The number of non-default behaviors executed by the cmd/go
325+ package due to a non-default GODEBUG=allowmultiplevcs=...
326+ setting.
327+
328 /godebug/non-default-behavior/execerrdot:events
329 The number of non-default behaviors executed by the os/exec
330 package due to a non-default GODEBUG=execerrdot=... setting.
331--
3322.40.0