From d85399b969525dc8d6304deaf5aabec9aa1435f0 Mon Sep 17 00:00:00 2001 From: John Ericson Date: Fri, 21 Jun 2024 09:13:08 -0400 Subject: [PATCH] openbsd: Add static linking support I've had better luck creating statically-linked binaries that work than dynamically-linked ones, so this is needed quite practically. (cherry picked from commit 676df1cf2d5b59632a9f7e36d655e10f6c6d2063) --- doc/stdenv/stdenv.chapter.md | 6 ++++- .../bintools-wrapper/default.nix | 24 +++++++++++-------- pkgs/os-specific/bsd/openbsd/pkgs/csu.nix | 10 ++++++++ .../bsd/openbsd/pkgs/libcMinimal/package.nix | 12 ++++++---- .../bsd/openbsd/pkgs/make-rules/package.nix | 11 ++++++++- .../bsd/openbsd/pkgs/mkDerivation.nix | 1 + pkgs/stdenv/generic/make-derivation.nix | 4 +++- 7 files changed, 50 insertions(+), 18 deletions(-) diff --git a/doc/stdenv/stdenv.chapter.md b/doc/stdenv/stdenv.chapter.md index f2bc7f71de383..ff1e307c2ac27 100644 --- a/doc/stdenv/stdenv.chapter.md +++ b/doc/stdenv/stdenv.chapter.md @@ -1660,7 +1660,11 @@ The following flags are disabled by default and should be enabled with `hardenin #### `pie` {#pie} -This flag is disabled by default for normal `glibc` based NixOS package builds, but enabled by default for `musl` based package builds. +This flag is disabled by default for normal `glibc` based NixOS package builds, but enabled by default for + + - `musl`-based package builds, except on Aarch64 and Aarch32, where there are issues. + + - Statically-linked for OpenBSD builds, where it appears to be required to get a working binary. Adds the `-fPIE` compiler and `-pie` linker options. Position Independent Executables are needed to take advantage of Address Space Layout Randomization, supported by modern kernel versions. While ASLR can already be enforced for data areas in the stack and heap (brk and mmap), the code areas must be compiled as position-independent. Shared libraries already do this with the `pic` flag, so they gain ASLR automatically, but binary .text regions need to be build with `pie` to gain ASLR. When this happens, ROP attacks are much harder since there are no static locations to bounce off of during a memory corruption attack. diff --git a/pkgs/build-support/bintools-wrapper/default.nix b/pkgs/build-support/bintools-wrapper/default.nix index 2a1fe1344e205..952bd85d4b011 100644 --- a/pkgs/build-support/bintools-wrapper/default.nix +++ b/pkgs/build-support/bintools-wrapper/default.nix @@ -45,16 +45,20 @@ "relro" "stackprotector" "strictoverflow" - ] ++ lib.optional (with stdenvNoCC; - # Musl-based platforms will keep "pie", other platforms will not. - # If you change this, make sure to update section `{#sec-hardening-in-nixpkgs}` - # in the nixpkgs manual to inform users about the defaults. - targetPlatform.libc == "musl" - # Except when: - # - static aarch64, where compilation works, but produces segfaulting dynamically linked binaries. - # - static armv7l, where compilation fails. - && !(targetPlatform.isAarch && targetPlatform.isStatic) - ) "pie" + ] ++ lib.optional (with stdenvNoCC; lib.any (x: x) [ + # OpenBSD static linking requires PIE + (with targetPlatform; isOpenBSD && isStatic) + (lib.all (x: x) [ + # Musl-based platforms will keep "pie", other platforms will not. + # If you change this, make sure to update section `{#sec-hardening-in-nixpkgs}` + # in the nixpkgs manual to inform users about the defaults. + (targetPlatform.libc == "musl") + # Except when: + # - static aarch64, where compilation works, but produces segfaulting dynamically linked binaries. + # - static armv7l, where compilation fails. + (!(targetPlatform.isAarch && targetPlatform.isStatic)) + ]) + ]) "pie" # Darwin code signing support utilities , postLinkSignHook ? null, signingUtils ? null diff --git a/pkgs/os-specific/bsd/openbsd/pkgs/csu.nix b/pkgs/os-specific/bsd/openbsd/pkgs/csu.nix index 03a7180425684..34c1183ba8bbc 100644 --- a/pkgs/os-specific/bsd/openbsd/pkgs/csu.nix +++ b/pkgs/os-specific/bsd/openbsd/pkgs/csu.nix @@ -1,6 +1,7 @@ { lib, mkDerivation, + fetchpatch, bsdSetupHook, openbsdSetupHook, makeMinimal, @@ -11,6 +12,15 @@ mkDerivation { noLibc = true; path = "lib/csu"; + patches = [ + # Support for a new NOBLIBSTATIC make variable + (fetchpatch { + name = "nolibstatic-support.patch"; + url = "https://marc.info/?l=openbsd-tech&m=171972639411562&q=raw"; + hash = "sha256-ZMegMq/A/SeFp8fofIyF0AA0IUo/11ZgKxg/UNT4z3E="; + includes = [ "libexec/ld.so/*" ]; + }) + ]; nativeBuildInputs = [ bsdSetupHook openbsdSetupHook diff --git a/pkgs/os-specific/bsd/openbsd/pkgs/libcMinimal/package.nix b/pkgs/os-specific/bsd/openbsd/pkgs/libcMinimal/package.nix index d8d6cc398e0de..94fda2d905715 100644 --- a/pkgs/os-specific/bsd/openbsd/pkgs/libcMinimal/package.nix +++ b/pkgs/os-specific/bsd/openbsd/pkgs/libcMinimal/package.nix @@ -2,6 +2,7 @@ lib, crossLibcStdenv, mkDerivation, + fetchpatch, bsdSetupHook, openbsdSetupHook, makeMinimal, @@ -9,13 +10,11 @@ flex, byacc, gencat, + lorder, + tsort, rpcgen, csu, include, - ctags, - tsort, - llvmPackages, - fetchpatch, }: mkDerivation { @@ -35,9 +34,11 @@ mkDerivation { patches = [ ./netbsd-make-to-lower.patch ./disable-librebuild.patch + # Do not produce ctags, can do that separately. (fetchpatch { + name = "skip-tags.patch"; url = "https://marc.info/?l=openbsd-tech&m=171575286706032&q=raw"; - sha256 = "sha256-2fqabJZLUvXUIWe5WZ4NrTOwgQCXqH49Wo0hAPu5lu0="; + hash = "sha256-2fqabJZLUvXUIWe5WZ4NrTOwgQCXqH49Wo0hAPu5lu0="; }) ]; @@ -47,6 +48,7 @@ mkDerivation { makeMinimal install tsort + lorder gencat ]; diff --git a/pkgs/os-specific/bsd/openbsd/pkgs/make-rules/package.nix b/pkgs/os-specific/bsd/openbsd/pkgs/make-rules/package.nix index fefa1136eb76d..a16448752566e 100644 --- a/pkgs/os-specific/bsd/openbsd/pkgs/make-rules/package.nix +++ b/pkgs/os-specific/bsd/openbsd/pkgs/make-rules/package.nix @@ -14,11 +14,20 @@ mkDerivation { dontBuild = true; patches = [ + # Use `$AR` not hardcoded `ar` (fetchpatch { + name = "use-ar-variable.patch"; url = "https://marc.info/?l=openbsd-tech&m=171575284906018&q=raw"; - sha256 = "sha256-bigxJGbaf9mCmFXxLVzQpnUUaEMMDfF3eZkTXVzd6B8="; + hash = "sha256-bigxJGbaf9mCmFXxLVzQpnUUaEMMDfF3eZkTXVzd6B8="; }) ./netbsd-make-sinclude.patch + # Support for a new NOBLIBSTATIC make variable + (fetchpatch { + name = "nolibstatic-support.patch"; + url = "https://marc.info/?l=openbsd-tech&m=171972639411562&q=raw"; + hash = "sha256-p4izV6ZXkfgJud+ZZU1Wqr5qFuHUzE6qVXM7QnXvV3k="; + includes = [ "share/mk/*" ]; + }) ]; postPatch = '' diff --git a/pkgs/os-specific/bsd/openbsd/pkgs/mkDerivation.nix b/pkgs/os-specific/bsd/openbsd/pkgs/mkDerivation.nix index a238a326f46d5..6ec9ba3429161 100644 --- a/pkgs/os-specific/bsd/openbsd/pkgs/mkDerivation.nix +++ b/pkgs/os-specific/bsd/openbsd/pkgs/mkDerivation.nix @@ -92,6 +92,7 @@ lib.makeOverridable ( installPhase = "includesPhase"; dontBuild = true; } + // lib.optionalAttrs stdenv'.hostPlatform.isStatic { NOLIBSHARED = true; } // attrs ) ) diff --git a/pkgs/stdenv/generic/make-derivation.nix b/pkgs/stdenv/generic/make-derivation.nix index af68bf890ed29..1621307e573c9 100644 --- a/pkgs/stdenv/generic/make-derivation.nix +++ b/pkgs/stdenv/generic/make-derivation.nix @@ -262,7 +262,9 @@ let defaultHardeningFlags = (if stdenv.hasCC then stdenv.cc else {}).defaultHardeningFlags or # fallback safe-ish set of flags - (remove "pie" knownHardeningFlags); + (if with stdenv.hostPlatform; isOpenBSD && isStatic + then knownHardeningFlags # Need pie, in fact + else remove "pie" knownHardeningFlags); enabledHardeningOptions = if builtins.elem "all" hardeningDisable' then []