From 6a8a86e6a0bda940a570b84a54a7563cfa2e620c Mon Sep 17 00:00:00 2001 From: Ridwan Shariffdeen Date: Mon, 7 Aug 2023 15:17:48 +0800 Subject: [PATCH 1/7] add sievefuzz --- fuzzers/SieveFuzz/builder.Dockerfile | 59 +++++++++++ fuzzers/SieveFuzz/fuzzer.py | 141 +++++++++++++++++++++++++++ fuzzers/SieveFuzz/runner.Dockerfile | 15 +++ 3 files changed, 215 insertions(+) create mode 100644 fuzzers/SieveFuzz/builder.Dockerfile create mode 100755 fuzzers/SieveFuzz/fuzzer.py create mode 100644 fuzzers/SieveFuzz/runner.Dockerfile diff --git a/fuzzers/SieveFuzz/builder.Dockerfile b/fuzzers/SieveFuzz/builder.Dockerfile new file mode 100644 index 000000000..c03903512 --- /dev/null +++ b/fuzzers/SieveFuzz/builder.Dockerfile @@ -0,0 +1,59 @@ +# 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 + +ARG DEBIAN_FRONTEND=noninteractive + +RUN apt update && \ + apt install -y \ + silversearcher-ag beanstalkd gdb screen patchelf apt-transport-https ca-certificates clang-9 libclang-9-dev\ + gcc-7 g++-7 sudo curl wget build-essential make cmake ninja-build git subversion python3 python3-dev python3-pip autoconf automake &&\ + python3 -m pip install --upgrade pip && python3 -m pip install greenstalk psutil + +RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-9 10 \ + --slave /usr/bin/clang++ clang++ /usr/bin/clang++-9 \ + --slave /usr/bin/opt opt /usr/bin/opt-9 +RUN update-alternatives --install /usr/lib/llvm llvm /usr/lib/llvm-9 20 \ + --slave /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-9 \ + --slave /usr/bin/llvm-link llvm-link /usr/bin/llvm-link-9 + + +RUN apt-get -y install locales && locale-gen en_US.UTF-8 +ENV LC_ALL="en_US.UTF-8" + +# Download and compile SieveFuzz +RUN git clone https://github.com/HexHive/SieveFuzz /afl && \ + cd /afl && \ + git checkout 1751673ed6c56b7dc69b71ef07ace49867e3cfa4 && \ + cd third_party && ./install_svf.sh + +RUN unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ && ./install_sievefuzz.sh + +RUN cp -r /afl/gllvm_bins /afl/third_party/SVF/Release-build/bin + + +# Use afl_driver.cpp from LLVM as our fuzzing library. +RUN apt-get update && \ + apt-get install wget -y && \ + wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/afl/afl_driver.cpp -O /afl/third_party/sievefuzz/afl_driver.cpp && \ + cd /afl/third_party/sievefuzz && \ + clang -D AF -D TRACE_METRIC -Wno-pointer-sign -c llvm_mode/afl-llvm-rt.o.c -I. -Iinclude && \ + clang++ -stdlib=libc++ -std=c++11 -O2 -c afl_driver.cpp && \ + ar r /libAFL.a *.o + + diff --git a/fuzzers/SieveFuzz/fuzzer.py b/fuzzers/SieveFuzz/fuzzer.py new file mode 100755 index 000000000..18cb71229 --- /dev/null +++ b/fuzzers/SieveFuzz/fuzzer.py @@ -0,0 +1,141 @@ +# 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 AFL fuzzer.""" + +import json +import os +import shutil +import subprocess + +from fuzzers import utils + + +def prepare_build_environment(): + """Set environment variables used to build targets for AFL-based + fuzzers.""" + cflags = ['-fsanitize-coverage=trace-pc-guard'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cflags) + + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + os.environ['FUZZER_LIB'] = '/libAFL.a' + + +def build(): + """Build benchmark.""" + prepare_build_environment() + + utils.build_benchmark() + + print('[post_build] Copying afl-fuzz to $OUT directory') + # Copy out the afl-fuzz binary as a build artifact. + shutil.copy('/afl/afl-fuzz', os.environ['OUT']) + + +def get_stats(output_corpus, fuzzer_log): # pylint: disable=unused-argument + """Gets fuzzer stats for AFL.""" + # Get a dictionary containing the stats AFL reports. + stats_file = os.path.join(output_corpus, 'fuzzer_stats') + if not os.path.exists(stats_file): + print('Can\'t find fuzzer_stats') + return '{}' + with open(stats_file, encoding='utf-8') as file_handle: + stats_file_lines = file_handle.read().splitlines() + stats_file_dict = {} + for stats_line in stats_file_lines: + key, value = stats_line.split(': ') + stats_file_dict[key.strip()] = value.strip() + + # Report to FuzzBench the stats it accepts. + stats = {'execs_per_sec': float(stats_file_dict['execs_per_sec'])} + return json.dumps(stats) + + +def prepare_fuzz_environment(input_corpus): + """Prepare to fuzz with AFL or another AFL-based fuzzer.""" + # Tell AFL to not use its terminal UI so we get usable logs. + os.environ['AFL_NO_UI'] = '1' + # Skip AFL's CPU frequency check (fails on Docker). + os.environ['AFL_SKIP_CPUFREQ'] = '1' + # No need to bind affinity to one core, Docker enforces 1 core usage. + os.environ['AFL_NO_AFFINITY'] = '1' + # AFL will abort on startup if the core pattern sends notifications to + # external programs. We don't care about this. + os.environ['AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES'] = '1' + # Don't exit when crashes are found. This can happen when corpus from + # OSS-Fuzz is used. + os.environ['AFL_SKIP_CRASHES'] = '1' + # Shuffle the queue + os.environ['AFL_SHUFFLE_QUEUE'] = '1' + + # AFL needs at least one non-empty seed to start. + utils.create_seed_file_for_empty_corpus(input_corpus) + + +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 run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=None, + hide_output=False): + """Run afl-fuzz.""" + # Spawn the afl fuzzing process. + print('[run_afl_fuzz] Running target with afl-fuzz') + command = [ + './afl-fuzz', + '-i', + input_corpus, + '-o', + output_corpus, + # Use no memory limit as ASAN doesn't play nicely with one. + '-m', + 'none', + '-t', + '1000+', # Use same default 1 sec timeout, but add '+' to skip hangs. + ] + # Use '-d' to skip deterministic mode, as long as it it compatible with + # additional flags. + if not additional_flags or check_skip_det_compatible(additional_flags): + command.append('-d') + if additional_flags: + command.extend(additional_flags) + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + command.extend(['-x', dictionary_path]) + command += [ + '--', + target_binary, + # Pass INT_MAX to afl the maximize the number of persistent loops it + # performs. + '2147483647' + ] + print('[run_afl_fuzz] Running command: ' + ' '.join(command)) + output_stream = subprocess.DEVNULL if hide_output else None + subprocess.check_call(command, stdout=output_stream, stderr=output_stream) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run afl-fuzz on target.""" + prepare_fuzz_environment(input_corpus) + + run_afl_fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/SieveFuzz/runner.Dockerfile b/fuzzers/SieveFuzz/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/SieveFuzz/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 1370745728451d0695fc8cef6d5166c07e581f18 Mon Sep 17 00:00:00 2001 From: Ridwan Shariffdeen Date: Mon, 7 Aug 2023 15:17:56 +0800 Subject: [PATCH 2/7] ignore idea dir --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index e752b94a2..ff6eeee4c 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,6 @@ docker/generated.mk # Vim backup files. .*.swp + +# IntelliJ files +.idea From e8082171fa17ddeec5866b654684874a1cd9dc55 Mon Sep 17 00:00:00 2001 From: Ridwan Shariffdeen Date: Mon, 7 Aug 2023 15:35:29 +0800 Subject: [PATCH 3/7] rename --- fuzzers/{SieveFuzz => sievefuzz}/builder.Dockerfile | 0 fuzzers/{SieveFuzz => sievefuzz}/fuzzer.py | 0 fuzzers/{SieveFuzz => sievefuzz}/runner.Dockerfile | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename fuzzers/{SieveFuzz => sievefuzz}/builder.Dockerfile (100%) rename fuzzers/{SieveFuzz => sievefuzz}/fuzzer.py (100%) rename fuzzers/{SieveFuzz => sievefuzz}/runner.Dockerfile (100%) diff --git a/fuzzers/SieveFuzz/builder.Dockerfile b/fuzzers/sievefuzz/builder.Dockerfile similarity index 100% rename from fuzzers/SieveFuzz/builder.Dockerfile rename to fuzzers/sievefuzz/builder.Dockerfile diff --git a/fuzzers/SieveFuzz/fuzzer.py b/fuzzers/sievefuzz/fuzzer.py similarity index 100% rename from fuzzers/SieveFuzz/fuzzer.py rename to fuzzers/sievefuzz/fuzzer.py diff --git a/fuzzers/SieveFuzz/runner.Dockerfile b/fuzzers/sievefuzz/runner.Dockerfile similarity index 100% rename from fuzzers/SieveFuzz/runner.Dockerfile rename to fuzzers/sievefuzz/runner.Dockerfile From 2fda5a43b7f03de310fd0baac36d7ebd22dac5dc Mon Sep 17 00:00:00 2001 From: Ridwan Shariffdeen Date: Mon, 7 Aug 2023 16:11:03 +0800 Subject: [PATCH 4/7] fix bug: change dir --- fuzzers/sievefuzz/builder.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzzers/sievefuzz/builder.Dockerfile b/fuzzers/sievefuzz/builder.Dockerfile index c03903512..e5b7e7800 100644 --- a/fuzzers/sievefuzz/builder.Dockerfile +++ b/fuzzers/sievefuzz/builder.Dockerfile @@ -40,7 +40,7 @@ RUN git clone https://github.com/HexHive/SieveFuzz /afl && \ git checkout 1751673ed6c56b7dc69b71ef07ace49867e3cfa4 && \ cd third_party && ./install_svf.sh -RUN unset CFLAGS CXXFLAGS && \ +RUN cd /afl/third_party && unset CFLAGS CXXFLAGS && \ export CC=clang AFL_NO_X86=1 && \ PYTHON_INCLUDE=/ && ./install_sievefuzz.sh From c16994dfe87031b7a80d4a8a0935e11fbeca44c4 Mon Sep 17 00:00:00 2001 From: Ridwan Shariffdeen Date: Mon, 7 Aug 2023 17:25:39 +0800 Subject: [PATCH 5/7] add only relevant file to lib archive --- fuzzers/sievefuzz/builder.Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fuzzers/sievefuzz/builder.Dockerfile b/fuzzers/sievefuzz/builder.Dockerfile index e5b7e7800..757fce646 100644 --- a/fuzzers/sievefuzz/builder.Dockerfile +++ b/fuzzers/sievefuzz/builder.Dockerfile @@ -54,6 +54,8 @@ RUN apt-get update && \ cd /afl/third_party/sievefuzz && \ clang -D AF -D TRACE_METRIC -Wno-pointer-sign -c llvm_mode/afl-llvm-rt.o.c -I. -Iinclude && \ clang++ -stdlib=libc++ -std=c++11 -O2 -c afl_driver.cpp && \ - ar r /libAFL.a *.o + ar r /libAFL.a afl_driver.o afl-llvm-rt.o + + From 464957545f13088eb55667a2bfc4e1d957e2df55 Mon Sep 17 00:00:00 2001 From: Ridwan Shariffdeen Date: Mon, 7 Aug 2023 17:49:51 +0800 Subject: [PATCH 6/7] install runtime dep libpython3.8 --- fuzzers/sievefuzz/runner.Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/fuzzers/sievefuzz/runner.Dockerfile b/fuzzers/sievefuzz/runner.Dockerfile index 0d6cf004e..43a708a0e 100644 --- a/fuzzers/sievefuzz/runner.Dockerfile +++ b/fuzzers/sievefuzz/runner.Dockerfile @@ -13,3 +13,4 @@ # limitations under the License. FROM gcr.io/fuzzbench/base-image +RUN apt-get install -y python3.8-dev From f2fcba1263e742087b7d725faebd2dc0c30eac5a Mon Sep 17 00:00:00 2001 From: Ridwan Shariffdeen Date: Mon, 7 Aug 2023 17:49:59 +0800 Subject: [PATCH 7/7] update driver --- fuzzers/sievefuzz/fuzzer.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/fuzzers/sievefuzz/fuzzer.py b/fuzzers/sievefuzz/fuzzer.py index 18cb71229..3f44181e9 100755 --- a/fuzzers/sievefuzz/fuzzer.py +++ b/fuzzers/sievefuzz/fuzzer.py @@ -21,6 +21,17 @@ from fuzzers import utils +def is_benchmark(name): + """Check if the benchmark contains the string |name|""" + benchmark = os.getenv('BENCHMARK', None) + return benchmark is not None and name in benchmark + +def fix_fuzzer_lib(): + """Fix FUZZER_LIB for certain benchmarks""" + + shutil.copy('/libAFL.a', '/usr/lib/libFuzzingEngine.a') + + def prepare_build_environment(): """Set environment variables used to build targets for AFL-based fuzzers.""" @@ -32,6 +43,9 @@ def prepare_build_environment(): os.environ['CXX'] = 'clang++' os.environ['FUZZER_LIB'] = '/libAFL.a' + # Fix FUZZER_LIB for various benchmarks. + fix_fuzzer_lib() + def build(): """Build benchmark.""" @@ -41,7 +55,7 @@ def build(): print('[post_build] Copying afl-fuzz to $OUT directory') # Copy out the afl-fuzz binary as a build artifact. - shutil.copy('/afl/afl-fuzz', os.environ['OUT']) + shutil.copy('/afl/third_party/sievefuzz/afl-fuzz', os.environ['OUT']) def get_stats(output_corpus, fuzzer_log): # pylint: disable=unused-argument @@ -100,7 +114,7 @@ def run_afl_fuzz(input_corpus, hide_output=False): """Run afl-fuzz.""" # Spawn the afl fuzzing process. - print('[run_afl_fuzz] Running target with afl-fuzz') + print('[run_afl_fuzz] Running target with sievefuzz') command = [ './afl-fuzz', '-i',