diff options
Diffstat (limited to 'nixpkgs/pkgs/tools/security/afl')
-rw-r--r-- | nixpkgs/pkgs/tools/security/afl/README.md | 19 | ||||
-rw-r--r-- | nixpkgs/pkgs/tools/security/afl/default.nix | 82 | ||||
-rw-r--r-- | nixpkgs/pkgs/tools/security/afl/libdislocator.nix | 34 | ||||
-rw-r--r-- | nixpkgs/pkgs/tools/security/afl/qemu-patches/no-etc-install.patch | 13 | ||||
-rw-r--r-- | nixpkgs/pkgs/tools/security/afl/qemu-patches/syscall-glibc2_30.diff | 51 | ||||
-rw-r--r-- | nixpkgs/pkgs/tools/security/afl/qemu.nix | 79 |
6 files changed, 278 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/tools/security/afl/README.md b/nixpkgs/pkgs/tools/security/afl/README.md new file mode 100644 index 000000000000..180cad6bc4ca --- /dev/null +++ b/nixpkgs/pkgs/tools/security/afl/README.md @@ -0,0 +1,19 @@ +Updating the QEMU patches +========================= + +When updating to the latest American Fuzzy Lop, make sure to check for +any new patches to qemu for binary fuzzing support: + +https://github.com/google/AFL/tree/master/qemu_mode + +Be sure to check the build script and make sure it's also using the +right QEMU version and options in `qemu.nix`: + +https://github.com/google/AFL/blob/master/qemu_mode/build_qemu_support.sh + +`afl-config.h`, `afl-types.h`, and `afl-qemu-cpu-inl.h` are part of +the afl source code, and copied from `config.h`, `types.h` and +`afl-qemu-cpu-inl.h` appropriately. These files and the QEMU patches +need to be slightly adjusted to fix their `#include`s (the patches +try to otherwise include files like `../../config.h` which causes the +build to fail). diff --git a/nixpkgs/pkgs/tools/security/afl/default.nix b/nixpkgs/pkgs/tools/security/afl/default.nix new file mode 100644 index 000000000000..ccdbd78716d9 --- /dev/null +++ b/nixpkgs/pkgs/tools/security/afl/default.nix @@ -0,0 +1,82 @@ +{ lib, stdenv, fetchFromGitHub, callPackage, makeWrapper +, clang, llvm, which, libcgroup +}: + +let + afl-qemu = callPackage ./qemu.nix { inherit afl; }; + qemu-exe-name = if stdenv.hostPlatform.system == "x86_64-linux" then "qemu-x86_64" + else if stdenv.hostPlatform.system == "i686-linux" then "qemu-i386" + else throw "afl: no support for ${stdenv.hostPlatform.system}!"; + afl = stdenv.mkDerivation rec { + pname = "afl"; + version = "2.57b"; + + src = fetchFromGitHub { + owner = "google"; + repo = pname; + rev = "v${version}"; + sha256 = "0fqj3g6ds1f21kxz7m9mc1fspi9r4jg9jcmi60inwxijrc5ncvr6"; + }; + enableParallelBuilding = true; + + # Note: libcgroup isn't needed for building, just for the afl-cgroup + # script. + nativeBuildInputs = [ makeWrapper which llvm.dev ]; + buildInputs = [ llvm ]; + + makeFlags = [ "PREFIX=$(out)" ]; + postBuild = '' + make -C llvm_mode $makeFlags -j$NIX_BUILD_CORES + ''; + postInstall = '' + # Install the custom QEMU emulator for binary blob fuzzing. + cp ${afl-qemu}/bin/${qemu-exe-name} $out/bin/afl-qemu-trace + + # 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 \ + --prefix AFL_PATH : "$out/lib/afl" \ + --run 'export AFL_CC=''${AFL_CC:-${clang}/bin/clang} AFL_CXX=''${AFL_CXX:-${clang}/bin/clang++}' + done + ''; + + passthru.qemu = afl-qemu; + + meta = { + description = "Powerful fuzzer via genetic algorithms and instrumentation"; + longDescription = '' + American fuzzy lop is a fuzzer that employs a novel type of + compile-time instrumentation and genetic algorithms to + automatically discover clean, interesting test cases that + trigger new internal states in the targeted binary. This + substantially improves the functional coverage for the fuzzed + code. The compact synthesized corpora produced by the tool are + also useful for seeding other, more labor or resource-intensive + testing regimes down the road. + ''; + homepage = "https://lcamtuf.coredump.cx/afl/"; + license = lib.licenses.asl20; + platforms = ["x86_64-linux" "i686-linux"]; + maintainers = with lib.maintainers; [ thoughtpolice ris ]; + }; + }; +in afl diff --git a/nixpkgs/pkgs/tools/security/afl/libdislocator.nix b/nixpkgs/pkgs/tools/security/afl/libdislocator.nix new file mode 100644 index 000000000000..400464c00567 --- /dev/null +++ b/nixpkgs/pkgs/tools/security/afl/libdislocator.nix @@ -0,0 +1,34 @@ +{ lib, stdenv, afl}: + +stdenv.mkDerivation { + version = lib.getVersion afl; + pname = "libdislocator"; + + src = afl.src; + sourceRoot = "${afl.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 lib; { + homepage = "https://lcamtuf.coredump.cx/afl/"; + description = '' + Drop-in replacement for the libc allocator which improves + the odds of bumping into heap-related security bugs in + several ways. + ''; + license = lib.licenses.asl20; + maintainers = with maintainers; [ ris ]; + }; +} diff --git a/nixpkgs/pkgs/tools/security/afl/qemu-patches/no-etc-install.patch b/nixpkgs/pkgs/tools/security/afl/qemu-patches/no-etc-install.patch new file mode 100644 index 000000000000..5dfbfd780f1c --- /dev/null +++ b/nixpkgs/pkgs/tools/security/afl/qemu-patches/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/nixpkgs/pkgs/tools/security/afl/qemu-patches/syscall-glibc2_30.diff b/nixpkgs/pkgs/tools/security/afl/qemu-patches/syscall-glibc2_30.diff new file mode 100644 index 000000000000..aa2950bf157c --- /dev/null +++ b/nixpkgs/pkgs/tools/security/afl/qemu-patches/syscall-glibc2_30.diff @@ -0,0 +1,51 @@ +--- qemu-2.10.0-clean/linux-user/syscall.c 2020-03-12 18:47:47.898592169 +0100 ++++ qemu-2.10.0/linux-user/syscall.c 2020-03-13 09:13:42.461809699 +0100 +@@ -34,6 +34,7 @@ + #include <sys/resource.h> + #include <sys/swap.h> + #include <linux/capability.h> ++#include <linux/sockios.h> // https://lkml.org/lkml/2019/6/3/988 + #include <sched.h> + #include <sys/timex.h> + #ifdef __ia64__ +@@ -256,7 +257,9 @@ static type name (type1 arg1,type2 arg2, + #endif + + #ifdef __NR_gettid +-_syscall0(int, gettid) ++// taken from https://patchwork.kernel.org/patch/10862231/ ++#define __NR_sys_gettid __NR_gettid ++_syscall0(int, sys_gettid) + #else + /* This is a replacement for the host gettid() and must return a host + errno. */ +@@ -6219,7 +6222,7 @@ static void *clone_func(void *arg) + cpu = ENV_GET_CPU(env); + thread_cpu = cpu; + ts = (TaskState *)cpu->opaque; +- info->tid = gettid(); ++ info->tid = sys_gettid(); + task_settid(ts); + if (info->child_tidptr) + put_user_u32(info->tid, info->child_tidptr); +@@ -6363,9 +6366,9 @@ static int do_fork(CPUArchState *env, un + mapping. We can't repeat the spinlock hack used above because + the child process gets its own copy of the lock. */ + if (flags & CLONE_CHILD_SETTID) +- put_user_u32(gettid(), child_tidptr); ++ put_user_u32(sys_gettid(), child_tidptr); + if (flags & CLONE_PARENT_SETTID) +- put_user_u32(gettid(), parent_tidptr); ++ put_user_u32(sys_gettid(), parent_tidptr); + ts = (TaskState *)cpu->opaque; + if (flags & CLONE_SETTLS) + cpu_set_tls (env, newtls); +@@ -11402,7 +11405,7 @@ abi_long do_syscall(void *cpu_env, int n + break; + #endif + case TARGET_NR_gettid: +- ret = get_errno(gettid()); ++ ret = get_errno(sys_gettid()); + break; + #ifdef TARGET_NR_readahead + case TARGET_NR_readahead: diff --git a/nixpkgs/pkgs/tools/security/afl/qemu.nix b/nixpkgs/pkgs/tools/security/afl/qemu.nix new file mode 100644 index 000000000000..e33c4c2fb03a --- /dev/null +++ b/nixpkgs/pkgs/tools/security/afl/qemu.nix @@ -0,0 +1,79 @@ +{ lib, stdenv, fetchurl, afl, python2, zlib, pkg-config, glib, perl +, texinfo, libuuid, flex, bison, pixman, autoconf +}: + +with lib; + +let + cpuTarget = if stdenv.hostPlatform.system == "x86_64-linux" then "x86_64-linux-user" + else if stdenv.hostPlatform.system == "i686-linux" then "i386-linux-user" + else throw "afl: no support for ${stdenv.hostPlatform.system}!"; +in +stdenv.mkDerivation rec { + pname = "afl-qemu"; + version = "2.10.0"; + + srcs = [ + (fetchurl { + url = "http://wiki.qemu.org/download/qemu-${version}.tar.bz2"; + sha256 = "0j3dfxzrzdp1w21k21fjvmakzc6lcha1rsclaicwqvbf63hkk7vy"; + }) + afl.src + ]; + + sourceRoot = "qemu-${version}"; + + postUnpack = '' + cp ${afl.src.name}/types.h $sourceRoot/afl-types.h + substitute ${afl.src.name}/config.h $sourceRoot/afl-config.h \ + --replace "types.h" "afl-types.h" + substitute ${afl.src.name}/qemu_mode/patches/afl-qemu-cpu-inl.h $sourceRoot/afl-qemu-cpu-inl.h \ + --replace "../../config.h" "afl-config.h" + substituteInPlace ${afl.src.name}/qemu_mode/patches/cpu-exec.diff \ + --replace "../patches/afl-qemu-cpu-inl.h" "afl-qemu-cpu-inl.h" + ''; + + nativeBuildInputs = [ + python2 perl pkg-config flex bison autoconf texinfo + ]; + + buildInputs = [ + zlib glib pixman libuuid + ]; + + enableParallelBuilding = true; + + patches = [ + # patches extracted from afl source + "../${afl.src.name}/qemu_mode/patches/cpu-exec.diff" + "../${afl.src.name}/qemu_mode/patches/elfload.diff" + "../${afl.src.name}/qemu_mode/patches/syscall.diff" + "../${afl.src.name}/qemu_mode/patches/configure.diff" + "../${afl.src.name}/qemu_mode/patches/memfd.diff" + # nix-specific patches to make installation more well-behaved + ./qemu-patches/no-etc-install.patch + # patch for fixing qemu build on glibc >= 2.30 + ./qemu-patches/syscall-glibc2_30.diff + ]; + + 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 lib; { + homepage = "http://www.qemu.org/"; + description = "Fork of QEMU with AFL instrumentation support"; + license = licenses.gpl2Plus; + maintainers = with maintainers; [ thoughtpolice ]; + platforms = platforms.linux; + }; +} |