aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan C. Mills <bcmills@google.com>2022-05-27 15:54:44 -0400
committerCherry Mui <cherryyz@google.com>2022-07-25 23:27:36 +0000
commitd252fdd630a51db206194b3c41c3d036fdd6f48a (patch)
tree2719dc02c0f299163a55211b3b446b91dc5079f3
parent4782f4275c8d006e0346026585e50633a5a31007 (diff)
downloadgo-d252fdd630a51db206194b3c41c3d036fdd6f48a.tar.gz
go-d252fdd630a51db206194b3c41c3d036fdd6f48a.zip
[release-branch.go1.18] cmd/go: omit build metadata that may contain system paths when -trimpath is set
CGO flag variables often include system paths for header files and compiled libraries. The point of -trimpath is to avoid dependending on system paths, so stamping these variables is counterproductive. Moreover, the point of stamping build information is to improve reproducibility. Since we don't also stamp the versions of C compilers, headers, and libraries used in a cgo build, only the most trivial cgo programs can be faithfully reproduced from the stamped information. Likewise, the -ldflags flag may include system-specific paths, particularly if external linking is in use. For now, we omit -ldflags entirely; however, in the future we may instead want to parse and redact the individual flags. Updates #52372. Fixes #53119. Change-Id: I73318a01cce4371d66955b3261fc7ee58d4b33dd Reviewed-on: https://go-review.googlesource.com/c/go/+/409174 TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Bryan Mills <bcmills@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Bryan Mills <bcmills@google.com> (cherry picked from commit a6e5be0d30770e8bd1ba1e4bac2089218df121d9) Reviewed-on: https://go-review.googlesource.com/c/go/+/414794 Reviewed-by: Nooras Saba‎ <saba@golang.org>
-rw-r--r--src/cmd/go/internal/load/pkg.go21
-rw-r--r--src/cmd/go/testdata/script/version_build_settings.txt17
2 files changed, 35 insertions, 3 deletions
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
index 438cc35085..5b5b5efbba 100644
--- a/src/cmd/go/internal/load/pkg.go
+++ b/src/cmd/go/internal/load/pkg.go
@@ -2329,7 +2329,17 @@ func (p *Package) setBuildInfo(includeVCS bool) {
appendSetting("-gcflags", BuildGcflags.String())
}
if BuildLdflags.present {
- appendSetting("-ldflags", BuildLdflags.String())
+ // https://go.dev/issue/52372: only include ldflags if -trimpath is not set,
+ // since it can include system paths through various linker flags (notably
+ // -extar, -extld, and -extldflags).
+ //
+ // TODO: since we control cmd/link, in theory we can parse ldflags to
+ // determine whether they may refer to system paths. If we do that, we can
+ // redact only those paths from the recorded -ldflags setting and still
+ // record the system-independent parts of the flags.
+ if !cfg.BuildTrimpath {
+ appendSetting("-ldflags", BuildLdflags.String())
+ }
}
if cfg.BuildMSan {
appendSetting("-msan", "true")
@@ -2345,7 +2355,14 @@ func (p *Package) setBuildInfo(includeVCS bool) {
cgo = "1"
}
appendSetting("CGO_ENABLED", cgo)
- if cfg.BuildContext.CgoEnabled {
+ // https://go.dev/issue/52372: only include CGO flags if -trimpath is not set.
+ // (If -trimpath is set, it is possible that these flags include system paths.)
+ // If cgo is involved, reproducibility is already pretty well ruined anyway,
+ // given that we aren't stamping header or library versions.
+ //
+ // TODO(bcmills): perhaps we could at least parse the flags and stamp the
+ // subset of flags that are known not to be paths?
+ if cfg.BuildContext.CgoEnabled && !cfg.BuildTrimpath {
for _, name := range []string{"CGO_CFLAGS", "CGO_CPPFLAGS", "CGO_CXXFLAGS", "CGO_LDFLAGS"} {
appendSetting(name, cfg.Getenv(name))
}
diff --git a/src/cmd/go/testdata/script/version_build_settings.txt b/src/cmd/go/testdata/script/version_build_settings.txt
index dc9e67681e..08df7e611d 100644
--- a/src/cmd/go/testdata/script/version_build_settings.txt
+++ b/src/cmd/go/testdata/script/version_build_settings.txt
@@ -47,19 +47,34 @@ go build
go version -m m$GOEXE
stdout '^\tbuild\tCGO_ENABLED=0$'
! stdout CGO_CPPFLAGS|CGO_CFLAGS|CGO_CXXFLAGS|CGO_LDFLAGS
+
[cgo] env CGO_ENABLED=1
[cgo] env CGO_CPPFLAGS=-DFROM_CPPFLAGS=1
[cgo] env CGO_CFLAGS=-DFROM_CFLAGS=1
[cgo] env CGO_CXXFLAGS=-DFROM_CXXFLAGS=1
[cgo] env CGO_LDFLAGS=-L/extra/dir/does/not/exist
-[cgo] go build
+[cgo] go build '-ldflags=all=-linkmode=external -extldflags=-L/bonus/dir/does/not/exist'
[cgo] go version -m m$GOEXE
+[cgo] stdout '^\tbuild\t-ldflags="all=-linkmode=external -extldflags=-L/bonus/dir/does/not/exist"$'
[cgo] stdout '^\tbuild\tCGO_ENABLED=1$'
[cgo] stdout '^\tbuild\tCGO_CPPFLAGS=-DFROM_CPPFLAGS=1$'
[cgo] stdout '^\tbuild\tCGO_CFLAGS=-DFROM_CFLAGS=1$'
[cgo] stdout '^\tbuild\tCGO_CXXFLAGS=-DFROM_CXXFLAGS=1$'
[cgo] stdout '^\tbuild\tCGO_LDFLAGS=-L/extra/dir/does/not/exist$'
+# https://go.dev/issue/52372: a cgo-enabled binary should not be stamped with
+# CGO_ flags that contain paths.
+[cgo] env CGO_ENABLED=1
+[cgo] env CGO_CPPFLAGS=-DFROM_CPPFLAGS=1
+[cgo] env CGO_CFLAGS=-DFROM_CFLAGS=1
+[cgo] env CGO_CXXFLAGS=-DFROM_CXXFLAGS=1
+[cgo] env CGO_LDFLAGS=-L/extra/dir/does/not/exist
+[cgo] go build -trimpath '-ldflags=all=-linkmode=external -extldflags=-L/bonus/dir/does/not/exist'
+[cgo] go version -m m$GOEXE
+[cgo] ! stdout '/extra/dir/does/not/exist'
+[cgo] ! stdout '/bonus/dir/does/not/exist'
+[cgo] stdout '^\tbuild\tCGO_ENABLED=1$'
+
-- go.mod --
module example.com/m