Merge pull request #133556 from risicle/ris-graphene-hardened-malloc-8

graphene-hardened-malloc: 2 -> 8, overhaul tests

Changed files
+56 -49
nixos
tests
pkgs
development
libraries
graphene-hardened-malloc
+2 -26
nixos/tests/hardened.nix
···
testScript =
let
-
hardened-malloc-tests = pkgs.stdenv.mkDerivation {
-
name = "hardened-malloc-tests-${pkgs.graphene-hardened-malloc.version}";
-
src = pkgs.graphene-hardened-malloc.src;
-
buildPhase = ''
-
cd test/simple-memory-corruption
-
make -j4
-
'';
-
-
installPhase = ''
-
find . -type f -executable -exec install -Dt $out/bin '{}' +
-
'';
-
};
+
hardened-malloc-tests = pkgs.graphene-hardened-malloc.ld-preload-tests;
in
''
machine.wait_for_unit("multi-user.target")
···
machine.fail("systemctl kexec")
-
# Test hardened memory allocator
-
def runMallocTestProg(prog_name, error_text):
-
text = "fatal allocator error: " + error_text
-
if not text in machine.fail(
-
"${hardened-malloc-tests}/bin/"
-
+ prog_name
-
+ " 2>&1"
-
):
-
raise Exception("Hardened malloc does not work for {}".format(error_text))
-
-
with subtest("The hardened memory allocator works"):
-
runMallocTestProg("double_free_large", "invalid free")
-
runMallocTestProg("unaligned_free_small", "invalid unaligned free")
-
runMallocTestProg("write_after_free_small", "detected write after free")
+
machine.succeed("${hardened-malloc-tests}/bin/run-tests")
'';
})
+54 -23
pkgs/development/libraries/graphene-hardened-malloc/default.nix
···
-
{ lib, stdenv, fetchurl }:
+
{ lib, stdenv, fetchurl, python3, runCommand, makeWrapper, stress-ng }:
-
stdenv.mkDerivation rec {
+
lib.fix (self: stdenv.mkDerivation rec {
pname = "graphene-hardened-malloc";
-
version = "2";
+
version = "8";
src = fetchurl {
url = "https://github.com/GrapheneOS/hardened_malloc/archive/${version}.tar.gz";
-
sha256 = "0zsl4vl65ic6lw5rzcjzvcxg8makg683abnwvy60zfap8hvijvjb";
+
sha256 = "0lipyd2pb1bmghkyv9zmg25jwcglj7m281f01zlh3ghz3xlfh0ym";
};
+
doCheck = true;
+
checkInputs = [ python3 ];
+
# these tests cover use as a build-time-linked library
+
checkPhase = ''
+
make test
+
'';
+
installPhase = ''
+
install -Dm444 -t $out/include include/*
install -Dm444 -t $out/lib libhardened_malloc.so
mkdir -p $out/bin
···
separateDebugInfo = true;
-
doInstallCheck = true;
-
installCheckPhase = ''
-
pushd test
-
make
-
$out/bin/preload-hardened-malloc ./offset
+
passthru = {
+
ld-preload-tests = stdenv.mkDerivation {
+
name = "${self.name}-ld-preload-tests";
+
src = self.src;
-
pushd simple-memory-corruption
-
make
+
nativeBuildInputs = [ makeWrapper ];
-
# these tests don't actually appear to generate overflows currently
-
rm read_after_free_small string_overflow eight_byte_overflow_large
+
# reuse the projects tests to cover use with LD_PRELOAD. we have
+
# to convince the test programs to build as though they're naive
+
# standalone executables. this includes disabling tests for
+
# malloc_object_size, which doesn't make sense to use via LD_PRELOAD.
+
buildPhase = ''
+
pushd test/simple-memory-corruption
+
make LDLIBS= LDFLAGS=-Wl,--unresolved-symbols=ignore-all CXXFLAGS=-lstdc++
+
substituteInPlace test_smc.py \
+
--replace 'test_malloc_object_size' 'dont_test_malloc_object_size' \
+
--replace 'test_invalid_malloc_object_size' 'dont_test_invalid_malloc_object_size'
+
popd # test/simple-memory-corruption
+
'';
-
for t in `find . -regex ".*/[a-z_]+"` ; do
-
echo "Running $t..."
-
# the program being aborted (as it should be) would result in an exit code > 128
-
(($out/bin/preload-hardened-malloc $t) && false) \
-
|| (test $? -gt 128 || (echo "$t was not aborted" && false))
-
done
-
popd
+
installPhase = ''
+
mkdir -p $out/test
+
cp -r test/simple-memory-corruption $out/test/simple-memory-corruption
-
popd
-
'';
+
mkdir -p $out/bin
+
makeWrapper ${python3.interpreter} $out/bin/run-tests \
+
--add-flags "-I -m unittest discover --start-directory $out/test/simple-memory-corruption"
+
'';
+
};
+
tests = {
+
ld-preload = runCommand "ld-preload-test-run" {} ''
+
${self}/bin/preload-hardened-malloc ${self.ld-preload-tests}/bin/run-tests
+
touch $out
+
'';
+
# to compensate for the lack of tests of correct normal malloc operation
+
stress = runCommand "stress-test-run" {} ''
+
${self}/bin/preload-hardened-malloc ${stress-ng}/bin/stress-ng \
+
--no-rand-seed \
+
--malloc 8 \
+
--malloc-ops 1000000 \
+
--verify
+
touch $out
+
'';
+
};
+
};
meta = with lib; {
homepage = "https://github.com/GrapheneOS/hardened_malloc";
···
maintainers = with maintainers; [ ris ];
platforms = [ "x86_64-linux" "aarch64-linux" ];
};
-
}
+
})