-
-
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
&& stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isGnu; | ||
|
||
in | ||
(stdenv.mkDerivation (finalAttrs: | ||
args | ||
|
@@ -175,10 +180,14 @@ in | |
(lib.optional (!finalAttrs.proxyVendor) "-mod=vendor") | ||
++ lib.warnIf (builtins.elem "-trimpath" GOFLAGS) "`-trimpath` is added by default to GOFLAGS by buildGoModule when allowGoReference isn't set to true" | ||
(lib.optional (!allowGoReference) "-trimpath"); | ||
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 commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. ..or string. CGO_ENABLED = "0" is also common There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe 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 commentThe 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 commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. Sounds reasonable 👍 |
||
|
||
# If not set to an explicit value, set the buildid empty for reproducibility. | ||
ldflags = ldflags ++ lib.optional (!lib.any (lib.hasPrefix "-buildid=") ldflags) "-buildid="; | ||
ldflags = ldflags | ||
++ lib.optional (!lib.any (lib.hasPrefix "-buildid=") ldflags) "-buildid=" | ||
++ lib.optional linuxGnuPie "-linkmode=external"; | ||
|
||
configurePhase = args.configurePhase or ('' | ||
runHook preConfigure | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -75,6 +75,12 @@ let | |
|
||
goPath = if goDeps != null then importGodeps { depsFile = goDeps; } ++ extraSrcs | ||
else extraSrcs; | ||
|
||
# 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 | ||
&& stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isGnu; | ||
|
||
package = stdenv.mkDerivation ( | ||
(builtins.removeAttrs args [ "goPackageAliases" "disabled" "extraSrcs"]) // { | ||
|
||
|
@@ -87,16 +93,19 @@ let | |
GOHOSTARCH = go.GOHOSTARCH or null; | ||
GOHOSTOS = go.GOHOSTOS or null; | ||
|
||
inherit CGO_ENABLED enableParallelBuilding; | ||
inherit enableParallelBuilding; | ||
|
||
CGO_ENABLED = linuxGnuPie || CGO_ENABLED; | ||
|
||
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 commentThe reason will be displayed to describe this comment to others. Learn more. Comment shouldn't be removed. |
||
ldflags = ldflags ++ lib.optional (!lib.any (lib.hasPrefix "-buildid=") ldflags) "-buildid="; | ||
ldflags = ldflags | ||
++ lib.optional (!lib.any (lib.hasPrefix "-buildid=") ldflags) "-buildid=" | ||
++ lib.optional linuxGnuPie "-linkmode=external"; | ||
|
||
configurePhase = args.configurePhase or ('' | ||
runHook preConfigure | ||
|
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:
So maybe we should drop or adapt this.