Clone of https://github.com/NixOS/nixpkgs.git (to stress-test knotserver)
1{ lib, stdenv, stdenvNoCC, fetchFromGitHub, callPackage, makeWrapper 2, clang, llvm, gcc, which, libcgroup, python, perl, gmp 3, file, wine ? null, fetchpatch 4}: 5 6# wine fuzzing is only known to work for win32 binaries, and using a mixture of 7# 32 and 64-bit libraries ... complicates things, so it's recommended to build 8# a full 32bit version of this package if you want to do wine fuzzing 9assert (wine != null) -> (stdenv.targetPlatform.system == "i686-linux"); 10 11let 12 aflplusplus-qemu = callPackage ./qemu.nix { inherit aflplusplus; }; 13 qemu-exe-name = if stdenv.targetPlatform.system == "x86_64-linux" then "qemu-x86_64" 14 else if stdenv.targetPlatform.system == "i686-linux" then "qemu-i386" 15 else throw "aflplusplus: no support for ${stdenv.targetPlatform.system}!"; 16 libdislocator = callPackage ./libdislocator.nix { inherit aflplusplus; }; 17 libtokencap = callPackage ./libtokencap.nix { inherit aflplusplus; }; 18 aflplusplus = stdenvNoCC.mkDerivation rec { 19 pname = "aflplusplus"; 20 version = "2.65c"; 21 22 src = fetchFromGitHub { 23 owner = "AFLplusplus"; 24 repo = "AFLplusplus"; 25 rev = version; 26 sha256 = "1np2a3kypb2m8nyv6qnij18yzn41pl8619jzydci40br4vxial9l"; 27 }; 28 enableParallelBuilding = true; 29 30 # Note: libcgroup isn't needed for building, just for the afl-cgroup 31 # script. 32 nativeBuildInputs = [ makeWrapper which clang gcc ]; 33 buildInputs = [ llvm python gmp ] 34 ++ lib.optional (wine != null) python.pkgs.wrapPython; 35 36 37 postPatch = '' 38 # Replace the CLANG_BIN variables with the correct path 39 substituteInPlace llvm_mode/afl-clang-fast.c \ 40 --replace "CLANGPP_BIN" '"${clang}/bin/clang++"' \ 41 --replace "CLANG_BIN" '"${clang}/bin/clang"' \ 42 --replace 'getenv("AFL_PATH")' "(getenv(\"AFL_PATH\") ? getenv(\"AFL_PATH\") : \"$out/lib/afl\")" 43 44 # Replace "gcc" and friends with full paths in afl-gcc 45 # Prevents afl-gcc picking up any (possibly incorrect) gcc from the path 46 substituteInPlace src/afl-gcc.c \ 47 --replace '"gcc"' '"${gcc}/bin/gcc"' \ 48 --replace '"g++"' '"${gcc}/bin/g++"' \ 49 --replace '"gcj"' '"gcj-UNSUPPORTED"' \ 50 --replace '"clang"' '"clang-UNSUPPORTED"' \ 51 --replace '"clang++"' '"clang++-UNSUPPORTED"' 52 ''; 53 54 env.NIX_CFLAGS_COMPILE = toString [ 55 # Needed with GCC 12 56 "-Wno-error=use-after-free" 57 ]; 58 59 makeFlags = [ "PREFIX=$(out)" ]; 60 buildPhase = '' 61 common="$makeFlags -j$NIX_BUILD_CORES" 62 make all $common 63 make radamsa $common 64 make -C gcc_plugin CC=${gcc}/bin/gcc CXX=${gcc}/bin/g++ $common 65 make -C llvm_mode $common 66 make -C qemu_mode/libcompcov $common 67 make -C qemu_mode/unsigaction $common 68 ''; 69 70 postInstall = '' 71 # remove afl-clang(++) which are just symlinks to afl-clang-fast 72 rm $out/bin/afl-clang $out/bin/afl-clang++ 73 74 # the makefile neglects to install unsigaction 75 cp qemu_mode/unsigaction/unsigaction*.so $out/lib/afl/ 76 77 # Install the custom QEMU emulator for binary blob fuzzing. 78 cp ${aflplusplus-qemu}/bin/${qemu-exe-name} $out/bin/afl-qemu-trace 79 80 # give user a convenient way of accessing libcompconv.so, libdislocator.so, libtokencap.so 81 cat > $out/bin/get-afl-qemu-libcompcov-so <<END 82 #!${stdenv.shell} 83 echo $out/lib/afl/libcompcov.so 84 END 85 chmod +x $out/bin/get-afl-qemu-libcompcov-so 86 cp ${libdislocator}/bin/get-libdislocator-so $out/bin/ 87 cp ${libtokencap}/bin/get-libtokencap-so $out/bin/ 88 89 # Install the cgroups wrapper for asan-based fuzzing. 90 cp examples/asan_cgroups/limit_memory.sh $out/bin/afl-cgroup 91 chmod +x $out/bin/afl-cgroup 92 substituteInPlace $out/bin/afl-cgroup \ 93 --replace "cgcreate" "${libcgroup}/bin/cgcreate" \ 94 --replace "cgexec" "${libcgroup}/bin/cgexec" \ 95 --replace "cgdelete" "${libcgroup}/bin/cgdelete" 96 97 patchShebangs $out/bin 98 99 '' + lib.optionalString (wine != null) '' 100 substitute afl-wine-trace $out/bin/afl-wine-trace \ 101 --replace "qemu_mode/unsigaction" "$out/lib/afl" 102 chmod +x $out/bin/afl-wine-trace 103 104 # qemu needs to be fed ELFs, not wrapper scripts, so we have to cheat a bit if we 105 # detect a wrapped wine 106 for winePath in ${wine}/bin/.wine ${wine}/bin/wine; do 107 if [ -x $winePath ]; then break; fi 108 done 109 makeWrapperArgs="--set-default 'AFL_WINE_PATH' '$winePath'" \ 110 wrapPythonProgramsIn $out/bin ${python.pkgs.pefile} 111 ''; 112 113 nativeInstallCheckInputs = [ perl file ]; 114 doInstallCheck = true; 115 installCheckPhase = '' 116 # replace references to tools in build directory with references to installed locations 117 substituteInPlace test/test.sh \ 118 --replace '../libcompcov.so' '`$out/bin/get-afl-qemu-libcompcov-so`' \ 119 --replace '../libdislocator.so' '`$out/bin/get-libdislocator-so`' \ 120 --replace '../libtokencap.so' '`$out/bin/get-libtokencap-so`' 121 perl -pi -e 's|(?<!\.)(?<!-I)(\.\./)([^\s\/]+?)(?<!\.c)(?<!\.s?o)(?=\s)|\$out/bin/\2|g' test/test.sh 122 cd test && ./test.sh 123 ''; 124 125 passthru = { 126 inherit libdislocator libtokencap; 127 qemu = aflplusplus-qemu; 128 }; 129 130 meta = { 131 description = '' 132 A heavily enhanced version of AFL, incorporating many features 133 and improvements from the community 134 ''; 135 homepage = "https://aflplus.plus"; 136 license = lib.licenses.asl20; 137 platforms = ["x86_64-linux" "i686-linux"]; 138 maintainers = with lib.maintainers; [ ris mindavi ]; 139 }; 140 }; 141in aflplusplus