diff options
author | Robert Scott <code@humanleg.org.uk> | 2019-12-29 01:52:31 +0000 |
---|---|---|
committer | Robert Scott <code@humanleg.org.uk> | 2020-04-18 19:52:11 +0100 |
commit | fbc11b4f025d95f1b3116ec4b594c0e558f46e90 (patch) | |
tree | a33f611d1255c3c342b1925d29bfc273fc44e03a /pkgs/tools/security/aflplusplus | |
parent | cd3bc38f40db28c16e631825a0adf6f21e80b88c (diff) |
aflplusplus: init at 2.59c
Diffstat (limited to 'pkgs/tools/security/aflplusplus')
-rw-r--r-- | pkgs/tools/security/aflplusplus/default.nix | 138 | ||||
-rw-r--r-- | pkgs/tools/security/aflplusplus/libdislocator.nix | 35 | ||||
-rw-r--r-- | pkgs/tools/security/aflplusplus/libtokencap.nix | 31 | ||||
-rw-r--r-- | pkgs/tools/security/aflplusplus/qemu-no-etc-install.patch | 13 | ||||
-rw-r--r-- | pkgs/tools/security/aflplusplus/qemu.nix | 77 |
5 files changed, 294 insertions, 0 deletions
diff --git a/pkgs/tools/security/aflplusplus/default.nix b/pkgs/tools/security/aflplusplus/default.nix new file mode 100644 index 0000000000000..a52ea88950c09 --- /dev/null +++ b/pkgs/tools/security/aflplusplus/default.nix @@ -0,0 +1,138 @@ +{ stdenv, fetchFromGitHub, callPackage, makeWrapper +, clang, llvm, gcc, which, libcgroup, python, perl, gmp +, wine ? null +}: + +# wine fuzzing is only known to work for win32 binaries, and using a mixture of +# 32 and 64-bit libraries ... complicates things, so it's recommended to build +# a full 32bit version of this package if you want to do wine fuzzing +assert (wine != null) -> (stdenv.targetPlatform.system == "i686-linux"); + +let + aflplusplus-qemu = callPackage ./qemu.nix { inherit aflplusplus; }; + qemu-exe-name = if stdenv.targetPlatform.system == "x86_64-linux" then "qemu-x86_64" + else if stdenv.targetPlatform.system == "i686-linux" then "qemu-i386" + else throw "aflplusplus: no support for ${stdenv.targetPlatform.system}!"; + libdislocator = callPackage ./libdislocator.nix { inherit aflplusplus; }; + libtokencap = callPackage ./libtokencap.nix { inherit aflplusplus; }; + aflplusplus = stdenv.mkDerivation rec { + pname = "aflplusplus"; + version = "2.59c"; + + src = fetchFromGitHub { + owner = "vanhauser-thc"; + repo = "AFLplusplus"; + rev = version; + sha256 = "1ik33ifk4n96762iv1h4kl4jf9yvsq2hgs097wkiy589siw44g5r"; + }; + enableParallelBuilding = true; + + # Note: libcgroup isn't needed for building, just for the afl-cgroup + # script. + nativeBuildInputs = [ makeWrapper which ]; + buildInputs = [ llvm python gmp ] + ++ stdenv.lib.optional (wine != null) python.pkgs.wrapPython; + + makeFlags = [ "PREFIX=$(out)" ]; + buildPhase = '' + common="$makeFlags -j$NIX_BUILD_CORES" + make all $common + make radamsa $common + make -C gcc_plugin CC=${gcc}/bin/gcc CXX=${gcc}/bin/g++ $common + make -C llvm_mode $common + make -C qemu_mode/libcompcov $common + make -C qemu_mode/unsigaction $common + ''; + + postInstall = '' + # the makefile neglects to install unsigaction + cp qemu_mode/unsigaction/unsigaction*.so $out/lib/afl/ + + # Install the custom QEMU emulator for binary blob fuzzing. + cp ${aflplusplus-qemu}/bin/${qemu-exe-name} $out/bin/afl-qemu-trace + + # give user a convenient way of accessing libcompconv.so, libdislocator.so, libtokencap.so + cat > $out/bin/get-afl-qemu-libcompcov-so <<END + #!${stdenv.shell} + echo $out/lib/afl/libcompcov.so + END + chmod +x $out/bin/get-afl-qemu-libcompcov-so + cp ${libdislocator}/bin/get-libdislocator-so $out/bin/ + cp ${libtokencap}/bin/get-libtokencap-so $out/bin/ + + # Install the cgroups wrapper for asan-based fuzzing. + cp experimental/asan_cgroups/limit_memory.sh $out/bin/afl-cgroup + chmod +x $out/bin/afl-cgroup + substituteInPlace $out/bin/afl-cgroup \ + --replace "cgcreate" "${libcgroup}/bin/cgcreate" \ + --replace "cgexec" "${libcgroup}/bin/cgexec" \ + --replace "cgdelete" "${libcgroup}/bin/cgdelete" + + # Patch shebangs before wrapping + patchShebangs $out/bin + + # Wrap afl-clang-fast(++) with a *different* AFL_PATH, because it + # has totally different semantics in that case(?) - and also set a + # proper AFL_CC and AFL_CXX so we don't pick up the wrong one out + # of $PATH. + # first though we need to replace the afl-clang-fast++ symlink with + # a real copy to prevent wrapProgram skipping the symlink and confusing + # nix's cc wrapper + rm $out/bin/afl-clang-fast++ + cp $out/bin/afl-clang-fast $out/bin/afl-clang-fast++ + for x in $out/bin/afl-clang-fast $out/bin/afl-clang-fast++; do + wrapProgram $x \ + --set-default AFL_PATH "$out/lib/afl" \ + --run 'export AFL_CC=''${AFL_CC:-${clang}/bin/clang} AFL_CXX=''${AFL_CXX:-${clang}/bin/clang++}' + done + # do similar for afl-gcc and afl-gcc-fast + for x in $out/bin/afl-gcc $out/bin/afl-gcc-fast; do + wrapProgram $x \ + --set-default AFL_PATH "$out/lib/afl" \ + --run 'export AFL_CC=''${AFL_CC:-${gcc}/bin/gcc} AFL_CXX=''${AFL_CXX:-${gcc}/bin/g++}' + done + '' + stdenv.lib.optionalString (wine != null) '' + substitute afl-wine-trace $out/bin/afl-wine-trace \ + --replace "qemu_mode/unsigaction" "$out/lib/afl" + chmod +x $out/bin/afl-wine-trace + + # qemu needs to be fed ELFs, not wrapper scripts, so we have to cheat a bit if we + # detect a wrapped wine + for winePath in ${wine}/bin/.wine ${wine}/bin/wine; do + if [ -x $winePath ]; then break; fi + done + makeWrapperArgs="--set-default 'AFL_WINE_PATH' '$winePath'" \ + wrapPythonProgramsIn $out/bin ${python.pkgs.pefile} + ''; + + installCheckInputs = [ perl ]; + doInstallCheck = true; + installCheckPhase = '' + # replace references to tools in build directory with references to installed locations + substituteInPlace test/test.sh \ + --replace '`which gcc`' "" \ + --replace '../libcompcov.so' '`$out/bin/get-afl-qemu-libcompcov-so`' \ + --replace '../libdislocator.so' '`$out/bin/get-libdislocator-so`' \ + --replace '../libtokencap.so' '`$out/bin/get-libtokencap-so`' + perl -pi -e 's|(?<=\s)gcc(?=\s)|${gcc}/bin/gcc|g' test/test.sh + perl -pi -e 's|(\.\./)(\S+?)(?<!\.c)(?<!\.s?o)(?=\s)|\$out/bin/\2|g' test/test.sh + cd test && ./test.sh + ''; + + passthru = { + inherit libdislocator libtokencap; + qemu = aflplusplus-qemu; + }; + + meta = { + description = '' + AFL++ is a heavily enhanced version of AFL, incorporating many features and + improvements from the community. + ''; + homepage = "https://github.com/vanhauser-thc/AFLplusplus"; + license = stdenv.lib.licenses.asl20; + platforms = ["x86_64-linux" "i686-linux"]; + maintainers = with stdenv.lib.maintainers; [ ris ]; + }; + }; +in aflplusplus diff --git a/pkgs/tools/security/aflplusplus/libdislocator.nix b/pkgs/tools/security/aflplusplus/libdislocator.nix new file mode 100644 index 0000000000000..d1d9dad6c5bc6 --- /dev/null +++ b/pkgs/tools/security/aflplusplus/libdislocator.nix @@ -0,0 +1,35 @@ +{ stdenv, aflplusplus}: + +stdenv.mkDerivation { + version = stdenv.lib.getVersion aflplusplus; + pname = "libdislocator"; + + src = aflplusplus.src; + postUnpack = "chmod -R +w ${aflplusplus.src.name}"; + sourceRoot = "${aflplusplus.src.name}/libdislocator"; + + makeFlags = [ "PREFIX=$(out)" ]; + + preInstall = '' + mkdir -p $out/lib/afl + ''; + postInstall = '' + mkdir $out/bin + cat > $out/bin/get-libdislocator-so <<END + #!${stdenv.shell} + echo $out/lib/afl/libdislocator.so + END + chmod +x $out/bin/get-libdislocator-so + ''; + + meta = with stdenv.lib; { + homepage = "https://github.com/vanhauser-thc/AFLplusplus"; + description = '' + Drop-in replacement for the libc allocator which improves + the odds of bumping into heap-related security bugs in + several ways. + ''; + license = stdenv.lib.licenses.asl20; + maintainers = with maintainers; [ ris ]; + }; +} diff --git a/pkgs/tools/security/aflplusplus/libtokencap.nix b/pkgs/tools/security/aflplusplus/libtokencap.nix new file mode 100644 index 0000000000000..830708227e31f --- /dev/null +++ b/pkgs/tools/security/aflplusplus/libtokencap.nix @@ -0,0 +1,31 @@ +{ stdenv, aflplusplus}: + +stdenv.mkDerivation { + version = stdenv.lib.getVersion aflplusplus; + pname = "libtokencap"; + + src = aflplusplus.src; + postUnpack = "chmod -R +w ${aflplusplus.src.name}"; + sourceRoot = "${aflplusplus.src.name}/libtokencap"; + + makeFlags = [ "PREFIX=$(out)" ]; + + preInstall = '' + mkdir -p $out/lib/afl + ''; + postInstall = '' + mkdir $out/bin + cat > $out/bin/get-libtokencap-so <<END + #!${stdenv.shell} + echo $out/lib/afl/libtokencap.so + END + chmod +x $out/bin/get-libtokencap-so + ''; + + meta = with stdenv.lib; { + homepage = "https://github.com/vanhauser-thc/AFLplusplus"; + description = "strcmp & memcmp token capture library"; + license = stdenv.lib.licenses.asl20; + maintainers = with maintainers; [ ris ]; + }; +} diff --git a/pkgs/tools/security/aflplusplus/qemu-no-etc-install.patch b/pkgs/tools/security/aflplusplus/qemu-no-etc-install.patch new file mode 100644 index 0000000000000..5dfbfd780f1ca --- /dev/null +++ b/pkgs/tools/security/aflplusplus/qemu-no-etc-install.patch @@ -0,0 +1,13 @@ +diff --git a/Makefile b/Makefile +index d6b9dc1..ce7c493 100644 +--- a/Makefile ++++ b/Makefile +@@ -601,7 +601,7 @@ install-localstatedir: + endif + + +-install: all $(if $(BUILD_DOCS),install-doc) install-datadir install-localstatedir ++install: all $(if $(BUILD_DOCS),install-doc) install-datadir + ifneq ($(TOOLS),) + $(call install-prog,$(subst qemu-ga,qemu-ga$(EXESUF),$(TOOLS)),$(DESTDIR)$(bindir)) + endif diff --git a/pkgs/tools/security/aflplusplus/qemu.nix b/pkgs/tools/security/aflplusplus/qemu.nix new file mode 100644 index 0000000000000..202657dac9ae5 --- /dev/null +++ b/pkgs/tools/security/aflplusplus/qemu.nix @@ -0,0 +1,77 @@ +{ stdenv, fetchurl, aflplusplus, python2, zlib, pkgconfig, glib, perl +, texinfo, libuuid, flex, bison, pixman, autoconf +}: + +with stdenv.lib; + +let + qemuName = "qemu-3.1.0"; + cpuTarget = if stdenv.targetPlatform.system == "x86_64-linux" then "x86_64-linux-user" + else if stdenv.targetPlatform.system == "i686-linux" then "i386-linux-user" + else throw "aflplusplus: no support for ${stdenv.targetPlatform.system}!"; +in +stdenv.mkDerivation { + name = "aflplusplus-${qemuName}"; + + srcs = [ + (fetchurl { + url = "http://wiki.qemu.org/download/${qemuName}.tar.bz2"; + sha256 = "08frr1fdjx8qcfh3fafn10kibdwbvkqqvfl7hpqbm7i9dg4f1zlq"; + }) + aflplusplus.src + ]; + + sourceRoot = qemuName; + + postUnpack = '' + chmod -R +w ${aflplusplus.src.name} + for f in ${aflplusplus.src.name}/qemu_mode/patches/* ; do + sed -E -i 's|(\.\./)+patches/([a-z-]+\.h)|\2|g' $f + sed -E -i 's|\.\./\.\./config\.h|afl-config.h|g' $f + done + cp ${aflplusplus.src.name}/qemu_mode/patches/*.h $sourceRoot/ + cp ${aflplusplus.src.name}/types.h $sourceRoot/afl-types.h + substitute ${aflplusplus.src.name}/config.h $sourceRoot/afl-config.h \ + --replace "types.h" "afl-types.h" + + cat ${aflplusplus.src.name}/qemu_mode/patches/*.diff > all.patch + ''; + + nativeBuildInputs = [ + python2 perl pkgconfig flex bison autoconf texinfo + ]; + + buildInputs = [ + zlib glib pixman libuuid + ]; + + enableParallelBuilding = true; + + patches = [ + # patches extracted from aflplusplus source + "../all.patch" + # nix-specific patches to make installation more well-behaved + ./qemu-no-etc-install.patch + ]; + + configureFlags = + [ "--disable-system" + "--enable-linux-user" + "--disable-gtk" + "--disable-sdl" + "--disable-vnc" + "--disable-kvm" + "--target-list=${cpuTarget}" + "--enable-pie" + "--sysconfdir=/etc" + "--localstatedir=/var" + ]; + + meta = with stdenv.lib; { + homepage = http://www.qemu.org/; + description = "Fork of QEMU with AFL++ instrumentation support"; + license = licenses.gpl2Plus; + maintainers = with maintainers; [ ris ]; + platforms = platforms.linux; + }; +} |