Skip to content
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

hardening flags: add FORTIFY_SOURCE=3 support #212498

Merged
merged 6 commits into from
Feb 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions pkgs/build-support/cc-wrapper/add-hardening.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,17 @@ done
# Remove unsupported flags.
for flag in @hardening_unsupported_flags@; do
unset -v "hardeningEnableMap[$flag]"
# fortify being unsupported implies fortify3 is unsupported
if [[ "$flag" = 'fortify' ]] ; then
unset -v "hardeningEnableMap['fortify3']"
fi
done

# make fortify and fortify3 mutually exclusive
if [[ -z "${hardeningEnableMap[fortify3]-}" ]]; then
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I've got the sense of this flipped. This should be -n shouldn't it?

unset -v "hardeningEnableMap['fortify']"
fi
Comment on lines +22 to +24
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I read it correctly it unsets fortify if fortify3 is not present (i.e. always).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Snap. See #217394


if (( "${NIX_DEBUG:-0}" >= 1 )); then
declare -a allHardeningFlags=(fortify stackprotector pie pic strictoverflow format)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should add fortify3 flag here to avoid ignorance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes probably I think the first time I scanned this I assumed it was another default setting, not just debugging output.

declare -A hardeningDisableMap=()
Expand All @@ -36,11 +45,23 @@ fi

for flag in "${!hardeningEnableMap[@]}"; do
case $flag in
fortify)
if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling fortify >&2; fi
fortify | fortify3)
# Use -U_FORTIFY_SOURCE to avoid warnings on toolchains that explicitly
# set -D_FORTIFY_SOURCE=0 (like 'clang -fsanitize=address').
hardeningCFlags+=('-O2' '-U_FORTIFY_SOURCE' '-D_FORTIFY_SOURCE=2')
hardeningCFlags+=('-O2' '-U_FORTIFY_SOURCE')
case $flag in
fortify)
if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling fortify >&2; fi
hardeningCFlags+=('-D_FORTIFY_SOURCE=2')
;;
fortify3)
if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling fortify3 >&2; fi
hardeningCFlags+=('-D_FORTIFY_SOURCE=3')
;;
*)
# Ignore unsupported.
;;
esac
;;
stackprotector)
if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling stackprotector >&2; fi
Expand Down
1 change: 1 addition & 0 deletions pkgs/development/compilers/gcc/10/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ stdenv.mkDerivation ({
passthru = {
inherit langC langCC langObjC langObjCpp langAda langFortran langGo langD version;
isGNU = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

enableParallelBuilding = true;
Expand Down
1 change: 1 addition & 0 deletions pkgs/development/compilers/gcc/11/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ stdenv.mkDerivation ({
passthru = {
inherit langC langCC langObjC langObjCpp langAda langFortran langGo langD version;
isGNU = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

enableParallelBuilding = true;
Expand Down
2 changes: 1 addition & 1 deletion pkgs/development/compilers/gcc/4.8/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ stdenv.mkDerivation ({
passthru = {
inherit langC langCC langObjC langObjCpp langFortran langGo version;
isGNU = true;
hardeningUnsupportedFlags = [ "stackprotector" ];
hardeningUnsupportedFlags = [ "stackprotector" "fortify3" ];
};

enableParallelBuilding = true;
Expand Down
1 change: 1 addition & 0 deletions pkgs/development/compilers/gcc/4.9/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ stdenv.mkDerivation ({
passthru = {
inherit langC langCC langObjC langObjCpp langFortran langGo version;
isGNU = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

enableParallelBuilding = true;
Expand Down
1 change: 1 addition & 0 deletions pkgs/development/compilers/gcc/6/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ stdenv.mkDerivation ({
passthru = {
inherit langC langCC langObjC langObjCpp langFortran langAda langGo version;
isGNU = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

enableParallelBuilding = true;
Expand Down
1 change: 1 addition & 0 deletions pkgs/development/compilers/gcc/7/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ stdenv.mkDerivation ({
passthru = {
inherit langC langCC langObjC langObjCpp langFortran langGo version;
isGNU = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

enableParallelBuilding = true;
Expand Down
1 change: 1 addition & 0 deletions pkgs/development/compilers/gcc/8/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ stdenv.mkDerivation ({
passthru = {
inherit langC langCC langObjC langObjCpp langFortran langGo version;
isGNU = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

enableParallelBuilding = true;
Expand Down
1 change: 1 addition & 0 deletions pkgs/development/compilers/gcc/9/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ stdenv.mkDerivation ({
passthru = {
inherit langC langCC langObjC langObjCpp langAda langFortran langGo langD version;
isGNU = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

enableParallelBuilding = true;
Expand Down
3 changes: 2 additions & 1 deletion pkgs/development/compilers/llvm/10/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ let
'';

passthru = {
isClang = true;
inherit libllvm;
isClang = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

meta = llvm_meta // {
Expand Down
3 changes: 2 additions & 1 deletion pkgs/development/compilers/llvm/11/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ let
'';

passthru = {
isClang = true;
inherit libllvm;
isClang = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

meta = llvm_meta // {
Expand Down
3 changes: 2 additions & 1 deletion pkgs/development/compilers/llvm/12/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,9 @@ let
'';

passthru = {
isClang = true;
inherit libllvm;
isClang = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

meta = llvm_meta // {
Expand Down
3 changes: 2 additions & 1 deletion pkgs/development/compilers/llvm/13/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ let
'';

passthru = {
isClang = true;
inherit libllvm;
isClang = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

meta = llvm_meta // {
Expand Down
3 changes: 2 additions & 1 deletion pkgs/development/compilers/llvm/14/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ let
'';

passthru = {
isClang = true;
inherit libllvm;
isClang = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

meta = llvm_meta // {
Expand Down
3 changes: 2 additions & 1 deletion pkgs/development/compilers/llvm/5/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ let
'';

passthru = {
isClang = true;
inherit libllvm;
isClang = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

meta = llvm_meta // {
Expand Down
3 changes: 2 additions & 1 deletion pkgs/development/compilers/llvm/6/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ let
'';

passthru = {
isClang = true;
inherit libllvm;
isClang = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

meta = llvm_meta // {
Expand Down
3 changes: 2 additions & 1 deletion pkgs/development/compilers/llvm/7/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ let
'';

passthru = {
isClang = true;
inherit libllvm;
isClang = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

meta = llvm_meta // {
Expand Down
3 changes: 2 additions & 1 deletion pkgs/development/compilers/llvm/8/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,9 @@ let
'';

passthru = {
isClang = true;
inherit libllvm;
isClang = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

meta = llvm_meta // {
Expand Down
3 changes: 2 additions & 1 deletion pkgs/development/compilers/llvm/9/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,9 @@ let
'';

passthru = {
isClang = true;
inherit libllvm;
isClang = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

meta = llvm_meta // {
Expand Down
3 changes: 2 additions & 1 deletion pkgs/development/compilers/llvm/git/clang/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,9 @@ let
'';

passthru = {
isClang = true;
inherit libllvm;
isClang = true;
hardeningUnsupportedFlags = [ "fortify3" ];
};

meta = llvm_meta // {
Expand Down
3 changes: 3 additions & 0 deletions pkgs/development/libraries/acl/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ stdenv.mkDerivation rec {
nativeBuildInputs = [ gettext ];
buildInputs = [ attr ];

# causes failures in coreutils test suite
hardeningDisable = [ "fortify3" ];

# Upstream use C++-style comments in C code. Remove them.
# This comment breaks compilation if too strict gcc flags are used.
patchPhase = ''
Expand Down
1 change: 1 addition & 0 deletions pkgs/development/libraries/libffi/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ stdenv.mkDerivation rec {

preCheck = ''
# The tests use -O0 which is not compatible with -D_FORTIFY_SOURCE.
NIX_HARDENING_ENABLE=''${NIX_HARDENING_ENABLE/fortify3/}
NIX_HARDENING_ENABLE=''${NIX_HARDENING_ENABLE/fortify/}
'';

Expand Down
28 changes: 18 additions & 10 deletions pkgs/stdenv/generic/make-derivation.nix
Original file line number Diff line number Diff line change
Expand Up @@ -178,21 +178,29 @@ let
++ buildInputs ++ propagatedBuildInputs
++ depsTargetTarget ++ depsTargetTargetPropagated) == 0;
dontAddHostSuffix = attrs ? outputHash && !noNonNativeDeps || !stdenv.hasCC;
supportedHardeningFlags = [ "fortify" "stackprotector" "pie" "pic" "strictoverflow" "format" "relro" "bindnow" ];

hardeningDisable' = if lib.any (x: x == "fortify") hardeningDisable
# disabling fortify implies fortify3 should also be disabled
then lib.unique (hardeningDisable ++ [ "fortify3" ])
else hardeningDisable;
supportedHardeningFlags = [ "fortify" "fortify3" "stackprotector" "pie" "pic" "strictoverflow" "format" "relro" "bindnow" ];
# 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.
defaultHardeningFlags = if stdenv.hostPlatform.isMusl &&
# Except when:
# - static aarch64, where compilation works, but produces segfaulting dynamically linked binaries.
# - static armv7l, where compilation fails.
!(stdenv.hostPlatform.isAarch && stdenv.hostPlatform.isStatic)
then supportedHardeningFlags
else lib.remove "pie" supportedHardeningFlags;
defaultHardeningFlags = let
# not ready for this by default
supportedHardeningFlags' = lib.remove "fortify3" supportedHardeningFlags;
in if stdenv.hostPlatform.isMusl &&
# Except when:
# - static aarch64, where compilation works, but produces segfaulting dynamically linked binaries.
# - static armv7l, where compilation fails.
!(stdenv.hostPlatform.isAarch && stdenv.hostPlatform.isStatic)
then supportedHardeningFlags'
else lib.remove "pie" supportedHardeningFlags';
enabledHardeningOptions =
if builtins.elem "all" hardeningDisable
if builtins.elem "all" hardeningDisable'
then []
else lib.subtractLists hardeningDisable (defaultHardeningFlags ++ hardeningEnable);
else lib.subtractLists hardeningDisable' (defaultHardeningFlags ++ hardeningEnable);
# hardeningDisable additionally supports "all".
erroneousHardeningFlags = lib.subtractLists supportedHardeningFlags (hardeningEnable ++ lib.remove "all" hardeningDisable);

Expand Down
1 change: 1 addition & 0 deletions pkgs/stdenv/linux/bootstrap-tools-musl/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ derivation ({
langC = true;
langCC = true;
isGNU = true;
hardeningUnsupportedFlags = [ "fortify3" ];
} // extraAttrs)
1 change: 1 addition & 0 deletions pkgs/stdenv/linux/bootstrap-tools/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ derivation ({
langC = true;
langCC = true;
isGNU = true;
hardeningUnsupportedFlags = [ "fortify3" ];
} // extraAttrs)