cc-wrapper: add support for strictflexarrays1 & strictflexarrays3 hardening flags (#400408)

This commit is contained in:
Philip Taron
2025-05-26 10:46:00 -07:00
committed by GitHub
19 changed files with 544 additions and 75 deletions
+1 -1
View File
@@ -19,7 +19,7 @@
<!-- To avoid merge conflicts, consider adding your item at an arbitrary place in the list instead. -->
- Create the first release note entry in this section!
- New hardening flags, `strictflexarrays1` and `strictflexarrays3` were made available, corresponding to the gcc/clang options `-fstrict-flex-arrays=1` and `-fstrict-flex-arrays=3` respectively.
## Nixpkgs Library {#sec-nixpkgs-release-25.11-lib}
+16
View File
@@ -1620,6 +1620,22 @@ Adds the `-fPIE` compiler and `-pie` linker options. Position Independent Execut
Static libraries need to be compiled with `-fPIE` so that executables can link them in with the `-pie` linker option.
If the libraries lack `-fPIE`, you will get the error `recompile with -fPIE`.
#### `strictflexarrays1` {#strictflexarrays1}
This flag adds the `-fstrict-flex-arrays=1` compiler option, which reduces the cases the compiler treats as "flexible arrays" to those declared with length `[1]`, `[0]` or (the correct) `[]`. This increases the coverage of fortify checks, because such arrays declared as the trailing element of a structure can normally not have their intended length determined by the compiler.
Enabling this flag on packages that still use length declarations of flexible arrays >1 may cause the package to fail to compile citing accesses beyond the bounds of an array or even crash at runtime by detecting an array access as an "overrun". Few projects still use length declarations of flexible arrays >1.
Disabling `strictflexarrays1` implies disablement of `strictflexarrays3`.
#### `strictflexarrays3` {#strictflexarrays3}
This flag adds the `-fstrict-flex-arrays=3` compiler option, which reduces the cases the compiler treats as "flexible arrays" to only those declared with length as (the correct) `[]`. This increases the coverage of fortify checks, because such arrays declared as the trailing element of a structure can normally not have their intended length determined by the compiler.
Enabling this flag on packages that still use non-empty length declarations for flexible arrays may cause the package to fail to compile citing accesses beyond the bounds of an array or even crash at runtime by detecting an array access as an "overrun". Many projects still use such non-empty length declarations for flexible arrays.
Enabling this flag implies enablement of `strictflexarrays1`. Disabling this flag does not imply disablement of `strictflexarrays1`.
#### `shadowstack` {#shadowstack}
Adds the `-fcf-protection=return` compiler option. This enables the Shadow Stack feature supported by some newer processors, which maintains a user-inaccessible copy of the program's stack containing only return-addresses. When returning from a function, the processor compares the return-address value on the two stacks and throws an error if they do not match, considering it a sign of corruption and possible tampering. This should significantly increase the difficulty of ROP attacks.
+33 -1
View File
@@ -10,6 +10,7 @@ for flag in ${NIX_HARDENING_ENABLE_@suffixSalt@-}; do
hardeningEnableMap["$flag"]=1
done
# fortify3 implies fortify enablement - make explicit before
# we filter unsupported flags because unsupporting fortify3
# doesn't mean we should unsupport fortify too
@@ -31,8 +32,31 @@ if [[ -n "${hardeningEnableMap[fortify3]-}" ]]; then
unset -v "hardeningEnableMap['fortify']"
fi
# strictflexarrays3 implies strictflexarrays1 enablement - make explicit before
# we filter unsupported flags because unsupporting strictflexarrays3
# doesn't mean we should unsupport strictflexarrays1 too
if [[ -n "${hardeningEnableMap[strictflexarrays3]-}" ]]; then
hardeningEnableMap["strictflexarrays1"]=1
fi
# Remove unsupported flags.
for flag in @hardening_unsupported_flags@; do
unset -v "hardeningEnableMap[$flag]"
# strictflexarrays1 being unsupported implies strictflexarrays3 is unsupported
if [[ "$flag" = 'strictflexarrays1' ]] ; then
unset -v "hardeningEnableMap['strictflexarrays3']"
fi
done
# now make strictflexarrays1 and strictflexarrays3 mutually exclusive
if [[ -n "${hardeningEnableMap[strictflexarrays3]-}" ]]; then
unset -v "hardeningEnableMap['strictflexarrays1']"
fi
if (( "${NIX_DEBUG:-0}" >= 1 )); then
declare -a allHardeningFlags=(fortify fortify3 shadowstack stackprotector stackclashprotection nostrictaliasing pacret pie pic strictoverflow format trivialautovarinit zerocallusedregs)
declare -a allHardeningFlags=(fortify fortify3 shadowstack stackprotector stackclashprotection nostrictaliasing pacret strictflexarrays1 strictflexarrays3 pie pic strictoverflow format trivialautovarinit zerocallusedregs)
declare -A hardeningDisableMap=()
# Determine which flags were effectively disabled so we can report below.
@@ -79,6 +103,14 @@ for flag in "${!hardeningEnableMap[@]}"; do
if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling shadowstack >&2; fi
hardeningCFlagsBefore+=('-fcf-protection=return')
;;
strictflexarrays1)
if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling strictflexarrays1 >&2; fi
hardeningCFlagsBefore+=('-fstrict-flex-arrays=1')
;;
strictflexarrays3)
if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling strictflexarrays3 >&2; fi
hardeningCFlagsBefore+=('-fstrict-flex-arrays=3')
;;
pacret)
if (( "${NIX_DEBUG:-0}" >= 1 )); then echo HARDENING: enabling pacret >&2; fi
hardeningCFlagsBefore+=('-mbranch-protection=pac-ret')
+2
View File
@@ -25,6 +25,8 @@ stdenv.mkDerivation (finalAttrs: {
depsBuildBuild = [ buildPackages.stdenv.cc ];
buildInputs = [ libedit ];
hardeningDisable = [ "strictflexarrays3" ];
configureFlags = [ "--with-libedit" ];
preConfigure = lib.optional stdenv.hostPlatform.isStatic ''
export LIBS="$(''${PKG_CONFIG:-pkg-config} --libs --static libedit)"
+2
View File
@@ -117,6 +117,8 @@ stdenv.mkDerivation rec {
propagatedNativeBuildInputs = [ setupDebugInfoDirs ];
hardeningDisable = [ "strictflexarrays3" ];
configureFlags =
[
"--program-prefix=eu-" # prevent collisions with binutils
+2
View File
@@ -24,6 +24,8 @@ stdenv.mkDerivation (finalAttrs: {
nativeBuildInputs = [ updateAutotoolsGnuConfigScriptsHook ];
hardeningDisable = [ "strictflexarrays3" ];
configureFlags = [ (lib.enableFeature true "libgdbm-compat") ];
outputs = [
+2
View File
@@ -123,6 +123,8 @@ stdenv.mkDerivation (finalAttrs: {
acl
];
hardeningDisable = [ "strictflexarrays3" ];
configureFlags = lib.optional (!xarSupport) "--without-xml2";
preBuild = lib.optionalString stdenv.hostPlatform.isCygwin ''
+10 -4
View File
@@ -32,10 +32,16 @@ stdenv.mkDerivation rec {
"out"
];
# The CPU Jitter random number generator must not be compiled with
# optimizations and the optimize -O0 pragma only works for gcc.
# The build enables -O2 by default for everything else.
hardeningDisable = lib.optional stdenv.cc.isClang "fortify";
hardeningDisable =
[
"strictflexarrays3"
]
++ lib.optionals stdenv.cc.isClang [
# The CPU Jitter random number generator must not be compiled with
# optimizations and the optimize -O0 pragma only works for gcc.
# The build enables -O2 by default for everything else.
"fortify"
];
depsBuildBuild = [ buildPackages.stdenv.cc ];
+2
View File
@@ -36,6 +36,8 @@ stdenv.mkDerivation (
sed '/BUILD_TIMESTAMP=/s/=.*/=1970-01-01T00:01+0000/' -i ./configure
'';
hardeningDisable = [ "strictflexarrays3" ];
configureFlags = [
# See https://dev.gnupg.org/T6257#164567
"--enable-install-gpg-error-config"
+2
View File
@@ -26,6 +26,8 @@ stdenv.mkDerivation rec {
propagatedBuildInputs = [ libgpg-error ];
depsBuildBuild = [ buildPackages.stdenv.cc ];
hardeningDisable = [ "strictflexarrays3" ];
configureFlags = [ "--with-libgpg-error-prefix=${libgpg-error.dev}" ];
postInstall = ''
+2
View File
@@ -19,6 +19,8 @@ stdenv.mkDerivation rec {
sha256 = "sha256-YKs/XYJ8UItOtSinl28/G9XFVzobFd4ZDKtClQDLXFk=";
};
hardeningDisable = [ "strictflexarrays3" ];
nativeBuildInputs = [
autoreconfHook
pkg-config
+4 -1
View File
@@ -16,7 +16,10 @@ stdenv.mkDerivation rec {
sha256 = "0dxx11knh3nk95p2gg2ak777dd11pr7jx5das2g49l262scrcv83";
};
hardeningDisable = [ "format" ];
hardeningDisable = [
"format"
"strictflexarrays3"
];
patchFlags = [
"-p1"
@@ -428,6 +428,10 @@ pipe
"fortify3"
"trivialautovarinit"
]
++ optionals (!atLeast13) [
"strictflexarrays1"
"strictflexarrays3"
]
++ optional (
!(targetPlatform.isLinux && targetPlatform.isx86_64 && targetPlatform.libc == "glibc")
) "shadowstack"
@@ -299,6 +299,8 @@ stdenv.mkDerivation (
++ lib.optional (
(lib.versionOlder release_version "15") || !(targetPlatform.isx86_64 || targetPlatform.isAarch64)
) "zerocallusedregs"
++ lib.optional (lib.versionOlder release_version "15") "strictflexarrays1"
++ lib.optional (lib.versionOlder release_version "16") "strictflexarrays3"
++ (finalAttrs.passthru.hardeningUnsupportedFlags or [ ]);
};
@@ -64,6 +64,7 @@ in
"fortify"
"pie"
"stackprotector"
"strictflexarrays3"
];
env = (previousAttrs.env or { }) // {
+15 -8
View File
@@ -33,6 +33,7 @@ let
optionalAttrs
optionalString
optionals
pipe
remove
splitString
subtractLists
@@ -159,6 +160,8 @@ let
"format"
"fortify"
"fortify3"
"strictflexarrays1"
"strictflexarrays3"
"shadowstack"
"nostrictaliasing"
"pacret"
@@ -356,14 +359,18 @@ let
) == 0;
dontAddHostSuffix = attrs ? outputHash && !noNonNativeDeps || !stdenv.hasCC;
hardeningDisable' =
if
any (x: x == "fortify") hardeningDisable
# disabling fortify implies fortify3 should also be disabled
then
unique (hardeningDisable ++ [ "fortify3" ])
else
hardeningDisable;
concretizeFlagImplications =
flag: impliesFlags: list:
if any (x: x == flag) list then (list ++ impliesFlags) else list;
hardeningDisable' = unique (
pipe hardeningDisable [
# disabling fortify implies fortify3 should also be disabled
(concretizeFlagImplications "fortify" [ "fortify3" ])
# disabling strictflexarrays1 implies strictflexarrays3 should also be disabled
(concretizeFlagImplications "strictflexarrays1" [ "strictflexarrays3" ])
]
);
defaultHardeningFlags =
(if stdenv.hasCC then stdenv.cc else { }).defaultHardeningFlags or
# fallback safe-ish set of flags
@@ -0,0 +1,33 @@
/* an example that should be protected by FORTIFY_SOURCE=2 but
* only if the appropriate -fstrict-flex-arrays= argument is used
* for the corresponding value used for BUFFER_DEF_SIZE
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct buffer_with_header {
char header[1];
char buffer[BUFFER_DEF_SIZE];
};
int main(int argc, char *argv[]) {
/* use volatile pointer to prevent compiler
* using the outer allocation length with a
* fortified strcpy, which would throw off
* the function-name-sniffing fortify-detecting
* approaches
*/
struct buffer_with_header *volatile b = \
(struct buffer_with_header *)malloc(sizeof(struct buffer_with_header)+1);
/* if there are no arguments, skip the write to allow
* builds with BUFFER_DEF_SIZE=0 to have a case where
* the program passes even with strict protection.
*/
if (argc > 1) {
strcpy(b->buffer, argv[1]);
puts(b->buffer);
}
return 0;
}
+410 -60
View File
@@ -37,6 +37,8 @@ let
f2exampleWithStdEnv = writeCBinWithStdenv ./fortify2-example.c;
f3exampleWithStdEnv = writeCBinWithStdenv ./fortify3-example.c;
flexArrF2ExampleWithStdEnv = writeCBinWithStdenv ./flex-arrays-fortify-example.c;
# for when we need a slightly more complicated program
helloWithStdEnv =
stdenv': env:
@@ -100,16 +102,21 @@ let
{
nativeBuildInputs = [ debian-devscripts ];
buildInputs = [ testBin ];
meta.platforms =
if ignoreStackClashProtection then
lib.platforms.linux # ELF-reliant
else
[ "x86_64-linux" ]; # stackclashprotection test looks for x86-specific instructions
meta = {
platforms =
if ignoreStackClashProtection then
lib.platforms.linux # ELF-reliant
else
[ "x86_64-linux" ]; # stackclashprotection test looks for x86-specific instructions
# musl implementation of fortify undetectable by this means even if present,
# static similarly
broken = (stdenv.hostPlatform.isMusl || stdenv.hostPlatform.isStatic) && !ignoreFortify;
};
}
(
''
if ${lib.optionalString (!expectFailure) "!"} {
hardening-check --nocfprotection \
hardening-check --nocfprotection --nobranchprotection \
${lib.optionalString ignoreBindNow "--nobindnow"} \
${lib.optionalString ignoreFortify "--nofortify"} \
${lib.optionalString ignorePie "--nopie"} \
@@ -141,13 +148,15 @@ let
})
);
fortifyExecTest = fortifyExecTestFull true "012345 7" "0123456 7";
# returning a specific exit code when aborting due to a fortify
# check isn't mandated. so it's better to just ensure that a
# nonzero exit code is returned when we go a single byte beyond
# the buffer, with the example programs being designed to be
# unlikely to genuinely segfault for such a small overflow.
fortifyExecTest =
testBin:
fortifyExecTestFull =
expectProtection: saturatedArgs: oneTooFarArgs: testBin:
runCommand "exec-test"
{
buildInputs = [
@@ -159,9 +168,15 @@ let
(
export PATH=$HOST_PATH
echo "Saturated buffer:" # check program isn't completly broken
test-bin 012345 7
echo "One byte too far:" # eighth byte being the null terminator
(! test-bin 0123456 7) || (echo 'Expected failure, but succeeded!' && exit 1)
test-bin ${saturatedArgs}
echo "One byte too far:" # overflow byte being the null terminator?
(
${if expectProtection then "!" else ""} test-bin ${oneTooFarArgs}
) || (
echo 'Expected ${if expectProtection then "failure" else "success"}, but ${
if expectProtection then "succeeded" else "failed"
}!' && exit 1
)
)
echo "Expected behaviour observed"
touch $out
@@ -259,8 +274,7 @@ nameDrvAfterAttrName (
}
);
# musl implementation undetectable by this means even if present
fortifyExplicitEnabled = brokenIf stdenv.hostPlatform.isMusl (
fortifyExplicitEnabled = (
checkTestBin
(f2exampleWithStdEnv stdenv {
hardeningEnable = [ "fortify" ];
@@ -277,28 +291,23 @@ nameDrvAfterAttrName (
);
# musl implementation is effectively FORTIFY_SOURCE=1-only,
# clang-on-glibc also only appears to support FORTIFY_SOURCE=1 (!)
fortifyExplicitEnabledExecTest =
brokenIf (stdenv.hostPlatform.isMusl || (stdenv.cc.isClang && stdenv.hostPlatform.libc == "glibc"))
(
fortifyExecTest (
f2exampleWithStdEnv stdenv {
hardeningEnable = [ "fortify" ];
}
)
);
fortifyExplicitEnabledExecTest = brokenIf stdenv.hostPlatform.isMusl (
fortifyExecTest (
f2exampleWithStdEnv stdenv {
hardeningEnable = [ "fortify" ];
}
)
);
fortify3ExplicitEnabled =
brokenIf (stdenv.hostPlatform.isMusl || !stdenv.cc.isGNU || lib.versionOlder stdenv.cc.version "12")
(
checkTestBin
(f3exampleWithStdEnv stdenv {
hardeningEnable = [ "fortify3" ];
})
{
ignoreFortify = false;
}
);
fortify3ExplicitEnabled = brokenIf (!stdenv.cc.isGNU || lib.versionOlder stdenv.cc.version "12") (
checkTestBin
(f3exampleWithStdEnv stdenv {
hardeningEnable = [ "fortify3" ];
})
{
ignoreFortify = false;
}
);
# musl implementation is effectively FORTIFY_SOURCE=1-only
fortify3ExplicitEnabledExecTest =
@@ -311,6 +320,128 @@ nameDrvAfterAttrName (
)
);
sfa1explicitEnabled =
checkTestBin
(flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [
"fortify"
"strictflexarrays1"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=7";
};
})
{
ignoreFortify = false;
};
# musl implementation is effectively FORTIFY_SOURCE=1-only
sfa1explicitEnabledExecTest = brokenIf stdenv.hostPlatform.isMusl (
fortifyExecTestFull true "012345" "0123456" (
flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [
"fortify"
"strictflexarrays1"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=7";
};
}
)
);
sfa1explicitEnabledDoesntProtectDefLen1 =
checkTestBin
(flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [
"fortify"
"strictflexarrays1"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=1";
};
})
{
ignoreFortify = false;
expectFailure = true;
};
# musl implementation is effectively FORTIFY_SOURCE=1-only
sfa1explicitEnabledDoesntProtectDefLen1ExecTest = brokenIf stdenv.hostPlatform.isMusl (
fortifyExecTestFull false "''" "0" (
flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [
"fortify"
"strictflexarrays1"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=1";
};
}
)
);
sfa3explicitEnabledProtectsDefLen1 =
checkTestBin
(flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [
"fortify"
"strictflexarrays3"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=1";
};
})
{
ignoreFortify = false;
};
# musl implementation is effectively FORTIFY_SOURCE=1-only
sfa3explicitEnabledProtectsDefLen1ExecTest = brokenIf stdenv.hostPlatform.isMusl (
fortifyExecTestFull true "''" "0" (
flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [
"fortify"
"strictflexarrays3"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=1";
};
}
)
);
sfa3explicitEnabledDoesntProtectCorrectFlex =
checkTestBin
(flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [
"fortify"
"strictflexarrays3"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=";
};
})
{
ignoreFortify = false;
expectFailure = true;
};
# musl implementation is effectively FORTIFY_SOURCE=1-only
sfa3explicitEnabledDoesntProtectCorrectFlexExecTest = brokenIf stdenv.hostPlatform.isMusl (
fortifyExecTestFull false "" "0" (
flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [
"fortify"
"strictflexarrays3"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=";
};
}
)
);
pieExplicitEnabled = brokenIf stdenv.hostPlatform.isStatic (
checkTestBin
(f2exampleWithStdEnv stdenv {
@@ -421,6 +552,99 @@ nameDrvAfterAttrName (
ignoreFortify = false;
};
# musl implementation is effectively FORTIFY_SOURCE=1-only
sfa1explicitDisabled = brokenIf stdenv.hostPlatform.isMusl (
checkTestBin
(flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [ "fortify" ];
hardeningDisable = [ "strictflexarrays1" ];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=7";
};
})
{
ignoreFortify = false;
expectFailure = true;
}
);
sfa1explicitDisabledExecTest = fortifyExecTestFull false "012345" "0123456" (
flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [ "fortify" ];
hardeningDisable = [ "strictflexarrays1" ];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=7";
};
}
);
# musl implementation is effectively FORTIFY_SOURCE=1-only
sfa1explicitDisabledDisablesSfa3 = brokenIf stdenv.hostPlatform.isMusl (
checkTestBin
(flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [
"fortify"
"strictflexarrays3"
];
hardeningDisable = [ "strictflexarrays1" ];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=1";
};
})
{
ignoreFortify = false;
expectFailure = true;
}
);
# musl implementation is effectively FORTIFY_SOURCE=1-only
sfa1explicitDisabledDisablesSfa3ExecTest = brokenIf stdenv.hostPlatform.isMusl (
fortifyExecTestFull false "''" "0" (
flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [
"fortify"
"strictflexarrays3"
];
hardeningDisable = [ "strictflexarrays1" ];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=1";
};
}
)
);
sfa3explicitDisabledDoesntDisableSfa1 =
checkTestBin
(flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [
"fortify"
"strictflexarrays1"
];
hardeningDisable = [ "strictflexarrays3" ];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=7";
};
})
{
ignoreFortify = false;
};
# musl implementation is effectively FORTIFY_SOURCE=1-only
sfa3explicitDisabledDoesntDisableSfa1ExecTest = brokenIf stdenv.hostPlatform.isMusl (
fortifyExecTestFull true "012345" "0123456" (
flexArrF2ExampleWithStdEnv stdenv {
hardeningEnable = [
"fortify"
"strictflexarrays1"
];
hardeningDisable = [ "strictflexarrays3" ];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=7";
};
}
)
);
pieExplicitDisabled = brokenIf (stdenv.hostPlatform.isMusl && stdenv.cc.isClang) (
checkTestBin
(f2exampleWithStdEnv stdenv {
@@ -513,16 +737,14 @@ nameDrvAfterAttrName (
expectFailure = true;
};
# musl implementation undetectable by this means even if present
fortify3StdenvUnsuppDoesntUnsuppFortify1 = brokenIf stdenv.hostPlatform.isMusl (
fortify3StdenvUnsuppDoesntUnsuppFortify1 =
checkTestBin
(f1exampleWithStdEnv (stdenvUnsupport [ "fortify3" ]) {
hardeningEnable = [ "fortify" ];
})
{
ignoreFortify = false;
}
);
};
fortify3StdenvUnsuppDoesntUnsuppFortify1ExecTest = fortifyExecTest (
f1exampleWithStdEnv (stdenvUnsupport [ "fortify3" ]) {
@@ -530,6 +752,90 @@ nameDrvAfterAttrName (
}
);
sfa1StdenvUnsupp =
checkTestBin
(flexArrF2ExampleWithStdEnv
(stdenvUnsupport [
"strictflexarrays1"
"strictflexarrays3"
])
{
hardeningEnable = [
"fortify"
"strictflexarrays1"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=7";
};
}
)
{
ignoreFortify = false;
expectFailure = true;
};
sfa3StdenvUnsupp =
checkTestBin
(flexArrF2ExampleWithStdEnv (stdenvUnsupport [ "strictflexarrays3" ]) {
hardeningEnable = [
"fortify"
"strictflexarrays3"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=1";
};
})
{
ignoreFortify = false;
expectFailure = true;
};
sfa1StdenvUnsuppUnsupportsSfa3 =
checkTestBin
(flexArrF2ExampleWithStdEnv (stdenvUnsupport [ "strictflexarrays1" ]) {
hardeningEnable = [
"fortify"
"strictflexarrays3"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=1";
};
})
{
ignoreFortify = false;
expectFailure = true;
};
sfa3StdenvUnsuppDoesntUnsuppSfa1 =
checkTestBin
(flexArrF2ExampleWithStdEnv (stdenvUnsupport [ "strictflexarrays3" ]) {
hardeningEnable = [
"fortify"
"strictflexarrays1"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=7";
};
})
{
ignoreFortify = false;
};
# musl implementation is effectively FORTIFY_SOURCE=1-only
sfa3StdenvUnsuppDoesntUnsuppSfa1ExecTest = brokenIf stdenv.hostPlatform.isMusl (
fortifyExecTestFull true "012345" "0123456" (
flexArrF2ExampleWithStdEnv (stdenvUnsupport [ "strictflexarrays3" ]) {
hardeningEnable = [
"fortify"
"strictflexarrays1"
];
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=7";
};
}
)
);
stackProtectorStdenvUnsupp =
checkTestBin
(f2exampleWithStdEnv (stdenvUnsupport [ "stackprotector" ]) {
@@ -590,8 +896,7 @@ nameDrvAfterAttrName (
expectFailure = true;
};
# musl implementation undetectable by this means even if present
fortify3EnabledEnvEnablesFortify1 = brokenIf stdenv.hostPlatform.isMusl (
fortify3EnabledEnvEnablesFortify1 =
checkTestBin
(f1exampleWithStdEnv stdenv {
hardeningDisable = [
@@ -604,8 +909,7 @@ nameDrvAfterAttrName (
})
{
ignoreFortify = false;
}
);
};
fortify3EnabledEnvEnablesFortify1ExecTest = fortifyExecTest (
f1exampleWithStdEnv stdenv {
@@ -635,6 +939,58 @@ nameDrvAfterAttrName (
expectFailure = true;
};
sfa3EnabledEnvEnablesSfa1 =
checkTestBin
(flexArrF2ExampleWithStdEnv stdenv {
hardeningDisable = [
"strictflexarrays1"
"strictflexarrays3"
];
postConfigure = ''
export NIX_HARDENING_ENABLE="fortify strictflexarrays3"
'';
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=7";
};
})
{
ignoreFortify = false;
};
sfa3EnabledEnvEnablesSfa1ExecTest = fortifyExecTestFull true "012345" "0123456" (
f1exampleWithStdEnv stdenv {
hardeningDisable = [
"strictflexarrays1"
"strictflexarrays3"
];
postConfigure = ''
export NIX_HARDENING_ENABLE="fortify strictflexarrays3"
'';
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=7";
};
}
);
sfa1EnabledEnvDoesntEnableSfa3 =
checkTestBin
(flexArrF2ExampleWithStdEnv stdenv {
hardeningDisable = [
"strictflexarrays1"
"strictflexarrays3"
];
postConfigure = ''
export NIX_HARDENING_ENABLE="fortify strictflexarrays1"
'';
env = {
TEST_EXTRA_FLAGS = "-DBUFFER_DEF_SIZE=1";
};
})
{
ignoreFortify = false;
expectFailure = true;
};
# NIX_HARDENING_ENABLE can't enable an unsupported feature
stackProtectorUnsupportedEnabledEnv =
checkTestBin
@@ -651,8 +1007,7 @@ nameDrvAfterAttrName (
# current implementation prevents the command-line from disabling
# fortify if cc-wrapper is enabling it.
# undetectable by this means on static even if present
fortify1ExplicitEnabledCmdlineDisabled = brokenIf stdenv.hostPlatform.isStatic (
fortify1ExplicitEnabledCmdlineDisabled =
checkTestBin
(f1exampleWithStdEnv stdenv {
hardeningEnable = [ "fortify" ];
@@ -663,27 +1018,22 @@ nameDrvAfterAttrName (
{
ignoreFortify = false;
expectFailure = false;
}
);
};
# current implementation doesn't force-disable fortify if
# command-line enables it even if we use hardeningDisable.
# musl implementation undetectable by this means even if present
fortify1ExplicitDisabledCmdlineEnabled =
brokenIf (stdenv.hostPlatform.isMusl || stdenv.hostPlatform.isStatic)
(
checkTestBin
(f1exampleWithStdEnv stdenv {
hardeningDisable = [ "fortify" ];
postConfigure = ''
export TEST_EXTRA_FLAGS='-D_FORTIFY_SOURCE=1'
'';
})
{
ignoreFortify = false;
}
);
checkTestBin
(f1exampleWithStdEnv stdenv {
hardeningDisable = [ "fortify" ];
postConfigure = ''
export TEST_EXTRA_FLAGS='-D_FORTIFY_SOURCE=1'
'';
})
{
ignoreFortify = false;
};
fortify1ExplicitDisabledCmdlineEnabledExecTest = fortifyExecTest (
f1exampleWithStdEnv stdenv {
+1
View File
@@ -104,6 +104,7 @@ self: super: {
stdenv = super'.withDefaultHardeningFlags (
super'.stdenv.cc.defaultHardeningFlags
++ [
"strictflexarrays1"
"shadowstack"
"nostrictaliasing"
"pacret"