python3Packages.orjson: Disable failing tests on 32 bit
[NixPkgs.git] / pkgs / tools / security / aflplusplus / default.nix
blob79a0779e60a1df310fd46afe85e379964687d655
1 { lib, stdenv, stdenvNoCC, fetchFromGitHub, callPackage, makeWrapper
2 , clang, llvm, gcc, which, libcgroup, python, perl, gmp
3 , file, wine ? null, fetchpatch
4 }:
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
9 assert (wine != null) -> (stdenv.targetPlatform.system == "i686-linux");
11 let
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";
22     src = fetchFromGitHub {
23       owner = "AFLplusplus";
24       repo = "AFLplusplus";
25       rev = version;
26       sha256 = "1np2a3kypb2m8nyv6qnij18yzn41pl8619jzydci40br4vxial9l";
27     };
28     enableParallelBuilding = true;
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;
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\")"
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     '';
54     makeFlags = [ "PREFIX=$(out)" ];
55     buildPhase = ''
56       common="$makeFlags -j$NIX_BUILD_CORES"
57       make all $common
58       make radamsa $common
59       make -C gcc_plugin CC=${gcc}/bin/gcc CXX=${gcc}/bin/g++ $common
60       make -C llvm_mode $common
61       make -C qemu_mode/libcompcov $common
62       make -C qemu_mode/unsigaction $common
63     '';
65     postInstall = ''
66       # remove afl-clang(++) which are just symlinks to afl-clang-fast
67       rm $out/bin/afl-clang $out/bin/afl-clang++
69       # the makefile neglects to install unsigaction
70       cp qemu_mode/unsigaction/unsigaction*.so $out/lib/afl/
72       # Install the custom QEMU emulator for binary blob fuzzing.
73       cp ${aflplusplus-qemu}/bin/${qemu-exe-name} $out/bin/afl-qemu-trace
75       # give user a convenient way of accessing libcompconv.so, libdislocator.so, libtokencap.so
76       cat > $out/bin/get-afl-qemu-libcompcov-so <<END
77       #!${stdenv.shell}
78       echo $out/lib/afl/libcompcov.so
79       END
80       chmod +x $out/bin/get-afl-qemu-libcompcov-so
81       cp ${libdislocator}/bin/get-libdislocator-so $out/bin/
82       cp ${libtokencap}/bin/get-libtokencap-so $out/bin/
84       # Install the cgroups wrapper for asan-based fuzzing.
85       cp examples/asan_cgroups/limit_memory.sh $out/bin/afl-cgroup
86       chmod +x $out/bin/afl-cgroup
87       substituteInPlace $out/bin/afl-cgroup \
88         --replace "cgcreate" "${libcgroup}/bin/cgcreate" \
89         --replace "cgexec"   "${libcgroup}/bin/cgexec" \
90         --replace "cgdelete" "${libcgroup}/bin/cgdelete"
92       patchShebangs $out/bin
94     '' + lib.optionalString (wine != null) ''
95       substitute afl-wine-trace $out/bin/afl-wine-trace \
96         --replace "qemu_mode/unsigaction" "$out/lib/afl"
97       chmod +x $out/bin/afl-wine-trace
99       # qemu needs to be fed ELFs, not wrapper scripts, so we have to cheat a bit if we
100       # detect a wrapped wine
101       for winePath in ${wine}/bin/.wine ${wine}/bin/wine; do
102         if [ -x $winePath ]; then break; fi
103       done
104       makeWrapperArgs="--set-default 'AFL_WINE_PATH' '$winePath'" \
105         wrapPythonProgramsIn $out/bin ${python.pkgs.pefile}
106     '';
108     installCheckInputs = [ perl file ];
109     doInstallCheck = true;
110     installCheckPhase = ''
111       # replace references to tools in build directory with references to installed locations
112       substituteInPlace test/test.sh \
113         --replace '../libcompcov.so' '`$out/bin/get-afl-qemu-libcompcov-so`' \
114         --replace '../libdislocator.so' '`$out/bin/get-libdislocator-so`' \
115         --replace '../libtokencap.so' '`$out/bin/get-libtokencap-so`'
116       perl -pi -e 's|(?<!\.)(?<!-I)(\.\./)([^\s\/]+?)(?<!\.c)(?<!\.s?o)(?=\s)|\$out/bin/\2|g' test/test.sh
117       cd test && ./test.sh
118     '';
120     passthru = {
121       inherit libdislocator libtokencap;
122       qemu = aflplusplus-qemu;
123     };
125     meta = {
126       description = ''
127         A heavily enhanced version of AFL, incorporating many features
128         and improvements from the community
129       '';
130       homepage    = "https://aflplus.plus";
131       license     = lib.licenses.asl20;
132       platforms   = ["x86_64-linux" "i686-linux"];
133       maintainers = with lib.maintainers; [ ris mindavi ];
134     };
135   };
136 in aflplusplus