-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
buildGo{Module,Package}: Support PIE mode on Linux #344325
base: staging
Are you sure you want to change the base?
Conversation
In order to support PIE builds on Linux CGO_ENABLED must be set and -linkmode=external added to ldflags, otherwise generated binaries are broken and depend on interpreter paths such as /lib64/ld-linux-x86-64.so.2.
nixpkgs/pkgs/build-support/go/module.nix Lines 201 to 204 in 24959f9
|
Yes, I'm aware. But this is not enough. For example:
|
@@ -63,6 +63,11 @@ let | |||
GO111MODULE = "on"; | |||
GOTOOLCHAIN = "local"; | |||
|
|||
# When building PIE binaries for Linux, we must set CGO_ENABLED and enable external linking. | |||
# Otherwise the emitted binary still depends on ld.so but at wrong path | |||
linuxGnuPie = builtins.elem "pie" stdenv.cc.bintools.defaultHardeningFlags |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this respect hardening{Disable,Enable} that could be set in a package?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those are usually set at runtime in shell. There is currently a check for musl that enables pie. Maybe it can also disable pie if it's not in NIX_HARDENING_ENABLE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That being sad on musl we now would add the flag twice:
if [[ $NIX_HARDENING_ENABLE =~ "pie" ]]; then
export GOFLAGS="-buildmode=pie $GOFLAGS"
fi
So maybe we should drop or adapt this.
inherit CGO_ENABLED enableParallelBuilding GO111MODULE GOTOOLCHAIN; | ||
inherit enableParallelBuilding GO111MODULE GOTOOLCHAIN; | ||
|
||
CGO_ENABLED = linuxGnuPie || CGO_ENABLED; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't evaluate, bool and int.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
..or string. CGO_ENABLED = "0" is also common
|
||
GO111MODULE = "off"; | ||
GOTOOLCHAIN = "local"; | ||
GOFLAGS = GOFLAGS ++ lib.optional (!allowGoReference) "-trimpath" ; | ||
|
||
GOARM = toString (lib.intersectLists [(stdenv.hostPlatform.parsed.cpu.version or "")] ["5" "6" "7"]); | ||
|
||
# If not set to an explicit value, set the buildid empty for reproducibility. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment shouldn't be removed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please revert the changes on buildGoPackage, which is deprecated and will be removed shortly after the 24.11 branch off.
inherit CGO_ENABLED enableParallelBuilding GO111MODULE GOTOOLCHAIN; | ||
inherit enableParallelBuilding GO111MODULE GOTOOLCHAIN; | ||
|
||
CGO_ENABLED = linuxGnuPie || CGO_ENABLED; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm really not sure about this one. As far as I understand, you plan is to enable PIE by default in stdenv, right? So that would mean we are always building with CGO_ENABLED as default. I don't think that's worth it. I'd only enable PIE in case CGO is enabled but respect when CGO is disabled. The security benefit of PIE in Go is minimal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
go programs can make use of C dependencies that are vulnerable in ways that relocation mitigates even if it's hard to write exploitable go code.
This seems important and makes it worth supporting PIE properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My concern is explicitly about enabling CGO to enable PIE (which the line aims to do according to my understanding). I'm not opposing to add PIE for CGO enabled binaries.
However, if CGO_ENABLED = 0, the Go binary cannot link against C libraries. So I would like to not enable PIE in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I misunderstood this badly.
Let me rephrase what you're suggesting to check if I understand:
pie on in stdenv + CGO_ENABLED: binary is compiled with relocation support, linked C libs are protected this way
pie on in stdenv + !CGO_ENABLED: binary is compiled without relocation support, no C libs can be present to be vulnerable
pie off in stdenv: no changes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds reasonable 👍
Description of changes
In order to support PIE builds on Linux CGO_ENABLED must be set and -linkmode=external added to ldflags, otherwise generated binaries are broken and depend on interpreter paths such as /lib64/ld-linux-x86-64.so.2.
This is a part of a larger effort (treewide PIE) documented at #252310
Reproducer:
Things done
Enabled those two options for PIE/Linux/Glibc builds.
nix.conf
? (See Nix manual)sandbox = relaxed
sandbox = true
nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD"
. Note: all changes have to be committed, also see nixpkgs-review usage./result/bin/
)Add a 👍 reaction to pull requests you find important.