[go-rpm-macros] Issue #36: Renaming BUILDTAGS and LDFLAGS to include GO prefixes
by Link Dupont
linkdupont reported a new issue against the project: `go-rpm-macros` that you are following:
``
In #34 and #35, it was brought up to rename the `BUILDTAGS` variable to `GOBUILDTAGS` in order to be more explicit about the intended use of the variables and to avoid any potential namespace collision with other variables. I looked into what packages are using `BUILDTAGS` today to figure out how much of an impact a rename like this will have.
As of this writing, the following packages are using `BUILDTAGS` in some capacity:
```
buildah.spec
containernetworking-plugins.spec
cri-tools.spec
go-compilers.spec
golang-github-prometheus-node-exporter.spec
golang-github-prometheus.spec
grafana.spec
hugo.spec
moby-engine.spec
oci-seccomp-bpf-hook.spec
pack.spec
podman.spec
reg.spec
runc.spec
skopeo.spec
snapd.spec
source-to-image.spec
stargz-snapshotter.spec
syncthing.spec
weldr-client.spec
```
And the follow packages use `LDFLAGS`:
```
aerc.spec
age.spec
butane.spec
clash.spec
containerd.spec
doctl.spec
fzf.spec
geoipupdate.spec
git-lfs.spec
golang-github-aliyun-cli.spec
golang-github-colinmarc-hdfs-2.spec
golang-github-haproxytech-dataplaneapi.spec
golang-github-hub.spec
golang-github-jsonnet-bundler.spec
golang-github-magefile-mage.spec
golang-github-prometheus.spec
golang-github-rfjakob-gocryptfs.spec
golang-github-tdewolff-minify.spec
golang-github-theoapp-theo-agent.spec
golang-mvdan-editorconfig.spec
ignition.spec
kiln.spec
micro.spec
open-policy-agent.spec
osbuild-composer.spec
rclone.spec
reg.spec
source-to-image.spec
syncthing.spec
tinygo.spec
vgrep.spec
weldr-client.spec
```
I identified these packages by grepping the contents of the [current spec tarball](https://src.fedoraproject.org/repo/rpm-specs-latest.tar.xz).
To avoid breaking these packages that are currently using `BUILDTAGS` or `LDFLAGS`, there are two possible approaches I see to safely rename the variables:
#### 1. Rebuild everything in a side-tag
Patch `go-rpm-macros` to rename `BUILDTAGS` and `LDFLAGS` to `GOBUILDTAGS` and `GOLDFLAGS` respectively. Then patch the above packages and stage them all in a side-tag to update them in one monolithic Bodhi update.
#### 2. Support both old and new variables at the same time
Patch `go-rpm-macros` to support **both** `BUILDTAGS`/`LDFLAGS` *and* `GOBUILDTAGS`/`GOLDFLAGS` simultaneously. Then patch the above packages over time until everything has been ported over to using `GOBUILDTAGS` and `GOLDFLAGS`, and then drop the old variables from `go-rpm-macros`.
I'm not sure how easy either of these approaches will be. They are both moving targets as new packages are constantly getting added. It might just be a constant effort to try and keep on top of all the patches as new packages come along and patches need to be rebased onto their target's changes.
``
To reply, visit the link below or just reply to this email
https://pagure.io/go-rpm-macros/issue/36
11 months, 2 weeks
[go-rpm-macros] Concerns about buildmode=pie
by Rohan Kumar
Hi,
I've been writing my first RPM spec[0] for one of my projects[1]. After
running rpmbuild, I something peculiar: the resulting binaries were
dynamically-linked according to the "file" command, even though I took
care to never import anything that could enable CGO. The same thing
happened to other non-CGO binaries in the Fedora repos, such as fzf and
shfmt. I managed to isolate the cause to the %gocompilerflags macro
setting -buildmode=pie.
[0] https://git.sr.ht/~seirdy/fedora-specs/tree/master/item/golang-sr-seirdy-...
[1] https://sr.ht/~seirdy/MOAC
The %gobuild macro sets -buildmode=PIE as of F26[2]. However,
-buildmode=PIE doesn't necessarily improve the security of a Go binary.
Russel Cox and Ian Lance Taylor share some information in the
golang-nuts list [3].
[2] https://fedoraproject.org/wiki/Changes/golang-buildmode-pie
[3] https://groups.google.com/g/golang-nuts/c/Jd9tlNc6jUE/m/qp2oyfEEfjQJ
Although the full thread is worth a read, Ian's messages towards the end
were the most relevant.
The view of the Go authors is that PIE makes sense for C/C++ toolchains,
but it isn't as relevant for the Go runtime. The Go runtime uses a fixed
memory address regardless of the build mode. What buildmode=pie does is
introduce position-independent code to make the binary look like a PIE
and satisfy the "PIE-only" requirement of many operating systems. It's a
box-ticker but doesn't actually serve as an exploit mitigation.
PIE is useful when a binary links in C code with CGO, but for Go
packages that make no use of CGO (shfmt, fzf, etc), PIE doesn't offer
tangible security benefits.
What buildmode=pie does accomplish for otherwise-non-CGO bins is the
introduction of additional complexity. Pure-Go bins now need a C
toolchain and are dynlinked against /lib64/ld-linux-%{arch}.so.2. If
anything, this introduces additional attack surface.
One of the main advantages of Linux is the relative stability of its
kernel ABI; we should make use of that by allowing binaries to be
independent of the system libc when reasonable.
Proposal:
Introduce macros for building Go packages without CGO. Unlike the
existing %gobuildflags and %gocompilerflags macros, they should:
- set "-linkmode internal" in -ldflags
- set the variable CGO_ENABLED=0
- set -buildmode=default
- omit extldflags (since no C code and internal linking means no C
toolchain)
This should produce statically-linked Go binaries independent of the
system libc/ld.
A more speculative follow-up idea I had:
Packages could define whether they will need CGO and why: for example,
Caddy would need CGO to use the OS networking stacks (e.g. for DNS),
Hugo would need CGO for building with SASS support via libsass, etc.
Simply importing something like net/http enables CGO by default, but
this is not strictly necessary; while such features would be useful to
Caddy, a hypothetical tiny Go program that simply needs to perform a
basic HTTP request doesn't need the advanced CGO-only net/http package.
--
/Seirdy
1 year, 8 months