Repository navigation
Description
What version of Go are you using (go version)?
$ go version go version go1.20 linux/amd64
Does this issue reproduce with the latest release?
Yes, it even reproduces when building go off of main.
From looking at the code, it seems like all versions of go should be affected.
What operating system and processor architecture are you using (go env)?
go env Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/james/.cache/go-build" GOENV="/home/james/.config/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/home/james/pkg/mod" GONOPROXY="" GONOSUMDB="" GOOS="linux" GOPATH="/home/james" GOPRIVATE="" GOPROXY="https://proxy.golang.org,direct" GOROOT="/opt/px_dev/tools/golang" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/opt/px_dev/tools/golang/pkg/tool/linux_amd64" GOVCS="" GOVERSION="go1.20" GCCGO="gccgo" GOAMD64="v1" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" GOMOD="/dev/null" GOWORK="" CGO_CFLAGS="-O2 -g" CGO_CPPFLAGS="" CGO_CXXFLAGS="-O2 -g" CGO_FFLAGS="-O2 -g" CGO_LDFLAGS="-O2 -g" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build2321536912=/tmp/go-build -gno-record-gcc-switches"
What did you do?
I created the following script to reproduce the exact issue I'm seeing.
repro.sh
#!/bin/bash -e
go="go"
if [[ "$USE_DEV_GO" = "1" ]]; then
go="$(pwd)/bin/go"
fi
tmpdir="$(mktemp -d)"
pushd "${tmpdir}" &>/dev/null
cleanup() {
rm -rf "${tmpdir}"
}
trap cleanup ERR
trap cleanup EXIT
cat <<EOF > trivial.go
package main
func main() {}
EOF
cat <<EOF > mycompiler.sh
#!/bin/bash
clang "\$@"
EOF
chmod +x mycompiler.sh
export CGO_ENABLED=1
"${go}" build -ldflags '-extld ./mycompiler.sh -linkmode=external -buildmode=exe -v' trivial.go 2>&1 | tee -a build_out
host_link="$(grep "host link:" build_out)"
if (echo "${host_link}" | grep -- '-no-pie') || (echo "${host_link}" | grep -- '-nopie'); then
echo "Host link has -no-pie or -nopie"
else
echo "Host link missing expected -no-pie or -nopie"
exit 10
fi
cleanupRan ./repro.sh. Also ran USE_DEV_GO=1 ./repro.sh inside of the go repository after running ./all.bash off of main, to test against main.
What did you expect to see?
./repro.sh to not return an error code.
What did you see instead?
./repro.sh returns an error code because -no-pie or -nopie are not added to the external link flags.
The way that the linkerFlagSupported function works, means that if -extld or -extldflags reference relative paths they can cause linkerFlagSupported to return false, leading linker flags to not be added when they should be. In my repro script, this manifests itself in -no-pie not getting added to the external link flags, which can cause downstream issues. For example, when using bazelbuild/rules_go with a relative compiler path and with a compiler that defaults to PIE, the built go binaries end up segfaulting because go was compiled expecting to be run as a static binary but the external linker links it as PIE.
The repro script I provided is just one example of issues with linkerFlagSupported being run outside of the current working directory, but you could for example also have a relative path in -extldflags say --sysroot=relative/path/to/sysroot.
The fix is pretty simple, linkerFlagSupported should be run in the current working directory instead of inside the created temporary directory. I will put out a PR shortly.
Activity
gopherbot commentedon May 3, 2023
Change https://go.dev/cl/491796 mentions this issue:
cmd/link: fix checks for supported linker flags with relative paths.[-]cmd/link: relative paths are not respected when checking supported linker flags.[/-][+]cmd/link: relative paths are not respected when checking supported linker flags[/+]cmd/link: fix checks for supported linker flags with relative paths.