go: build PIE by default (#442965)

This commit is contained in:
Philip Taron
2025-10-07 20:35:30 -07:00
committed by GitHub
6 changed files with 108 additions and 12 deletions
@@ -31,11 +31,6 @@ buildGoModule rec {
env GOFLAGS="" go generate ./jaeger/static
env GOFLAGS="" go generate ./multicluster/static
env GOFLAGS="" go generate ./viz/static
# Necessary for building Musl
if [[ $NIX_HARDENING_ENABLE =~ "pie" ]]; then
export GOFLAGS="-buildmode=pie $GOFLAGS"
fi
'';
tags = [
+3 -7
View File
@@ -250,6 +250,9 @@ lib.extendMkDerivation {
export GOPATH="$TMPDIR/go"
export GOPROXY=off
export GOSUMDB=off
if [ -f "$NIX_CC_FOR_TARGET/nix-support/dynamic-linker" ]; then
export GO_LDSO=$(cat $NIX_CC_FOR_TARGET/nix-support/dynamic-linker)
fi
cd "$modRoot"
''
+ lib.optionalString (finalAttrs.vendorHash != null) ''
@@ -266,13 +269,6 @@ lib.extendMkDerivation {
}
''
+ ''
# currently pie is only enabled by default in pkgsMusl
# this will respect the `hardening{Disable,Enable}` flags if set
if [[ $NIX_HARDENING_ENABLE =~ "pie" ]]; then
export GOFLAGS="-buildmode=pie $GOFLAGS"
fi
runHook postConfigure
''
);
+13
View File
@@ -64,6 +64,10 @@ stdenv.mkDerivation (finalAttrs: {
})
./remove-tools-1.11.patch
./go_no_vendor_checks-1.23.patch
./go-env-go_ldso.patch
(replaceVars ./go-default-pie.patch {
inherit (stdenv.targetPlatform.go) GOARCH;
})
];
inherit (stdenv.targetPlatform.go) GOOS GOARCH GOARM;
@@ -99,6 +103,9 @@ stdenv.mkDerivation (finalAttrs: {
buildPhase = ''
runHook preBuild
export GOCACHE=$TMPDIR/go-cache
if [ -f "$NIX_CC/nix-support/dynamic-linker" ]; then
export GO_LDSO=$(cat $NIX_CC/nix-support/dynamic-linker)
fi
export PATH=$(pwd)/bin:$PATH
@@ -106,6 +113,12 @@ stdenv.mkDerivation (finalAttrs: {
# Independent from host/target, CC should produce code for the building system.
# We only set it when cross-compiling.
export CC=${buildPackages.stdenv.cc}/bin/cc
# Prefer external linker for cross when CGO is supported, since
# we haven't taught go's internal linker to pick the correct ELF
# interpreter for cross
# When CGO is not supported we rely on static binaries being built
# since they don't need an ELF interpreter
export GO_EXTLINK_ENABLED=${toString finalAttrs.CGO_ENABLED}
''}
ulimit -a
+35
View File
@@ -10,8 +10,12 @@
buildPackages,
pkgsBuildTarget,
targetPackages,
# for testing
testers,
runCommand,
bintools,
skopeo,
clickhouse-backup,
buildGo125Module,
}:
@@ -19,6 +23,7 @@ let
goBootstrap = buildPackages.callPackage ./bootstrap122.nix { };
skopeoTest = skopeo.override { buildGoModule = buildGo125Module; };
clickhouse-backupTest = clickhouse-backup.override { buildGoModule = buildGo125Module; };
# We need a target compiler which is still runnable at build time,
# to handle the cross-building case where build != host == target
@@ -69,6 +74,10 @@ stdenv.mkDerivation (finalAttrs: {
})
./remove-tools-1.11.patch
./go_no_vendor_checks-1.23.patch
./go-env-go_ldso.patch
(replaceVars ./go-default-pie.patch {
inherit (stdenv.targetPlatform.go) GOARCH;
})
];
inherit (stdenv.targetPlatform.go) GOOS GOARCH GOARM;
@@ -104,6 +113,9 @@ stdenv.mkDerivation (finalAttrs: {
buildPhase = ''
runHook preBuild
export GOCACHE=$TMPDIR/go-cache
if [ -f "$NIX_CC/nix-support/dynamic-linker" ]; then
export GO_LDSO=$(cat $NIX_CC/nix-support/dynamic-linker)
fi
export PATH=$(pwd)/bin:$PATH
@@ -111,6 +123,12 @@ stdenv.mkDerivation (finalAttrs: {
# Independent from host/target, CC should produce code for the building system.
# We only set it when cross-compiling.
export CC=${buildPackages.stdenv.cc}/bin/cc
# Prefer external linker for cross when CGO is supported, since
# we haven't taught go's internal linker to pick the correct ELF
# interpreter for cross
# When CGO is not supported we rely on static binaries being built
# since they don't need an ELF interpreter
export GO_EXTLINK_ENABLED=${toString finalAttrs.CGO_ENABLED}
''}
ulimit -a
@@ -169,6 +187,23 @@ stdenv.mkDerivation (finalAttrs: {
command = "go version";
version = "go${finalAttrs.version}";
};
# Picked clickhouse-backup as a package that sets CGO_ENABLED=0
# Running and outputting the right version proves a working ELF interpreter was picked
clickhouse-backup = testers.testVersion { package = clickhouse-backupTest; };
clickhouse-backup-is-pie = runCommand "has-pie" { meta.broken = stdenv.hostPlatform.isStatic; } ''
${lib.optionalString (!isCross) ''
if ${lib.getExe' bintools "readelf"} -p .comment ${lib.getExe clickhouse-backup} | grep -Fq "GCC: (GNU)"; then
echo "${lib.getExe clickhouse-backup} has a GCC .comment, but it should have used the internal go linker"
exit 1
fi
''}
if ${lib.getExe' bintools "readelf"} -h ${lib.getExe clickhouse-backup} | grep -q "Type:.*DYN"; then
touch $out
else
echo "ERROR: clickhouse-backup is NOT PIE"
exit 1
fi
'';
};
};
@@ -0,0 +1,13 @@
diff --git a/src/internal/platform/supported.go b/src/internal/platform/supported.go
index f9706a6988..abac42d550 100644
--- a/src/internal/platform/supported.go
+++ b/src/internal/platform/supported.go
@@ -249,7 +253,7 @@ func DefaultPIE(goos, goarch string, isRace bool) bool {
case "darwin":
return true
}
- return false
+ return goarch == "@GOARCH@" && BuildModeSupported("gc", "pie", goos, goarch)
}
// ExecutableHasDWARF reports whether the linked executable includes DWARF
@@ -0,0 +1,44 @@
diff --git a/src/cmd/dist/buildruntime.go b/src/cmd/dist/buildruntime.go
index 87e8867176..dbb635011f 100644
--- a/src/cmd/dist/buildruntime.go
+++ b/src/cmd/dist/buildruntime.go
@@ -62,7 +62,7 @@ func mkbuildcfg(file string) {
fmt.Fprintf(&buf, "const DefaultGORISCV64 = `%s`\n", goriscv64)
fmt.Fprintf(&buf, "const defaultGOEXPERIMENT = `%s`\n", goexperiment)
fmt.Fprintf(&buf, "const defaultGO_EXTLINK_ENABLED = `%s`\n", goextlinkenabled)
- fmt.Fprintf(&buf, "const defaultGO_LDSO = `%s`\n", defaultldso)
+ fmt.Fprintf(&buf, "const DefaultGO_LDSO = `%s`\n", defaultldso)
fmt.Fprintf(&buf, "const version = `%s`\n", findgoversion())
fmt.Fprintf(&buf, "const defaultGOOS = runtime.GOOS\n")
fmt.Fprintf(&buf, "const defaultGOARCH = runtime.GOARCH\n")
diff --git a/src/cmd/link/internal/ld/elf.go b/src/cmd/link/internal/ld/elf.go
index 6ff1d94383..147a7d91c9 100644
--- a/src/cmd/link/internal/ld/elf.go
+++ b/src/cmd/link/internal/ld/elf.go
@@ -1927,8 +1927,12 @@ func asmbElf(ctxt *Link) {
sh.Flags = uint64(elf.SHF_ALLOC)
sh.Addralign = 1
- if interpreter == "" && buildcfg.GOOS == runtime.GOOS && buildcfg.GOARCH == runtime.GOARCH && buildcfg.GO_LDSO != "" {
- interpreter = buildcfg.GO_LDSO
+ if interpreter == "" {
+ if goLdso := os.Getenv("GO_LDSO"); goLdso != "" {
+ interpreter = goLdso
+ } else if buildcfg.GOOS == runtime.GOOS && buildcfg.GOARCH == runtime.GOARCH {
+ interpreter = buildcfg.DefaultGO_LDSO
+ }
}
if interpreter == "" {
diff --git a/src/internal/buildcfg/cfg.go b/src/internal/buildcfg/cfg.go
index 7e4ee365df..8aaa70fb36 100644
--- a/src/internal/buildcfg/cfg.go
+++ b/src/internal/buildcfg/cfg.go
@@ -33,7 +33,6 @@ var (
GORISCV64 = goriscv64()
GOWASM = gowasm()
ToolTags = toolTags()
- GO_LDSO = defaultGO_LDSO
GOFIPS140 = gofips140()
Version = version
)