From 6a316a6e351160edd391d06fb5e41a76237791e1 Mon Sep 17 00:00:00 2001 From: Kush Jain Date: Sat, 13 Apr 2024 08:12:56 -0400 Subject: [PATCH 01/10] Muttfuzz code and experiments --- .../aflplusplus_muttfuzz/builder.Dockerfile | 40 +++ fuzzers/aflplusplus_muttfuzz/fuzzer.py | 87 ++++++ fuzzers/aflplusplus_muttfuzz/fuzzutil.py | 272 ++++++++++++++++++ fuzzers/aflplusplus_muttfuzz/mutate.py | 130 +++++++++ .../aflplusplus_muttfuzz/runner.Dockerfile | 28 ++ service/experiment-requests.yaml | 5 + 6 files changed, 562 insertions(+) create mode 100644 fuzzers/aflplusplus_muttfuzz/builder.Dockerfile create mode 100644 fuzzers/aflplusplus_muttfuzz/fuzzer.py create mode 100644 fuzzers/aflplusplus_muttfuzz/fuzzutil.py create mode 100644 fuzzers/aflplusplus_muttfuzz/mutate.py create mode 100644 fuzzers/aflplusplus_muttfuzz/runner.Dockerfile diff --git a/fuzzers/aflplusplus_muttfuzz/builder.Dockerfile b/fuzzers/aflplusplus_muttfuzz/builder.Dockerfile new file mode 100644 index 000000000..d4fc0787f --- /dev/null +++ b/fuzzers/aflplusplus_muttfuzz/builder.Dockerfile @@ -0,0 +1,40 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ARG parent_image +FROM $parent_image + +# Install libstdc++ to use llvm_mode. +RUN apt-get update && \ + apt-get install -y wget libstdc++-5-dev libtool-bin automake flex bison \ + libglib2.0-dev libpixman-1-dev python3-setuptools unzip \ + apt-utils apt-transport-https ca-certificates + +# Download and compile afl++. +RUN git clone https://github.com/AFLplusplus/AFLplusplus.git /afl && \ + cd /afl && \ + git checkout 0c122aeee65c5e91b6ecc465dcdf740aa67943d1 + +# Build without Python support as we don't need it. +# Set AFL_NO_X86 to skip flaky tests. +RUN cd /afl && unset CFLAGS && unset CXXFLAGS && \ + export CC=clang && export AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && make install && \ + make -C utils/aflpp_driver && \ + cp utils/aflpp_driver/libAFLDriver.a / + +RUN apt-get update && apt-get install -y python3 + +RUN pip3 install --upgrade --force pip +RUN pip install muttfuzz \ No newline at end of file diff --git a/fuzzers/aflplusplus_muttfuzz/fuzzer.py b/fuzzers/aflplusplus_muttfuzz/fuzzer.py new file mode 100644 index 000000000..df27b1810 --- /dev/null +++ b/fuzzers/aflplusplus_muttfuzz/fuzzer.py @@ -0,0 +1,87 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Integration code for AFLplusplus fuzzer.""" + +# This optimized afl++ variant should always be run together with +# "aflplusplus" to show the difference - a default configured afl++ vs. +# a hand-crafted optimized one. afl++ is configured not to enable the good +# stuff by default to be as close to vanilla afl as possible. +# But this means that the good stuff is hidden away in this benchmark +# otherwise. + +import os + +from fuzzers.aflplusplus import fuzzer as aflplusplus_fuzzer +from fuzzers.aflplusplus_muttfuzz import fuzzutil + + +def build(): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + aflplusplus_fuzzer.build() + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, "cmplog") + + +def check_skip_det_compatible(additional_flags): + """Checks if additional flags are compatible with '-d' option""" + # AFL refuses to take in '-d' with '-M' or '-S' options for parallel mode. + # (cf. https://github.com/google/AFL/blob/8da80951/afl-fuzz.c#L7477) + if "-M" in additional_flags or "-S" in additional_flags: + return False + return True + + +def restore_out(input_corpus, output_corpus, crashes_storage): + """Restores output dir and copies crashes after mutant is done running""" + os.system(f"rm -rf {input_corpus}/*") + os.system( + f"cp {output_corpus}/default/crashes/crashes.*/id* {crashes_storage}/") + os.system( + f"cp {output_corpus}/default/crashes/crashes.*/id* {input_corpus}/") + os.system(f"cp {output_corpus}/default/queue/* {input_corpus}/") + os.system(f"rm -rf {output_corpus}/*") + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + os.environ["AFL_SKIP_CRASHES"] = "1" + os.environ["AFL_AUTORESUME"] = "1" + print(f"{input_corpus} {output_corpus} {target_binary}") + + crashes_storage = "/storage" + os.makedirs(crashes_storage, exist_ok=True) + + aflplusplus_fuzz_fn = lambda: aflplusplus_fuzzer.fuzz( + input_corpus, output_corpus, target_binary) + + budget = 86_400 + fraction_mutant = 0.5 + time_per_mutant = 300 + initial_budget = 1_800 + post_mutant_fn = lambda: restore_out(input_corpus, output_corpus, + crashes_storage) + fuzzutil.fuzz_with_mutants_via_function( + aflplusplus_fuzz_fn, + target_binary, + budget, + time_per_mutant, + fraction_mutant, + initial_fn=aflplusplus_fuzz_fn, + initial_budget=initial_budget, + post_initial_fn=post_mutant_fn, + post_mutant_fn=post_mutant_fn, + ) diff --git a/fuzzers/aflplusplus_muttfuzz/fuzzutil.py b/fuzzers/aflplusplus_muttfuzz/fuzzutil.py new file mode 100644 index 000000000..5c0c508ac --- /dev/null +++ b/fuzzers/aflplusplus_muttfuzz/fuzzutil.py @@ -0,0 +1,272 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Utilities for running muttfuzz""" +import os +import signal +import subprocess +import time +from contextlib import contextmanager +from datetime import datetime + +from fuzzers.aflplusplus_muttfuzz import mutate + + +class TimeoutException(Exception): + """ "Exception thrown when timeouts occur""" + + +@contextmanager +def time_limit(seconds): + """Method to define a time limit before throwing exception""" + + def signal_handler(signum, frame): + raise TimeoutException("Timed out!") + + signal.signal(signal.SIGALRM, signal_handler) + signal.alarm(seconds) + try: + yield + finally: + signal.alarm(0) + + +def restore_executable(executable, executable_code): + """Method to restore the original executable""" + # We do this because it could still be busy if fuzzer hasn't shut down yet + with open("/tmp/new_executable", "wb") as f_name: + f_name.write(executable_code) + os.rename("/tmp/new_executable", executable) + subprocess.check_call(["chmod", "+x", executable]) + + +def silent_run_with_timeout(cmd, timeout): + """Method to run command silently with timeout""" + dnull = open(os.devnull, "w") + start_p = time.time() + try: + with open("cmd_errors.txt", "w") as cmd_errors: + process = subprocess.Popen( # pylint: disable=subprocess-popen-preexec-fn + cmd, + shell=True, + preexec_fn=os.setsid, + stdout=dnull, + stderr=cmd_errors, + ) + while (process.poll() is None) and ( + (time.time() - start_p) < timeout): + time.sleep(0.5) + if process.poll() is None: + os.killpg(os.getpgid(process.pid), signal.SIGTERM) + with open("cmd_errors.txt", "r") as cmd_errors: + cmd_errors_out = cmd_errors.read() + if len(cmd_errors_out) > 0: + print("ERRORS:") + print(cmd_errors_out) + finally: + if process.poll() is None: + os.killpg(os.getpgid(process.pid), signal.SIGTERM) + + +def fuzz_with_mutants( # pylint: disable=too-many-locals,too-many-arguments + fuzzer_cmd, + executable, + budget, + time_per_mutant, + fraction_mutant, + initial_fuzz_cmd="", + initial_budget=0, + post_initial_cmd="", + post_mutant_cmd="", + status_cmd="", + order=1, +): + """Function to fuzz mutants from commands""" + executable_code = mutate.get_code(executable) + executable_jumps = mutate.get_jumps(executable) + start_fuzz = time.time() + mutant_no = 1 + try: + if initial_fuzz_cmd != "": + print( + "=" * 10, + datetime.utcfromtimestamp( + time.time()).strftime("%Y-%m-%d %H:%M:%S"), + "=" * 10, + ) + print("RUNNING INITIAL FUZZING...") + silent_run_with_timeout(initial_fuzz_cmd, initial_budget) + if status_cmd != "": + print("INITIAL STATUS:") + subprocess.call(status_cmd, shell=True) + if post_initial_cmd != "": + subprocess.call(post_initial_cmd, shell=True) + + while ((time.time() - start_fuzz) - initial_budget) < (budget * + fraction_mutant): + print( + "=" * 10, + datetime.utcfromtimestamp( + time.time()).strftime("%Y-%m-%d %H:%M:%S"), + "=" * 10, + ) + print( + round(time.time() - start_fuzz, 2), + "ELAPSED: GENERATING MUTANT #" + str(mutant_no), + ) + mutant_no += 1 + # make a new mutant of the executable; rename + # avoids hitting a busy executable + mutate.mutate_from( + executable_code, + executable_jumps, + "/tmp/new_executable", + order=order, + ) + os.rename("/tmp/new_executable", executable) + subprocess.check_call(["chmod", "+x", executable]) + print("FUZZING MUTANT...") + start_run = time.time() + silent_run_with_timeout(fuzzer_cmd, time_per_mutant) + print( + "FINISHED FUZZING IN", + round(time.time() - start_run, 2), + "SECONDS", + ) + if post_mutant_cmd != "": + subprocess.call(post_mutant_cmd, shell=True) + if status_cmd != "": + print("STATUS:") + subprocess.call(status_cmd, shell=True) + + print( + datetime.utcfromtimestamp( + time.time()).strftime("%Y-%m-%d %H:%M:%S")) + print(round(time.time() - start_fuzz, 2), + "ELAPSED: STARTING FINAL FUZZ") + restore_executable(executable, executable_code) + silent_run_with_timeout(fuzzer_cmd, budget - (time.time() - start_fuzz)) + print( + "COMPLETED ALL FUZZING AFTER", + round(time.time() - start_fuzz, 2), + "SECONDS", + ) + if status_cmd != "": + print("FINAL STATUS:") + subprocess.call(status_cmd, shell=True) + finally: + # always restore the original binary! + restore_executable(executable, executable_code) + + +def fuzz_with_mutants_via_function( # pylint: disable=too-many-locals,too-many-statements,too-many-arguments + fuzzer_fn, + executable, + budget, + time_per_mutant, + fraction_mutant, + initial_fn=None, + initial_budget=0, + post_initial_fn=None, + post_mutant_fn=None, + status_fn=None, + order=1, +): + """Fuzz mutants from initial and post mutant functions""" + executable_code = mutate.get_code(executable) + executable_jumps = mutate.get_jumps(executable) + start_fuzz = time.time() + mutant_no = 1 + try: + if initial_fn is not None: + print( + "=" * 10, + datetime.utcfromtimestamp( + time.time()).strftime("%Y-%m-%d %H:%M:%S"), + "=" * 10, + ) + print("RUNNING INITIAL FUZZING...") + try: + with time_limit(initial_budget): + initial_fn() + except TimeoutException: + pass + if status_fn is not None: + print("INITIAL STATUS:") + status_fn() + if post_initial_fn is not None: + post_initial_fn() + + while ((time.time() - start_fuzz) - initial_budget) < (budget * + fraction_mutant): + print( + "=" * 10, + datetime.utcfromtimestamp( + time.time()).strftime("%Y-%m-%d %H:%M:%S"), + "=" * 10, + ) + print( + round(time.time() - start_fuzz, 2), + "ELAPSED: GENERATING MUTANT #" + str(mutant_no), + ) + mutant_no += 1 + # make a new mutant of the executable; rename avoids + # hitting a busy executable + mutate.mutate_from( + executable_code, + executable_jumps, + "/tmp/new_executable", + order=order, + ) + os.rename("/tmp/new_executable", executable) + subprocess.check_call(["chmod", "+x", executable]) + print("FUZZING MUTANT...") + start_run = time.time() + try: + with time_limit(time_per_mutant): + fuzzer_fn() + except TimeoutException: + pass + print( + "FINISHED FUZZING IN", + round(time.time() - start_run, 2), + "SECONDS", + ) + if post_mutant_fn is not None: + post_mutant_fn() + if status_fn is not None: + print("STATUS:") + status_fn() + + print( + datetime.utcfromtimestamp( + time.time()).strftime("%Y-%m-%d %H:%M:%S")) + print(round(time.time() - start_fuzz, 2), + "ELAPSED: STARTING FINAL FUZZ") + restore_executable(executable, executable_code) + try: + with time_limit(int(budget - (time.time() - start_fuzz))): + fuzzer_fn() + except TimeoutException: + pass + print( + "COMPLETED ALL FUZZING AFTER", + round(time.time() - start_fuzz, 2), + "SECONDS", + ) + if status_fn is not None: + print("FINAL STATUS:") + status_fn() + finally: + # always restore the original binary! + restore_executable(executable, executable_code) diff --git a/fuzzers/aflplusplus_muttfuzz/mutate.py b/fuzzers/aflplusplus_muttfuzz/mutate.py new file mode 100644 index 000000000..e5e388a90 --- /dev/null +++ b/fuzzers/aflplusplus_muttfuzz/mutate.py @@ -0,0 +1,130 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Module to apply mutants at bytecode level""" +import random +import subprocess + +JUMP_OPCODES = ["je", "jne", "jl", "jle", "jg", "jge"] +SHORT_JUMPS = list( + map(bytes.fromhex, ["74", "75", "7C", "7D", "7E", "7F", "EB"])) +# no unconditional for near jumps, since changes opcode length, not worth it +NEAR_JUMPS = list( + map( + bytes.fromhex, + ["0F 84", "0F 85", "0F 8C", "0F 8D", "0F 8E", "0F 8F", "90 E9"], + )) + +# known markers for fuzzer/compiler injected instrumentation/etc. +INST_SET = ["__afl", "__asan", "__ubsan", "__sanitizer", "__lsan", "__sancov"] + + +def get_jumps(filename): # pylint: disable=too-many-locals + """Method to get all jumps in file""" + jumps = {} + + proc = subprocess.Popen( + ["objdump", "-d", "--file-offsets", filename], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + out, _ = proc.communicate() + output = str(out, encoding="utf-8") + + for line in output.split("\n"): + try: + if "File Offset" in line and line[-1] == ":": + section_base = int(line.split()[0], 16) + offset_hex = line.split("File Offset:")[1].split(")")[0] + section_offset = int(offset_hex, 16) - section_base + continue + found_inst = False + for i in INST_SET: + if i in line: + found_inst = True + break + if found_inst: + continue # Don't mutate these things + fields = line.split("\t") + if len(fields) > 1: + opcode = fields[2].split()[0] + if opcode in JUMP_OPCODES: + loc_bytes = fields[0].split(":")[0] + loc = int(loc_bytes, 16) + section_offset + jumps[loc] = (opcode, bytes.fromhex(fields[1])) + # pylint: disable=bare-except + except: # If we can't parse some line in the objdump, just skip it + pass + + return jumps + + +def different_jump(hexdata): + """Method to select a different jump""" + # NEAR JUMP BYTE CHECK + if hexdata[0] == 15: # pylint: disable=no-else-return + # Have a high chance of just changing near JE and JNE to a + # forced JMP, "removing" a branch + if ((hexdata[1] == NEAR_JUMPS[0][1]) or + (hexdata[1] == NEAR_JUMPS[1][1])) and (random.random() <= 0.75): + return NEAR_JUMPS[-1] + return random.choice( + list(filter(lambda j: j[1] != hexdata[1], NEAR_JUMPS))) + else: + # Have a high chance of just changing short JE and + # JNE to a forced JMP, "removing" a branch + if ((hexdata[0] == SHORT_JUMPS[0][0]) or + (hexdata[0] == SHORT_JUMPS[1][0])) and (random.random() <= 0.75): + return SHORT_JUMPS[-1] + return random.choice( + list(filter(lambda j: j[0] != hexdata[0], SHORT_JUMPS))) + + +def pick_and_change(jumps): + """Randomly change jumps""" + loc = random.choice(list(jumps.keys())) + return (loc, different_jump(jumps[loc][1])) + + +def get_code(filename): + """Read code as array of bytes""" + with open(filename, "rb") as f_name: + return bytearray(f_name.read()) + + +def mutant_from(code, jumps, order=1): + """Get new code from code and jumps""" + new_code = bytearray(code) + for _ in range( + order): # allows higher-order mutants, though can undo mutations + (loc, new_data) = pick_and_change(jumps) + for offset in range(0, len(new_data)): # pylint: disable=consider-using-enumerate + new_code[loc + offset] = new_data[offset] + return new_code + + +def mutant(filename, order=1): + """Write mutant to file""" + return mutant_from(get_code(filename), get_jumps(filename), order=order) + + +def mutate_from(code, jumps, new_filename, order=1): + """Wrap mutant_from wth order to write to new_filename""" + with open(new_filename, "wb") as f_name: + f_name.write(mutant_from(code, jumps, order=order)) + + +def mutate(filename, new_filename, order=1): + """Write mutant to new file""" + with open(new_filename, "wb") as f_name: + f_name.write(mutant(filename, order=order)) diff --git a/fuzzers/aflplusplus_muttfuzz/runner.Dockerfile b/fuzzers/aflplusplus_muttfuzz/runner.Dockerfile new file mode 100644 index 000000000..6237d656b --- /dev/null +++ b/fuzzers/aflplusplus_muttfuzz/runner.Dockerfile @@ -0,0 +1,28 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM gcr.io/fuzzbench/base-image + +# This makes interactive docker runs painless: +ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/out" +#ENV AFL_MAP_SIZE=2621440 +ENV PATH="$PATH:/out" +ENV AFL_SKIP_CPUFREQ=1 +ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 +ENV AFL_TESTCACHE_SIZE=2 + +RUN apt-get update && apt-get install -y python3 + +RUN pip3 install --upgrade --force pip +RUN pip install muttfuzz \ No newline at end of file diff --git a/service/experiment-requests.yaml b/service/experiment-requests.yaml index fe0efe2a2..d2a421503 100644 --- a/service/experiment-requests.yaml +++ b/service/experiment-requests.yaml @@ -20,6 +20,11 @@ # Please add new experiment requests towards the top of this file. # +- experiment: 2024-04-13-aflpp-muttfuzz + description: "Benchmark afl++ muttfuzz" + fuzzers: + - aflplusplus_muttfuzz + - experiment: 2023-06-12-aflpp description: "Benchmark afl++ releases and newmutation" fuzzers: From 5a27fdb7757feebb646533749b455992e17f9581 Mon Sep 17 00:00:00 2001 From: Kush Jain Date: Sat, 13 Apr 2024 08:18:48 -0400 Subject: [PATCH 02/10] Fix undefined var --- fuzzers/aflplusplus_muttfuzz/fuzzutil.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fuzzers/aflplusplus_muttfuzz/fuzzutil.py b/fuzzers/aflplusplus_muttfuzz/fuzzutil.py index 5c0c508ac..dca0daa1d 100644 --- a/fuzzers/aflplusplus_muttfuzz/fuzzutil.py +++ b/fuzzers/aflplusplus_muttfuzz/fuzzutil.py @@ -54,6 +54,7 @@ def silent_run_with_timeout(cmd, timeout): """Method to run command silently with timeout""" dnull = open(os.devnull, "w") start_p = time.time() + process = None try: with open("cmd_errors.txt", "w") as cmd_errors: process = subprocess.Popen( # pylint: disable=subprocess-popen-preexec-fn @@ -74,8 +75,9 @@ def silent_run_with_timeout(cmd, timeout): print("ERRORS:") print(cmd_errors_out) finally: - if process.poll() is None: - os.killpg(os.getpgid(process.pid), signal.SIGTERM) + if process is not None: + if process.poll() is None: + os.killpg(os.getpgid(process.pid), signal.SIGTERM) def fuzz_with_mutants( # pylint: disable=too-many-locals,too-many-arguments From 8d0570ce45aed846bf9de340c2ef84983fa24cc5 Mon Sep 17 00:00:00 2001 From: Kush Jain Date: Thu, 18 Apr 2024 11:02:31 -0400 Subject: [PATCH 03/10] Update AFLpp to current dockerfiles --- .../aflplusplus_muttfuzz/builder.Dockerfile | 36 +++++++++++++------ .../aflplusplus_muttfuzz/runner.Dockerfile | 1 + 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/fuzzers/aflplusplus_muttfuzz/builder.Dockerfile b/fuzzers/aflplusplus_muttfuzz/builder.Dockerfile index d4fc0787f..fa2b3813e 100644 --- a/fuzzers/aflplusplus_muttfuzz/builder.Dockerfile +++ b/fuzzers/aflplusplus_muttfuzz/builder.Dockerfile @@ -15,23 +15,37 @@ ARG parent_image FROM $parent_image -# Install libstdc++ to use llvm_mode. RUN apt-get update && \ - apt-get install -y wget libstdc++-5-dev libtool-bin automake flex bison \ - libglib2.0-dev libpixman-1-dev python3-setuptools unzip \ - apt-utils apt-transport-https ca-certificates + apt-get install -y \ + build-essential \ + python3-dev \ + python3-setuptools \ + automake \ + cmake \ + git \ + flex \ + bison \ + libglib2.0-dev \ + libpixman-1-dev \ + cargo \ + libgtk-3-dev \ + # for QEMU mode + ninja-build \ + gcc-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-plugin-dev \ + libstdc++-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-dev -# Download and compile afl++. -RUN git clone https://github.com/AFLplusplus/AFLplusplus.git /afl && \ +# Download afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ cd /afl && \ - git checkout 0c122aeee65c5e91b6ecc465dcdf740aa67943d1 + git checkout 27d05f3c216e18163236efa42b630a5b3784d2e9 || \ + true # Build without Python support as we don't need it. # Set AFL_NO_X86 to skip flaky tests. -RUN cd /afl && unset CFLAGS && unset CXXFLAGS && \ - export CC=clang && export AFL_NO_X86=1 && \ - PYTHON_INCLUDE=/ make && make install && \ - make -C utils/aflpp_driver && \ +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ cp utils/aflpp_driver/libAFLDriver.a / RUN apt-get update && apt-get install -y python3 diff --git a/fuzzers/aflplusplus_muttfuzz/runner.Dockerfile b/fuzzers/aflplusplus_muttfuzz/runner.Dockerfile index 6237d656b..21504f934 100644 --- a/fuzzers/aflplusplus_muttfuzz/runner.Dockerfile +++ b/fuzzers/aflplusplus_muttfuzz/runner.Dockerfile @@ -21,6 +21,7 @@ ENV PATH="$PATH:/out" ENV AFL_SKIP_CPUFREQ=1 ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 ENV AFL_TESTCACHE_SIZE=2 +RUN apt install -y unzip git gdb joe RUN apt-get update && apt-get install -y python3 From 4021dbc4106e877c2897bf30189803a5b4abf086 Mon Sep 17 00:00:00 2001 From: Dongge Liu Date: Tue, 23 Apr 2024 10:00:28 +1000 Subject: [PATCH 04/10] Modify gcbrun_experiment.py to enable PR-experiments --- service/gcbrun_experiment.py | 1 + 1 file changed, 1 insertion(+) diff --git a/service/gcbrun_experiment.py b/service/gcbrun_experiment.py index f19ab493d..642702d2c 100644 --- a/service/gcbrun_experiment.py +++ b/service/gcbrun_experiment.py @@ -16,6 +16,7 @@ """Entrypoint for gcbrun into run_experiment. This script will get the command from the last PR comment containing "/gcbrun" and pass it to run_experiment.py which will run an experiment.""" +# a dummy comment! import logging import os From 9d70f0ddef7e8378a16b69f497aa3e90b7d968fa Mon Sep 17 00:00:00 2001 From: Dongge Liu Date: Tue, 23 Apr 2024 10:01:34 +1000 Subject: [PATCH 05/10] No need to edit experiment-requests.yaml --- service/experiment-requests.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/service/experiment-requests.yaml b/service/experiment-requests.yaml index d2a421503..fe0efe2a2 100644 --- a/service/experiment-requests.yaml +++ b/service/experiment-requests.yaml @@ -20,11 +20,6 @@ # Please add new experiment requests towards the top of this file. # -- experiment: 2024-04-13-aflpp-muttfuzz - description: "Benchmark afl++ muttfuzz" - fuzzers: - - aflplusplus_muttfuzz - - experiment: 2023-06-12-aflpp description: "Benchmark afl++ releases and newmutation" fuzzers: From f55490a648baa92e0c1bb265979f08160a5a65a9 Mon Sep 17 00:00:00 2001 From: Kush Jain Date: Tue, 23 Apr 2024 17:02:56 -0400 Subject: [PATCH 06/10] Adding popular fuzzer aflplusplus variants --- fuzzers/aflplusplus_muttfuzz/fuzzer.py | 15 --- fuzzers/aflsmart_muttfuzz/README.md | 18 ++++ fuzzers/aflsmart_muttfuzz/builder.Dockerfile | 75 +++++++++++++ fuzzers/aflsmart_muttfuzz/fuzzer.py | 68 ++++++++++++ fuzzers/aflsmart_muttfuzz/runner.Dockerfile | 21 ++++ fuzzers/honggfuzz_muttfuzz/builder.Dockerfile | 36 +++++++ fuzzers/honggfuzz_muttfuzz/fuzzer.py | 68 ++++++++++++ fuzzers/honggfuzz_muttfuzz/runner.Dockerfile | 18 ++++ fuzzers/libafll_muttfuzz/builder.Dockerfile | 60 +++++++++++ fuzzers/libafll_muttfuzz/description.md | 11 ++ fuzzers/libafll_muttfuzz/fuzzer.py | 66 ++++++++++++ fuzzers/libafll_muttfuzz/runner.Dockerfile | 25 +++++ fuzzers/libfuzzer_muttfuzz/builder.Dockerfile | 26 +++++ fuzzers/libfuzzer_muttfuzz/fuzzer.py | 66 ++++++++++++ fuzzers/libfuzzer_muttfuzz/patch.diff | 100 ++++++++++++++++++ fuzzers/libfuzzer_muttfuzz/runner.Dockerfile | 15 +++ 16 files changed, 673 insertions(+), 15 deletions(-) create mode 100644 fuzzers/aflsmart_muttfuzz/README.md create mode 100644 fuzzers/aflsmart_muttfuzz/builder.Dockerfile create mode 100755 fuzzers/aflsmart_muttfuzz/fuzzer.py create mode 100644 fuzzers/aflsmart_muttfuzz/runner.Dockerfile create mode 100644 fuzzers/honggfuzz_muttfuzz/builder.Dockerfile create mode 100644 fuzzers/honggfuzz_muttfuzz/fuzzer.py create mode 100644 fuzzers/honggfuzz_muttfuzz/runner.Dockerfile create mode 100644 fuzzers/libafll_muttfuzz/builder.Dockerfile create mode 100644 fuzzers/libafll_muttfuzz/description.md create mode 100755 fuzzers/libafll_muttfuzz/fuzzer.py create mode 100644 fuzzers/libafll_muttfuzz/runner.Dockerfile create mode 100644 fuzzers/libfuzzer_muttfuzz/builder.Dockerfile create mode 100755 fuzzers/libfuzzer_muttfuzz/fuzzer.py create mode 100644 fuzzers/libfuzzer_muttfuzz/patch.diff create mode 100644 fuzzers/libfuzzer_muttfuzz/runner.Dockerfile diff --git a/fuzzers/aflplusplus_muttfuzz/fuzzer.py b/fuzzers/aflplusplus_muttfuzz/fuzzer.py index df27b1810..408bd218f 100644 --- a/fuzzers/aflplusplus_muttfuzz/fuzzer.py +++ b/fuzzers/aflplusplus_muttfuzz/fuzzer.py @@ -30,21 +30,6 @@ def build(): # pylint: disable=too-many-branches,too-many-statements """Build benchmark.""" aflplusplus_fuzzer.build() - -def get_cmplog_build_directory(target_directory): - """Return path to CmpLog target directory.""" - return os.path.join(target_directory, "cmplog") - - -def check_skip_det_compatible(additional_flags): - """Checks if additional flags are compatible with '-d' option""" - # AFL refuses to take in '-d' with '-M' or '-S' options for parallel mode. - # (cf. https://github.com/google/AFL/blob/8da80951/afl-fuzz.c#L7477) - if "-M" in additional_flags or "-S" in additional_flags: - return False - return True - - def restore_out(input_corpus, output_corpus, crashes_storage): """Restores output dir and copies crashes after mutant is done running""" os.system(f"rm -rf {input_corpus}/*") diff --git a/fuzzers/aflsmart_muttfuzz/README.md b/fuzzers/aflsmart_muttfuzz/README.md new file mode 100644 index 000000000..df780998f --- /dev/null +++ b/fuzzers/aflsmart_muttfuzz/README.md @@ -0,0 +1,18 @@ +# Supported benchmarks + +[AFLSmart](https://github.com/aflsmart/aflsmart) is a structure-aware greybox-fuzzer and it is designed to work best for programs taking chunk-based file formats (e.g., JPEG, PNG and many others) as inputs. To fully enable its structure-aware mode, AFLSmart requires input models (e.g., grammar). So if you evaluate AFLSmart on FuzzBench, please focus on the results for the following benchmarks. We keep trying to include more input models so that more benchmarks will be supported. + +1. libpng-1.2.56 + +2. libjpeg-turbo-07-2017 + +3. libpcap_fuzz_both + +4. freetype2-2017 + +5. vorbis-2017-12-11 + +6. bloaty_fuzz_target + +Since the experiment summary diagram of the default FuzzBench report is automatically generated based on the results of all benchmarks, many of them have not been supported by AFLSmart, the ranking of AFLSmart in that diagram may not be correct. + diff --git a/fuzzers/aflsmart_muttfuzz/builder.Dockerfile b/fuzzers/aflsmart_muttfuzz/builder.Dockerfile new file mode 100644 index 000000000..a9f56fed3 --- /dev/null +++ b/fuzzers/aflsmart_muttfuzz/builder.Dockerfile @@ -0,0 +1,75 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ARG parent_image +FROM $parent_image + +# Install gcc-4.4 & g++-4.4 required by Peach while running on Ubuntu 16.04. +# Install Python2 and Pip2 required by AFLSmart on Ubuntu:20.04. +RUN echo 'deb http://dk.archive.ubuntu.com/ubuntu/ trusty main' >> \ + /etc/apt/sources.list && \ + echo 'deb http://dk.archive.ubuntu.com/ubuntu/ trusty universe' >> \ + /etc/apt/sources.list && \ + apt-get update && \ + apt-get install -y \ + gcc-4.4 \ + g++-4.4 \ + unzip \ + wget \ + tzdata \ + python2 && \ + curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py && \ + python2 get-pip.py && \ + rm /usr/bin/python && \ + ln -s /usr/bin/python2.7 /usr/bin/python + +# Install AFLSmart dependencies. +RUN dpkg --add-architecture i386 && \ + apt-get update && \ + apt-get install -y \ + apt-utils \ + libc6-dev-i386 \ + g++-multilib \ + mono-complete \ + software-properties-common + +# Download and compile AFLSmart. +RUN git clone https://github.com/aflsmart/aflsmart /afl && \ + cd /afl && \ + git checkout 4286ae47e0e5d8c412f91aae94ef9d11fb97dfd8 && \ + AFL_NO_X86=1 make + +# Setup Peach. +# Set CFLAGS="" so that we don't use the CFLAGS defined in OSS-Fuzz images. +# Use a copy of +# https://sourceforge.net/projects/peachfuzz/files/Peach/3.0/peach-3.0.202-source.zip +# to avoid network flakiness. +RUN cd /afl && \ + wget https://storage.googleapis.com/fuzzbench-files/peach-3.0.202-source.zip && \ + unzip peach-3.0.202-source.zip && \ + patch -p1 < peach-3.0.202.patch && \ + cd peach-3.0.202-source && \ + CC=gcc-4.4 CXX=g++-4.4 CFLAGS="" CXXFLAGS="-std=c++0x" ./waf configure && \ + CC=gcc-4.4 CXX=g++-4.4 CFLAGS="" CXXFLAGS="-std=c++0x" ./waf install + +# Use afl_driver.cpp from LLVM as our fuzzing library. +RUN wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/afl/afl_driver.cpp -O /afl/afl_driver.cpp && \ + clang -Wno-pointer-sign -c /afl/llvm_mode/afl-llvm-rt.o.c -I/afl && \ + clang++ -stdlib=libc++ -std=c++11 -O2 -c /afl/afl_driver.cpp && \ + ar r /libAFL.a *.o + +RUN apt-get update && apt-get install -y python3 + +RUN pip3 install --upgrade --force pip +RUN pip install muttfuzz \ No newline at end of file diff --git a/fuzzers/aflsmart_muttfuzz/fuzzer.py b/fuzzers/aflsmart_muttfuzz/fuzzer.py new file mode 100755 index 000000000..8422893e1 --- /dev/null +++ b/fuzzers/aflsmart_muttfuzz/fuzzer.py @@ -0,0 +1,68 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Integration code for AFLSmart fuzzer.""" + +import os +import shutil +import glob + +from fuzzers.aflsmart import fuzzer as aflsmart_fuzzer +from fuzzers.aflplusplus_muttfuzz import fuzzutil + + +def build(): + """Build benchmark.""" + aflsmart_fuzzer.build() + + +def restore_out(input_corpus, output_corpus, crashes_storage): + """Restores output dir and copies crashes after mutant is done running""" + os.system(f"rm -rf {input_corpus}/*") + os.system( + f"cp {output_corpus}/default/crashes/crashes.*/id* {crashes_storage}/") + os.system( + f"cp {output_corpus}/default/crashes/crashes.*/id* {input_corpus}/") + os.system(f"cp {output_corpus}/default/queue/* {input_corpus}/") + os.system(f"rm -rf {output_corpus}/*") + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run afl-fuzz on target.""" + os.environ["AFL_SKIP_CRASHES"] = "1" + os.environ["AFL_AUTORESUME"] = "1" + print(f"{input_corpus} {output_corpus} {target_binary}") + + crashes_storage = "/storage" + os.makedirs(crashes_storage, exist_ok=True) + + aflsmart_fuzzer_fn = lambda: aflsmart_fuzzer.fuzz( + input_corpus, output_corpus, target_binary) + + budget = 86_400 + fraction_mutant = 0.5 + time_per_mutant = 300 + initial_budget = 1_800 + post_mutant_fn = lambda: restore_out(input_corpus, output_corpus, + crashes_storage) + fuzzutil.fuzz_with_mutants_via_function( + aflsmart_fuzzer_fn, + target_binary, + budget, + time_per_mutant, + fraction_mutant, + initial_fn=aflsmart_fuzzer_fn, + initial_budget=initial_budget, + post_initial_fn=post_mutant_fn, + post_mutant_fn=post_mutant_fn, + ) diff --git a/fuzzers/aflsmart_muttfuzz/runner.Dockerfile b/fuzzers/aflsmart_muttfuzz/runner.Dockerfile new file mode 100644 index 000000000..1e9046888 --- /dev/null +++ b/fuzzers/aflsmart_muttfuzz/runner.Dockerfile @@ -0,0 +1,21 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM gcr.io/fuzzbench/base-image + +RUN apt-get update -y && \ + DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC \ + apt-get install -y \ + mono-complete \ + tzdata diff --git a/fuzzers/honggfuzz_muttfuzz/builder.Dockerfile b/fuzzers/honggfuzz_muttfuzz/builder.Dockerfile new file mode 100644 index 000000000..11a483288 --- /dev/null +++ b/fuzzers/honggfuzz_muttfuzz/builder.Dockerfile @@ -0,0 +1,36 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ARG parent_image +FROM $parent_image + +# honggfuzz requires libfd and libunwid. +RUN apt-get update -y && \ + apt-get install -y \ + libbfd-dev \ + libunwind-dev \ + libblocksruntime-dev \ + liblzma-dev + +# Download honggfuz version 2.3.1 + 0b4cd5b1c4cf26b7e022dc1deb931d9318c054cb +# Set CFLAGS use honggfuzz's defaults except for -mnative which can build CPU +# dependent code that may not work on the machines we actually fuzz on. +# Create an empty object file which will become the FUZZER_LIB lib (since +# honggfuzz doesn't need this when hfuzz-clang(++) is used). +RUN git clone https://github.com/google/honggfuzz.git /honggfuzz && \ + cd /honggfuzz && \ + git checkout oss-fuzz && \ + CFLAGS="-O3 -funroll-loops" make && \ + touch empty_lib.c && \ + cc -c -o empty_lib.o empty_lib.c \ No newline at end of file diff --git a/fuzzers/honggfuzz_muttfuzz/fuzzer.py b/fuzzers/honggfuzz_muttfuzz/fuzzer.py new file mode 100644 index 000000000..c4399e258 --- /dev/null +++ b/fuzzers/honggfuzz_muttfuzz/fuzzer.py @@ -0,0 +1,68 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Integration code for AFLSmart fuzzer.""" + +import os +import shutil +import glob + +from fuzzers.honggfuzz import fuzzer as honggfuzz_fuzzer +from fuzzers.aflplusplus_muttfuzz import fuzzutil + + +def build(): + """Build benchmark.""" + honggfuzz_fuzzer.build() + + +def restore_out(input_corpus, output_corpus, crashes_storage): + """Restores output dir and copies crashes after mutant is done running""" + os.system(f"rm -rf {input_corpus}/*") + os.system( + f"cp {output_corpus}/crashes/* {crashes_storage}/") + os.system( + f"cp {output_corpus}/crashes/* {input_corpus}/") + os.system(f"cp {output_corpus}/corpus/* {input_corpus}/") + os.system(f"rm -rf {output_corpus}/*") + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run afl-fuzz on target.""" + os.environ["AFL_SKIP_CRASHES"] = "1" + os.environ["AFL_AUTORESUME"] = "1" + print(f"{input_corpus} {output_corpus} {target_binary}") + + crashes_storage = "/storage" + os.makedirs(crashes_storage, exist_ok=True) + + honggfuzz_fuzzer_fn = lambda: honggfuzz_fuzzer.fuzz( + input_corpus, output_corpus, target_binary) + + budget = 86_400 + fraction_mutant = 0.5 + time_per_mutant = 300 + initial_budget = 1_800 + post_mutant_fn = lambda: restore_out(input_corpus, output_corpus, + crashes_storage) + fuzzutil.fuzz_with_mutants_via_function( + honggfuzz_fuzzer_fn, + target_binary, + budget, + time_per_mutant, + fraction_mutant, + initial_fn=honggfuzz_fuzzer_fn, + initial_budget=initial_budget, + post_initial_fn=post_mutant_fn, + post_mutant_fn=post_mutant_fn, + ) diff --git a/fuzzers/honggfuzz_muttfuzz/runner.Dockerfile b/fuzzers/honggfuzz_muttfuzz/runner.Dockerfile new file mode 100644 index 000000000..f3eb30039 --- /dev/null +++ b/fuzzers/honggfuzz_muttfuzz/runner.Dockerfile @@ -0,0 +1,18 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM gcr.io/fuzzbench/base-image + +# honggfuzz requires libfd and libunwid +RUN apt-get update -y && apt-get install -y libbfd-dev libunwind-dev diff --git a/fuzzers/libafll_muttfuzz/builder.Dockerfile b/fuzzers/libafll_muttfuzz/builder.Dockerfile new file mode 100644 index 000000000..3f726cfec --- /dev/null +++ b/fuzzers/libafll_muttfuzz/builder.Dockerfile @@ -0,0 +1,60 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ARG parent_image +FROM $parent_image + +# Uninstall old Rust & Install the latest one. +RUN if which rustup; then rustup self uninstall -y; fi && \ + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > /rustup.sh && \ + sh /rustup.sh --default-toolchain nightly-2023-09-21 -y && \ + rm /rustup.sh + +# Install dependencies. +RUN apt-get update && \ + apt-get remove -y llvm-10 && \ + apt-get install -y \ + build-essential \ + lsb-release wget software-properties-common gnupg && \ + apt-get install -y wget libstdc++5 libtool-bin automake flex bison \ + libglib2.0-dev libpixman-1-dev python3-setuptools unzip \ + apt-utils apt-transport-https ca-certificates joe curl && \ + wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && ./llvm.sh 17 + +RUN wget https://gist.githubusercontent.com/tokatoka/26f4ba95991c6e33139999976332aa8e/raw/698ac2087d58ce5c7a6ad59adce58dbfdc32bd46/createAliases.sh && chmod u+x ./createAliases.sh && ./createAliases.sh + +# Uninstall old Rust & Install the latest one. +RUN if which rustup; then rustup self uninstall -y; fi && \ + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > /rustup.sh && \ + sh /rustup.sh --default-toolchain nightly-2024-03-12 -y && \ + rm /rustup.sh + +# Download libafl. +RUN git clone https://github.com/AFLplusplus/LibAFL /libafl + +# Checkout a current commit +RUN cd /libafl && git pull && git checkout b4efb6151550a37f61a869acf2957a1b07894a93 || true +# Note that due a nightly bug it is currently fixed to a known version on top! + +# Compile libafl. +RUN cd /libafl && \ + unset CFLAGS CXXFLAGS && \ + export LIBAFL_EDGES_MAP_SIZE=2621440 && \ + cd ./fuzzers/fuzzbench && \ + PATH="/root/.cargo/bin/:$PATH" cargo build --profile release-fuzzbench --features no_link_main + +# Auxiliary weak references. +RUN cd /libafl/fuzzers/fuzzbench && \ + clang -c stub_rt.c && \ + ar r /stub_rt.a stub_rt.o diff --git a/fuzzers/libafll_muttfuzz/description.md b/fuzzers/libafll_muttfuzz/description.md new file mode 100644 index 000000000..ea9b947d6 --- /dev/null +++ b/fuzzers/libafll_muttfuzz/description.md @@ -0,0 +1,11 @@ +# libafl + +libafl fuzzer instance + - cmplog feature + - persistent mode + +Repository: [https://github.com/AFLplusplus/libafl/](https://github.com/AFLplusplus/libafl/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/libafll_muttfuzz/fuzzer.py b/fuzzers/libafll_muttfuzz/fuzzer.py new file mode 100755 index 000000000..f5715c2a1 --- /dev/null +++ b/fuzzers/libafll_muttfuzz/fuzzer.py @@ -0,0 +1,66 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Integration code for AFLSmart fuzzer.""" + +import os +import shutil +import glob + +from fuzzers.libafl import fuzzer as libafl_fuzzer +from fuzzers.aflplusplus_muttfuzz import fuzzutil + + +def build(): + """Build benchmark.""" + libafl_fuzzer.build() + + +def restore_out(input_corpus, output_corpus, crashes_storage): + """Restores output dir and copies crashes after mutant is done running""" + os.system(f"rm -rf {input_corpus}/*") + os.system( + f"cp {output_corpus}/crashes/* {crashes_storage}/") + os.system( + f"cp {output_corpus}/crashes/* {input_corpus}/") + os.system(f"cp {output_corpus}/queue/* {input_corpus}/") + os.system(f"rm -rf {output_corpus}/*") + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run afl-fuzz on target.""" + print(f"{input_corpus} {output_corpus} {target_binary}") + + crashes_storage = "/storage" + os.makedirs(crashes_storage, exist_ok=True) + + libafl_fuzzer_fn = lambda: libafl_fuzzer.fuzz( + input_corpus, output_corpus, target_binary) + + budget = 86_400 + fraction_mutant = 0.5 + time_per_mutant = 300 + initial_budget = 1_800 + post_mutant_fn = lambda: restore_out(input_corpus, output_corpus, + crashes_storage) + fuzzutil.fuzz_with_mutants_via_function( + libafl_fuzzer_fn, + target_binary, + budget, + time_per_mutant, + fraction_mutant, + initial_fn=libafl_fuzzer_fn, + initial_budget=initial_budget, + post_initial_fn=post_mutant_fn, + post_mutant_fn=post_mutant_fn, + ) diff --git a/fuzzers/libafll_muttfuzz/runner.Dockerfile b/fuzzers/libafll_muttfuzz/runner.Dockerfile new file mode 100644 index 000000000..f0c5eb6cc --- /dev/null +++ b/fuzzers/libafll_muttfuzz/runner.Dockerfile @@ -0,0 +1,25 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM gcr.io/fuzzbench/base-image + +RUN apt install libjemalloc2 + +# This makes interactive docker runs painless: +ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/out" +#ENV AFL_MAP_SIZE=2621440 +ENV PATH="$PATH:/out" +ENV AFL_SKIP_CPUFREQ=1 +ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 +ENV AFL_TESTCACHE_SIZE=2 diff --git a/fuzzers/libfuzzer_muttfuzz/builder.Dockerfile b/fuzzers/libfuzzer_muttfuzz/builder.Dockerfile new file mode 100644 index 000000000..7fe80447e --- /dev/null +++ b/fuzzers/libfuzzer_muttfuzz/builder.Dockerfile @@ -0,0 +1,26 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ARG parent_image +FROM $parent_image + +RUN git clone https://github.com/llvm/llvm-project.git /llvm-project && \ + cd /llvm-project && \ + git checkout 5cda4dc7b4d28fcd11307d4234c513ff779a1c6f && \ + cd compiler-rt/lib/fuzzer && \ + (for f in *.cpp; do \ + clang++ -stdlib=libc++ -fPIC -O2 -std=c++11 $f -c & \ + done && wait) && \ + ar r libFuzzer.a *.o && \ + cp libFuzzer.a /usr/lib diff --git a/fuzzers/libfuzzer_muttfuzz/fuzzer.py b/fuzzers/libfuzzer_muttfuzz/fuzzer.py new file mode 100755 index 000000000..546027693 --- /dev/null +++ b/fuzzers/libfuzzer_muttfuzz/fuzzer.py @@ -0,0 +1,66 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Integration code for AFLSmart fuzzer.""" + +import os +import shutil +import glob + +from fuzzers.libfuzzer import fuzzer as libfuzzer_fuzzer +from fuzzers.aflplusplus_muttfuzz import fuzzutil + + +def build(): + """Build benchmark.""" + libfuzzer_fuzzer.build() + + +def restore_out(input_corpus, output_corpus, crashes_storage): + """Restores output dir and copies crashes after mutant is done running""" + os.system(f"rm -rf {input_corpus}/*") + os.system( + f"cp {output_corpus}/crashes/* {crashes_storage}/") + os.system( + f"cp {output_corpus}/crashes/* {input_corpus}/") + os.system(f"cp {output_corpus}/corpus/* {input_corpus}/") + os.system(f"rm -rf {output_corpus}/*") + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run afl-fuzz on target.""" + print(f"{input_corpus} {output_corpus} {target_binary}") + + crashes_storage = "/storage" + os.makedirs(crashes_storage, exist_ok=True) + + libfuzzer_fuzzer_fn = lambda: libfuzzer_fuzzer.fuzz( + input_corpus, output_corpus, target_binary) + + budget = 86_400 + fraction_mutant = 0.5 + time_per_mutant = 300 + initial_budget = 1_800 + post_mutant_fn = lambda: restore_out(input_corpus, output_corpus, + crashes_storage) + fuzzutil.fuzz_with_mutants_via_function( + libfuzzer_fuzzer_fn, + target_binary, + budget, + time_per_mutant, + fraction_mutant, + initial_fn=libfuzzer_fuzzer_fn, + initial_budget=initial_budget, + post_initial_fn=post_mutant_fn, + post_mutant_fn=post_mutant_fn, + ) diff --git a/fuzzers/libfuzzer_muttfuzz/patch.diff b/fuzzers/libfuzzer_muttfuzz/patch.diff new file mode 100644 index 000000000..a31cc301e --- /dev/null +++ b/fuzzers/libfuzzer_muttfuzz/patch.diff @@ -0,0 +1,100 @@ +diff --git a/compiler-rt/lib/fuzzer/FuzzerFork.cpp b/compiler-rt/lib/fuzzer/FuzzerFork.cpp +index 84725d2..4e1a506 100644 +--- a/compiler-rt/lib/fuzzer/FuzzerFork.cpp ++++ b/compiler-rt/lib/fuzzer/FuzzerFork.cpp +@@ -26,6 +26,8 @@ + #include + #include + #include ++#include ++#include + + namespace fuzzer { + +@@ -70,6 +72,8 @@ struct FuzzJob { + std::string SeedListPath; + std::string CFPath; + size_t JobId; ++ bool Executing = false; ++ Vector CopiedSeeds; + + int DftTimeInSeconds = 0; + +@@ -124,7 +128,6 @@ struct GlobalEnv { + Cmd.addFlag("reload", "0"); // working in an isolated dir, no reload. + Cmd.addFlag("print_final_stats", "1"); + Cmd.addFlag("print_funcs", "0"); // no need to spend time symbolizing. +- Cmd.addFlag("max_total_time", std::to_string(std::min((size_t)300, JobId))); + Cmd.addFlag("stop_file", StopFile()); + if (!DataFlowBinary.empty()) { + Cmd.addFlag("data_flow_trace", DFTDir); +@@ -133,11 +136,10 @@ struct GlobalEnv { + } + auto Job = new FuzzJob; + std::string Seeds; +- if (size_t CorpusSubsetSize = +- std::min(Files.size(), (size_t)sqrt(Files.size() + 2))) { ++ if (size_t CorpusSubsetSize = Files.size()) { + auto Time1 = std::chrono::system_clock::now(); + for (size_t i = 0; i < CorpusSubsetSize; i++) { +- auto &SF = Files[Rand->SkewTowardsLast(Files.size())]; ++ auto &SF = Files[i]; + Seeds += (Seeds.empty() ? "" : ",") + SF; + CollectDFT(SF); + } +@@ -213,11 +215,20 @@ struct GlobalEnv { + Set NewFeatures, NewCov; + CrashResistantMerge(Args, {}, MergeCandidates, &FilesToAdd, Features, + &NewFeatures, Cov, &NewCov, Job->CFPath, false); ++ RemoveFile(Job->CFPath); + for (auto &Path : FilesToAdd) { +- auto U = FileToVector(Path); +- auto NewPath = DirPlusFile(MainCorpusDir, Hash(U)); +- WriteToFile(U, NewPath); +- Files.push_back(NewPath); ++ // Only merge files that have not been merged already. ++ if (std::find(Job->CopiedSeeds.begin(), Job->CopiedSeeds.end(), Path) == Job->CopiedSeeds.end()) { ++ // NOT THREAD SAFE: Fast check whether file still exists. ++ struct stat buffer; ++ if (stat (Path.c_str(), &buffer) == 0) { ++ auto U = FileToVector(Path); ++ auto NewPath = DirPlusFile(MainCorpusDir, Hash(U)); ++ WriteToFile(U, NewPath); ++ Files.push_back(NewPath); ++ Job->CopiedSeeds.push_back(Path); ++ } ++ } + } + Features.insert(NewFeatures.begin(), NewFeatures.end()); + Cov.insert(NewCov.begin(), NewCov.end()); +@@ -271,10 +282,19 @@ struct JobQueue { + } + }; + +-void WorkerThread(JobQueue *FuzzQ, JobQueue *MergeQ) { ++void WorkerThread(GlobalEnv *Env, JobQueue *FuzzQ, JobQueue *MergeQ) { + while (auto Job = FuzzQ->Pop()) { +- // Printf("WorkerThread: job %p\n", Job); ++ Job->Executing = true; ++ int Sleep_ms = 5 * 60 * 1000; ++ std::thread([=]() { ++ std::this_thread::sleep_for(std::chrono::milliseconds(Sleep_ms / 5)); ++ while (Job->Executing) { ++ Env->RunOneMergeJob(Job); ++ std::this_thread::sleep_for(std::chrono::milliseconds(Sleep_ms)); ++ } ++ }).detach(); + Job->ExitCode = ExecuteCommand(Job->Cmd); ++ Job->Executing = false; + MergeQ->Push(Job); + } + } +@@ -335,7 +355,7 @@ void FuzzWithFork(Random &Rand, const FuzzingOptions &Options, + size_t JobId = 1; + Vector Threads; + for (int t = 0; t < NumJobs; t++) { +- Threads.push_back(std::thread(WorkerThread, &FuzzQ, &MergeQ)); ++ Threads.push_back(std::thread(WorkerThread, &Env, &FuzzQ, &MergeQ)); + FuzzQ.Push(Env.CreateNewJob(JobId++)); + } + diff --git a/fuzzers/libfuzzer_muttfuzz/runner.Dockerfile b/fuzzers/libfuzzer_muttfuzz/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/libfuzzer_muttfuzz/runner.Dockerfile @@ -0,0 +1,15 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM gcr.io/fuzzbench/base-image From 12e8487f2057d7660ef085d8c2c5380519c6a1cd Mon Sep 17 00:00:00 2001 From: Kush Jain Date: Tue, 23 Apr 2024 17:09:20 -0400 Subject: [PATCH 07/10] Formatting --- fuzzers/aflplusplus_muttfuzz/fuzzer.py | 1 + fuzzers/aflsmart_muttfuzz/fuzzer.py | 4 ++-- fuzzers/honggfuzz_muttfuzz/fuzzer.py | 10 ++++------ fuzzers/libafll_muttfuzz/fuzzer.py | 14 ++++++-------- fuzzers/libfuzzer_muttfuzz/fuzzer.py | 10 ++++------ 5 files changed, 17 insertions(+), 22 deletions(-) diff --git a/fuzzers/aflplusplus_muttfuzz/fuzzer.py b/fuzzers/aflplusplus_muttfuzz/fuzzer.py index 408bd218f..e3abf7c40 100644 --- a/fuzzers/aflplusplus_muttfuzz/fuzzer.py +++ b/fuzzers/aflplusplus_muttfuzz/fuzzer.py @@ -30,6 +30,7 @@ def build(): # pylint: disable=too-many-branches,too-many-statements """Build benchmark.""" aflplusplus_fuzzer.build() + def restore_out(input_corpus, output_corpus, crashes_storage): """Restores output dir and copies crashes after mutant is done running""" os.system(f"rm -rf {input_corpus}/*") diff --git a/fuzzers/aflsmart_muttfuzz/fuzzer.py b/fuzzers/aflsmart_muttfuzz/fuzzer.py index 8422893e1..20f00557a 100755 --- a/fuzzers/aflsmart_muttfuzz/fuzzer.py +++ b/fuzzers/aflsmart_muttfuzz/fuzzer.py @@ -13,12 +13,12 @@ # limitations under the License. """Integration code for AFLSmart fuzzer.""" +import glob import os import shutil -import glob -from fuzzers.aflsmart import fuzzer as aflsmart_fuzzer from fuzzers.aflplusplus_muttfuzz import fuzzutil +from fuzzers.aflsmart import fuzzer as aflsmart_fuzzer def build(): diff --git a/fuzzers/honggfuzz_muttfuzz/fuzzer.py b/fuzzers/honggfuzz_muttfuzz/fuzzer.py index c4399e258..1dffd222d 100644 --- a/fuzzers/honggfuzz_muttfuzz/fuzzer.py +++ b/fuzzers/honggfuzz_muttfuzz/fuzzer.py @@ -13,12 +13,12 @@ # limitations under the License. """Integration code for AFLSmart fuzzer.""" +import glob import os import shutil -import glob -from fuzzers.honggfuzz import fuzzer as honggfuzz_fuzzer from fuzzers.aflplusplus_muttfuzz import fuzzutil +from fuzzers.honggfuzz import fuzzer as honggfuzz_fuzzer def build(): @@ -29,10 +29,8 @@ def build(): def restore_out(input_corpus, output_corpus, crashes_storage): """Restores output dir and copies crashes after mutant is done running""" os.system(f"rm -rf {input_corpus}/*") - os.system( - f"cp {output_corpus}/crashes/* {crashes_storage}/") - os.system( - f"cp {output_corpus}/crashes/* {input_corpus}/") + os.system(f"cp {output_corpus}/crashes/* {crashes_storage}/") + os.system(f"cp {output_corpus}/crashes/* {input_corpus}/") os.system(f"cp {output_corpus}/corpus/* {input_corpus}/") os.system(f"rm -rf {output_corpus}/*") diff --git a/fuzzers/libafll_muttfuzz/fuzzer.py b/fuzzers/libafll_muttfuzz/fuzzer.py index f5715c2a1..af51cd69d 100755 --- a/fuzzers/libafll_muttfuzz/fuzzer.py +++ b/fuzzers/libafll_muttfuzz/fuzzer.py @@ -13,12 +13,12 @@ # limitations under the License. """Integration code for AFLSmart fuzzer.""" +import glob import os import shutil -import glob -from fuzzers.libafl import fuzzer as libafl_fuzzer from fuzzers.aflplusplus_muttfuzz import fuzzutil +from fuzzers.libafl import fuzzer as libafl_fuzzer def build(): @@ -29,10 +29,8 @@ def build(): def restore_out(input_corpus, output_corpus, crashes_storage): """Restores output dir and copies crashes after mutant is done running""" os.system(f"rm -rf {input_corpus}/*") - os.system( - f"cp {output_corpus}/crashes/* {crashes_storage}/") - os.system( - f"cp {output_corpus}/crashes/* {input_corpus}/") + os.system(f"cp {output_corpus}/crashes/* {crashes_storage}/") + os.system(f"cp {output_corpus}/crashes/* {input_corpus}/") os.system(f"cp {output_corpus}/queue/* {input_corpus}/") os.system(f"rm -rf {output_corpus}/*") @@ -44,8 +42,8 @@ def fuzz(input_corpus, output_corpus, target_binary): crashes_storage = "/storage" os.makedirs(crashes_storage, exist_ok=True) - libafl_fuzzer_fn = lambda: libafl_fuzzer.fuzz( - input_corpus, output_corpus, target_binary) + libafl_fuzzer_fn = lambda: libafl_fuzzer.fuzz(input_corpus, output_corpus, + target_binary) budget = 86_400 fraction_mutant = 0.5 diff --git a/fuzzers/libfuzzer_muttfuzz/fuzzer.py b/fuzzers/libfuzzer_muttfuzz/fuzzer.py index 546027693..fea62e628 100755 --- a/fuzzers/libfuzzer_muttfuzz/fuzzer.py +++ b/fuzzers/libfuzzer_muttfuzz/fuzzer.py @@ -13,12 +13,12 @@ # limitations under the License. """Integration code for AFLSmart fuzzer.""" +import glob import os import shutil -import glob -from fuzzers.libfuzzer import fuzzer as libfuzzer_fuzzer from fuzzers.aflplusplus_muttfuzz import fuzzutil +from fuzzers.libfuzzer import fuzzer as libfuzzer_fuzzer def build(): @@ -29,10 +29,8 @@ def build(): def restore_out(input_corpus, output_corpus, crashes_storage): """Restores output dir and copies crashes after mutant is done running""" os.system(f"rm -rf {input_corpus}/*") - os.system( - f"cp {output_corpus}/crashes/* {crashes_storage}/") - os.system( - f"cp {output_corpus}/crashes/* {input_corpus}/") + os.system(f"cp {output_corpus}/crashes/* {crashes_storage}/") + os.system(f"cp {output_corpus}/crashes/* {input_corpus}/") os.system(f"cp {output_corpus}/corpus/* {input_corpus}/") os.system(f"rm -rf {output_corpus}/*") From 93e14cae299679ecd66d86a115f3704aa3b4640d Mon Sep 17 00:00:00 2001 From: Kush Jain Date: Tue, 23 Apr 2024 21:13:30 -0400 Subject: [PATCH 08/10] Fixing typo in naming --- fuzzers/{libafll_muttfuzz => libafl_muttfuzz}/builder.Dockerfile | 0 fuzzers/{libafll_muttfuzz => libafl_muttfuzz}/description.md | 0 fuzzers/{libafll_muttfuzz => libafl_muttfuzz}/fuzzer.py | 0 fuzzers/{libafll_muttfuzz => libafl_muttfuzz}/runner.Dockerfile | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename fuzzers/{libafll_muttfuzz => libafl_muttfuzz}/builder.Dockerfile (100%) rename fuzzers/{libafll_muttfuzz => libafl_muttfuzz}/description.md (100%) rename fuzzers/{libafll_muttfuzz => libafl_muttfuzz}/fuzzer.py (100%) rename fuzzers/{libafll_muttfuzz => libafl_muttfuzz}/runner.Dockerfile (100%) diff --git a/fuzzers/libafll_muttfuzz/builder.Dockerfile b/fuzzers/libafl_muttfuzz/builder.Dockerfile similarity index 100% rename from fuzzers/libafll_muttfuzz/builder.Dockerfile rename to fuzzers/libafl_muttfuzz/builder.Dockerfile diff --git a/fuzzers/libafll_muttfuzz/description.md b/fuzzers/libafl_muttfuzz/description.md similarity index 100% rename from fuzzers/libafll_muttfuzz/description.md rename to fuzzers/libafl_muttfuzz/description.md diff --git a/fuzzers/libafll_muttfuzz/fuzzer.py b/fuzzers/libafl_muttfuzz/fuzzer.py similarity index 100% rename from fuzzers/libafll_muttfuzz/fuzzer.py rename to fuzzers/libafl_muttfuzz/fuzzer.py diff --git a/fuzzers/libafll_muttfuzz/runner.Dockerfile b/fuzzers/libafl_muttfuzz/runner.Dockerfile similarity index 100% rename from fuzzers/libafll_muttfuzz/runner.Dockerfile rename to fuzzers/libafl_muttfuzz/runner.Dockerfile From 520ca0716f6029f3781d15f095503501d9e3211c Mon Sep 17 00:00:00 2001 From: Kush Jain Date: Thu, 2 May 2024 11:34:50 -0400 Subject: [PATCH 09/10] No reset, just continue --- fuzzers/aflplusplus_muttfuzz/fuzzer.py | 15 ++++++++------- fuzzers/aflsmart_muttfuzz/fuzzer.py | 15 ++++++++------- fuzzers/honggfuzz_muttfuzz/fuzzer.py | 12 ++++++------ fuzzers/libafl_muttfuzz/fuzzer.py | 11 ++++++----- fuzzers/libfuzzer_muttfuzz/fuzzer.py | 11 ++++++----- 5 files changed, 34 insertions(+), 30 deletions(-) diff --git a/fuzzers/aflplusplus_muttfuzz/fuzzer.py b/fuzzers/aflplusplus_muttfuzz/fuzzer.py index e3abf7c40..7999d34d7 100644 --- a/fuzzers/aflplusplus_muttfuzz/fuzzer.py +++ b/fuzzers/aflplusplus_muttfuzz/fuzzer.py @@ -33,13 +33,14 @@ def build(): # pylint: disable=too-many-branches,too-many-statements def restore_out(input_corpus, output_corpus, crashes_storage): """Restores output dir and copies crashes after mutant is done running""" - os.system(f"rm -rf {input_corpus}/*") - os.system( - f"cp {output_corpus}/default/crashes/crashes.*/id* {crashes_storage}/") - os.system( - f"cp {output_corpus}/default/crashes/crashes.*/id* {input_corpus}/") - os.system(f"cp {output_corpus}/default/queue/* {input_corpus}/") - os.system(f"rm -rf {output_corpus}/*") + # os.system(f"rm -rf {input_corpus}/*") + # os.system( + # f"cp {output_corpus}/default/crashes/crashes.*/id* {crashes_storage}/") + # os.system( + # f"cp {output_corpus}/default/crashes/crashes.*/id* {input_corpus}/") + # os.system(f"cp {output_corpus}/default/queue/* {input_corpus}/") + # os.system(f"rm -rf {output_corpus}/*") + pass def fuzz(input_corpus, output_corpus, target_binary): diff --git a/fuzzers/aflsmart_muttfuzz/fuzzer.py b/fuzzers/aflsmart_muttfuzz/fuzzer.py index 20f00557a..88ad49327 100755 --- a/fuzzers/aflsmart_muttfuzz/fuzzer.py +++ b/fuzzers/aflsmart_muttfuzz/fuzzer.py @@ -28,13 +28,14 @@ def build(): def restore_out(input_corpus, output_corpus, crashes_storage): """Restores output dir and copies crashes after mutant is done running""" - os.system(f"rm -rf {input_corpus}/*") - os.system( - f"cp {output_corpus}/default/crashes/crashes.*/id* {crashes_storage}/") - os.system( - f"cp {output_corpus}/default/crashes/crashes.*/id* {input_corpus}/") - os.system(f"cp {output_corpus}/default/queue/* {input_corpus}/") - os.system(f"rm -rf {output_corpus}/*") + # os.system(f"rm -rf {input_corpus}/*") + # os.system( + # f"cp {output_corpus}/default/crashes/crashes.*/id* {crashes_storage}/") + # os.system( + # f"cp {output_corpus}/default/crashes/crashes.*/id* {input_corpus}/") + # os.system(f"cp {output_corpus}/default/queue/* {input_corpus}/") + # os.system(f"rm -rf {output_corpus}/*") + pass def fuzz(input_corpus, output_corpus, target_binary): diff --git a/fuzzers/honggfuzz_muttfuzz/fuzzer.py b/fuzzers/honggfuzz_muttfuzz/fuzzer.py index 1dffd222d..5cc31eee1 100644 --- a/fuzzers/honggfuzz_muttfuzz/fuzzer.py +++ b/fuzzers/honggfuzz_muttfuzz/fuzzer.py @@ -28,12 +28,12 @@ def build(): def restore_out(input_corpus, output_corpus, crashes_storage): """Restores output dir and copies crashes after mutant is done running""" - os.system(f"rm -rf {input_corpus}/*") - os.system(f"cp {output_corpus}/crashes/* {crashes_storage}/") - os.system(f"cp {output_corpus}/crashes/* {input_corpus}/") - os.system(f"cp {output_corpus}/corpus/* {input_corpus}/") - os.system(f"rm -rf {output_corpus}/*") - + # os.system(f"rm -rf {input_corpus}/*") + # os.system(f"cp {output_corpus}/crashes/* {crashes_storage}/") + # os.system(f"cp {output_corpus}/crashes/* {input_corpus}/") + # os.system(f"cp {output_corpus}/corpus/* {input_corpus}/") + # os.system(f"rm -rf {output_corpus}/*") + pass def fuzz(input_corpus, output_corpus, target_binary): """Run afl-fuzz on target.""" diff --git a/fuzzers/libafl_muttfuzz/fuzzer.py b/fuzzers/libafl_muttfuzz/fuzzer.py index af51cd69d..3770ac7c6 100755 --- a/fuzzers/libafl_muttfuzz/fuzzer.py +++ b/fuzzers/libafl_muttfuzz/fuzzer.py @@ -28,11 +28,12 @@ def build(): def restore_out(input_corpus, output_corpus, crashes_storage): """Restores output dir and copies crashes after mutant is done running""" - os.system(f"rm -rf {input_corpus}/*") - os.system(f"cp {output_corpus}/crashes/* {crashes_storage}/") - os.system(f"cp {output_corpus}/crashes/* {input_corpus}/") - os.system(f"cp {output_corpus}/queue/* {input_corpus}/") - os.system(f"rm -rf {output_corpus}/*") + # os.system(f"rm -rf {input_corpus}/*") + # os.system(f"cp {output_corpus}/crashes/* {crashes_storage}/") + # os.system(f"cp {output_corpus}/crashes/* {input_corpus}/") + # os.system(f"cp {output_corpus}/queue/* {input_corpus}/") + # os.system(f"rm -rf {output_corpus}/*") + pass def fuzz(input_corpus, output_corpus, target_binary): diff --git a/fuzzers/libfuzzer_muttfuzz/fuzzer.py b/fuzzers/libfuzzer_muttfuzz/fuzzer.py index fea62e628..b768c8d19 100755 --- a/fuzzers/libfuzzer_muttfuzz/fuzzer.py +++ b/fuzzers/libfuzzer_muttfuzz/fuzzer.py @@ -28,11 +28,12 @@ def build(): def restore_out(input_corpus, output_corpus, crashes_storage): """Restores output dir and copies crashes after mutant is done running""" - os.system(f"rm -rf {input_corpus}/*") - os.system(f"cp {output_corpus}/crashes/* {crashes_storage}/") - os.system(f"cp {output_corpus}/crashes/* {input_corpus}/") - os.system(f"cp {output_corpus}/corpus/* {input_corpus}/") - os.system(f"rm -rf {output_corpus}/*") + # os.system(f"rm -rf {input_corpus}/*") + # os.system(f"cp {output_corpus}/crashes/* {crashes_storage}/") + # os.system(f"cp {output_corpus}/crashes/* {input_corpus}/") + # os.system(f"cp {output_corpus}/corpus/* {input_corpus}/") + # os.system(f"rm -rf {output_corpus}/*") + pass def fuzz(input_corpus, output_corpus, target_binary): From dc12ff0a605e1353985d2e1fe2c1094a4480fbe9 Mon Sep 17 00:00:00 2001 From: Kush Jain Date: Thu, 2 May 2024 11:38:03 -0400 Subject: [PATCH 10/10] Formatting fix --- fuzzers/honggfuzz_muttfuzz/fuzzer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/fuzzers/honggfuzz_muttfuzz/fuzzer.py b/fuzzers/honggfuzz_muttfuzz/fuzzer.py index 5cc31eee1..dbffb86b1 100644 --- a/fuzzers/honggfuzz_muttfuzz/fuzzer.py +++ b/fuzzers/honggfuzz_muttfuzz/fuzzer.py @@ -35,6 +35,7 @@ def restore_out(input_corpus, output_corpus, crashes_storage): # os.system(f"rm -rf {output_corpus}/*") pass + def fuzz(input_corpus, output_corpus, target_binary): """Run afl-fuzz on target.""" os.environ["AFL_SKIP_CRASHES"] = "1"