diff --git a/fuzzers/afl_257/builder.Dockerfile b/fuzzers/afl_257/builder.Dockerfile new file mode 100644 index 000000000..94d7f5076 --- /dev/null +++ b/fuzzers/afl_257/builder.Dockerfile @@ -0,0 +1,33 @@ +# 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 + +# Download and compile AFL v2.57b. +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone \ + --depth 1 \ + --branch v2.57b \ + https://github.com/google/AFL.git /afl && \ + cd /afl && \ + CFLAGS= CXXFLAGS= AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/afl_random_favored/fuzzer.py b/fuzzers/afl_257/fuzzer.py similarity index 97% rename from fuzzers/afl_random_favored/fuzzer.py rename to fuzzers/afl_257/fuzzer.py index 7c4c44180..18cb71229 100755 --- a/fuzzers/afl_random_favored/fuzzer.py +++ b/fuzzers/afl_257/fuzzer.py @@ -48,6 +48,9 @@ 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 = {} diff --git a/fuzzers/afl_random_favored/runner.Dockerfile b/fuzzers/afl_257/runner.Dockerfile similarity index 100% rename from fuzzers/afl_random_favored/runner.Dockerfile rename to fuzzers/afl_257/runner.Dockerfile diff --git a/fuzzers/afl_mb/builder.Dockerfile b/fuzzers/afl_mb/builder.Dockerfile new file mode 100644 index 000000000..8f825c0f9 --- /dev/null +++ b/fuzzers/afl_mb/builder.Dockerfile @@ -0,0 +1,32 @@ +# 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 + +# Download and compile AFL v2.57b. +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone --depth 1 \ + https://github.com/MagicHavoc/Havoc-Study +RUN mv Havoc-Study/fuzzers/Havoc_DMA /afl +RUN cd /afl && \ + CFLAGS= CXXFLAGS= AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/afl_virginmap/fuzzer.py b/fuzzers/afl_mb/fuzzer.py similarity index 97% rename from fuzzers/afl_virginmap/fuzzer.py rename to fuzzers/afl_mb/fuzzer.py index 7c4c44180..18cb71229 100755 --- a/fuzzers/afl_virginmap/fuzzer.py +++ b/fuzzers/afl_mb/fuzzer.py @@ -48,6 +48,9 @@ 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 = {} diff --git a/fuzzers/afl_virginmap/runner.Dockerfile b/fuzzers/afl_mb/runner.Dockerfile similarity index 100% rename from fuzzers/afl_virginmap/runner.Dockerfile rename to fuzzers/afl_mb/runner.Dockerfile diff --git a/fuzzers/afl_t0/builder.Dockerfile b/fuzzers/afl_t0/builder.Dockerfile new file mode 100644 index 000000000..94d7f5076 --- /dev/null +++ b/fuzzers/afl_t0/builder.Dockerfile @@ -0,0 +1,33 @@ +# 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 + +# Download and compile AFL v2.57b. +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone \ + --depth 1 \ + --branch v2.57b \ + https://github.com/google/AFL.git /afl && \ + cd /afl && \ + CFLAGS= CXXFLAGS= AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/afl_t0/fuzzer.py b/fuzzers/afl_t0/fuzzer.py new file mode 100755 index 000000000..18cb71229 --- /dev/null +++ b/fuzzers/afl_t0/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/symcc_afl/runner.Dockerfile b/fuzzers/afl_t0/runner.Dockerfile similarity index 88% rename from fuzzers/symcc_afl/runner.Dockerfile rename to fuzzers/afl_t0/runner.Dockerfile index d882a6575..0d6cf004e 100644 --- a/fuzzers/symcc_afl/runner.Dockerfile +++ b/fuzzers/afl_t0/runner.Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021 Google LLC +# 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. @@ -13,5 +13,3 @@ # limitations under the License. FROM gcr.io/fuzzbench/base-image - -ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/out" diff --git a/fuzzers/afl_t1/builder.Dockerfile b/fuzzers/afl_t1/builder.Dockerfile new file mode 100644 index 000000000..94d7f5076 --- /dev/null +++ b/fuzzers/afl_t1/builder.Dockerfile @@ -0,0 +1,33 @@ +# 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 + +# Download and compile AFL v2.57b. +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone \ + --depth 1 \ + --branch v2.57b \ + https://github.com/google/AFL.git /afl && \ + cd /afl && \ + CFLAGS= CXXFLAGS= AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/afl_t1/fuzzer.py b/fuzzers/afl_t1/fuzzer.py new file mode 100755 index 000000000..18cb71229 --- /dev/null +++ b/fuzzers/afl_t1/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/symcc_afl_single/runner.Dockerfile b/fuzzers/afl_t1/runner.Dockerfile similarity index 88% rename from fuzzers/symcc_afl_single/runner.Dockerfile rename to fuzzers/afl_t1/runner.Dockerfile index d882a6575..0d6cf004e 100644 --- a/fuzzers/symcc_afl_single/runner.Dockerfile +++ b/fuzzers/afl_t1/runner.Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021 Google LLC +# 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. @@ -13,5 +13,3 @@ # limitations under the License. FROM gcr.io/fuzzbench/base-image - -ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/out" diff --git a/fuzzers/afl_t2/builder.Dockerfile b/fuzzers/afl_t2/builder.Dockerfile new file mode 100644 index 000000000..94d7f5076 --- /dev/null +++ b/fuzzers/afl_t2/builder.Dockerfile @@ -0,0 +1,33 @@ +# 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 + +# Download and compile AFL v2.57b. +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone \ + --depth 1 \ + --branch v2.57b \ + https://github.com/google/AFL.git /afl && \ + cd /afl && \ + CFLAGS= CXXFLAGS= AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/afl_t2/fuzzer.py b/fuzzers/afl_t2/fuzzer.py new file mode 100755 index 000000000..18cb71229 --- /dev/null +++ b/fuzzers/afl_t2/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/symcc_aflplusplus/runner.Dockerfile b/fuzzers/afl_t2/runner.Dockerfile similarity index 88% rename from fuzzers/symcc_aflplusplus/runner.Dockerfile rename to fuzzers/afl_t2/runner.Dockerfile index d882a6575..0d6cf004e 100644 --- a/fuzzers/symcc_aflplusplus/runner.Dockerfile +++ b/fuzzers/afl_t2/runner.Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021 Google LLC +# 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. @@ -13,5 +13,3 @@ # limitations under the License. FROM gcr.io/fuzzbench/base-image - -ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/out" diff --git a/fuzzers/afl_t3/builder.Dockerfile b/fuzzers/afl_t3/builder.Dockerfile new file mode 100644 index 000000000..94d7f5076 --- /dev/null +++ b/fuzzers/afl_t3/builder.Dockerfile @@ -0,0 +1,33 @@ +# 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 + +# Download and compile AFL v2.57b. +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone \ + --depth 1 \ + --branch v2.57b \ + https://github.com/google/AFL.git /afl && \ + cd /afl && \ + CFLAGS= CXXFLAGS= AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/afl_t3/fuzzer.py b/fuzzers/afl_t3/fuzzer.py new file mode 100755 index 000000000..18cb71229 --- /dev/null +++ b/fuzzers/afl_t3/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/symcc_aflplusplus_single/runner.Dockerfile b/fuzzers/afl_t3/runner.Dockerfile similarity index 88% rename from fuzzers/symcc_aflplusplus_single/runner.Dockerfile rename to fuzzers/afl_t3/runner.Dockerfile index d882a6575..0d6cf004e 100644 --- a/fuzzers/symcc_aflplusplus_single/runner.Dockerfile +++ b/fuzzers/afl_t3/runner.Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2021 Google LLC +# 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. @@ -13,5 +13,3 @@ # limitations under the License. FROM gcr.io/fuzzbench/base-image - -ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/out" diff --git a/fuzzers/afl_t4/builder.Dockerfile b/fuzzers/afl_t4/builder.Dockerfile new file mode 100644 index 000000000..94d7f5076 --- /dev/null +++ b/fuzzers/afl_t4/builder.Dockerfile @@ -0,0 +1,33 @@ +# 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 + +# Download and compile AFL v2.57b. +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone \ + --depth 1 \ + --branch v2.57b \ + https://github.com/google/AFL.git /afl && \ + cd /afl && \ + CFLAGS= CXXFLAGS= AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/afl_t4/fuzzer.py b/fuzzers/afl_t4/fuzzer.py new file mode 100755 index 000000000..18cb71229 --- /dev/null +++ b/fuzzers/afl_t4/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/afl_t4/runner.Dockerfile b/fuzzers/afl_t4/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/afl_t4/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 diff --git a/fuzzers/aflfast_t0/builder.Dockerfile b/fuzzers/aflfast_t0/builder.Dockerfile new file mode 100644 index 000000000..b38039810 --- /dev/null +++ b/fuzzers/aflfast_t0/builder.Dockerfile @@ -0,0 +1,31 @@ +# 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 + +# Download and compile AFLFast (extends AFL with Power Schedules). +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/mboehme/aflfast.git /afl && \ + cd /afl && \ + git checkout d1d54caf9850ca4afe2ac634a2a212aa6bb40032 && \ + AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/aflfast_t0/fuzzer.py b/fuzzers/aflfast_t0/fuzzer.py new file mode 100755 index 000000000..5c366aef5 --- /dev/null +++ b/fuzzers/aflfast_t0/fuzzer.py @@ -0,0 +1,34 @@ +# 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 AFLFast fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + + # Write AFL's output to /dev/null to avoid filling up disk by writing too + # much to log file. This is a problem in general with AFLFast but + # particularly with the lcms benchmark. + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + hide_output=True) diff --git a/fuzzers/aflfast_t0/runner.Dockerfile b/fuzzers/aflfast_t0/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/aflfast_t0/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 diff --git a/fuzzers/aflfast_t1/builder.Dockerfile b/fuzzers/aflfast_t1/builder.Dockerfile new file mode 100644 index 000000000..b38039810 --- /dev/null +++ b/fuzzers/aflfast_t1/builder.Dockerfile @@ -0,0 +1,31 @@ +# 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 + +# Download and compile AFLFast (extends AFL with Power Schedules). +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/mboehme/aflfast.git /afl && \ + cd /afl && \ + git checkout d1d54caf9850ca4afe2ac634a2a212aa6bb40032 && \ + AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/aflfast_t1/fuzzer.py b/fuzzers/aflfast_t1/fuzzer.py new file mode 100755 index 000000000..5c366aef5 --- /dev/null +++ b/fuzzers/aflfast_t1/fuzzer.py @@ -0,0 +1,34 @@ +# 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 AFLFast fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + + # Write AFL's output to /dev/null to avoid filling up disk by writing too + # much to log file. This is a problem in general with AFLFast but + # particularly with the lcms benchmark. + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + hide_output=True) diff --git a/fuzzers/aflfast_t1/runner.Dockerfile b/fuzzers/aflfast_t1/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/aflfast_t1/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 diff --git a/fuzzers/aflfast_t2/builder.Dockerfile b/fuzzers/aflfast_t2/builder.Dockerfile new file mode 100644 index 000000000..b38039810 --- /dev/null +++ b/fuzzers/aflfast_t2/builder.Dockerfile @@ -0,0 +1,31 @@ +# 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 + +# Download and compile AFLFast (extends AFL with Power Schedules). +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/mboehme/aflfast.git /afl && \ + cd /afl && \ + git checkout d1d54caf9850ca4afe2ac634a2a212aa6bb40032 && \ + AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/aflfast_t2/fuzzer.py b/fuzzers/aflfast_t2/fuzzer.py new file mode 100755 index 000000000..5c366aef5 --- /dev/null +++ b/fuzzers/aflfast_t2/fuzzer.py @@ -0,0 +1,34 @@ +# 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 AFLFast fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + + # Write AFL's output to /dev/null to avoid filling up disk by writing too + # much to log file. This is a problem in general with AFLFast but + # particularly with the lcms benchmark. + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + hide_output=True) diff --git a/fuzzers/aflfast_t2/runner.Dockerfile b/fuzzers/aflfast_t2/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/aflfast_t2/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 diff --git a/fuzzers/aflfast_t3/builder.Dockerfile b/fuzzers/aflfast_t3/builder.Dockerfile new file mode 100644 index 000000000..b38039810 --- /dev/null +++ b/fuzzers/aflfast_t3/builder.Dockerfile @@ -0,0 +1,31 @@ +# 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 + +# Download and compile AFLFast (extends AFL with Power Schedules). +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/mboehme/aflfast.git /afl && \ + cd /afl && \ + git checkout d1d54caf9850ca4afe2ac634a2a212aa6bb40032 && \ + AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/aflfast_t3/fuzzer.py b/fuzzers/aflfast_t3/fuzzer.py new file mode 100755 index 000000000..5c366aef5 --- /dev/null +++ b/fuzzers/aflfast_t3/fuzzer.py @@ -0,0 +1,34 @@ +# 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 AFLFast fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + + # Write AFL's output to /dev/null to avoid filling up disk by writing too + # much to log file. This is a problem in general with AFLFast but + # particularly with the lcms benchmark. + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + hide_output=True) diff --git a/fuzzers/aflfast_t3/runner.Dockerfile b/fuzzers/aflfast_t3/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/aflfast_t3/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 diff --git a/fuzzers/aflfast_t4/builder.Dockerfile b/fuzzers/aflfast_t4/builder.Dockerfile new file mode 100644 index 000000000..b38039810 --- /dev/null +++ b/fuzzers/aflfast_t4/builder.Dockerfile @@ -0,0 +1,31 @@ +# 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 + +# Download and compile AFLFast (extends AFL with Power Schedules). +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/mboehme/aflfast.git /afl && \ + cd /afl && \ + git checkout d1d54caf9850ca4afe2ac634a2a212aa6bb40032 && \ + AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/aflfast_t4/fuzzer.py b/fuzzers/aflfast_t4/fuzzer.py new file mode 100755 index 000000000..5c366aef5 --- /dev/null +++ b/fuzzers/aflfast_t4/fuzzer.py @@ -0,0 +1,34 @@ +# 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 AFLFast fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + + # Write AFL's output to /dev/null to avoid filling up disk by writing too + # much to log file. This is a problem in general with AFLFast but + # particularly with the lcms benchmark. + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + hide_output=True) diff --git a/fuzzers/aflfast_t4/runner.Dockerfile b/fuzzers/aflfast_t4/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/aflfast_t4/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 diff --git a/fuzzers/aflplusplus/builder.Dockerfile b/fuzzers/aflplusplus/builder.Dockerfile index fc0561c41..8e88d048a 100644 --- a/fuzzers/aflplusplus/builder.Dockerfile +++ b/fuzzers/aflplusplus/builder.Dockerfile @@ -37,11 +37,9 @@ RUN apt-get update && \ # Download afl++. RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ cd /afl && \ - git checkout 56d5aa3101945e81519a3fac8783d0d8fad82779 || \ - true + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 # Build without Python support as we don't need it. -# Set AFL_NO_X86 to skip flaky tests. RUN cd /afl && \ unset CFLAGS CXXFLAGS && \ export CC=clang AFL_NO_X86=1 && \ diff --git a/fuzzers/aflplusplus/fuzzer.py b/fuzzers/aflplusplus/fuzzer.py index 7016da75e..566607790 100755 --- a/fuzzers/aflplusplus/fuzzer.py +++ b/fuzzers/aflplusplus/fuzzer.py @@ -269,6 +269,7 @@ def fuzz(input_corpus, os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' os.environ['AFL_FAST_CAL'] = '1' os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' if not skip: os.environ['AFL_DISABLE_TRIM'] = '1' diff --git a/fuzzers/aflplusplus2/builder.Dockerfile b/fuzzers/aflplusplus2/builder.Dockerfile new file mode 100644 index 000000000..9d0cbb386 --- /dev/null +++ b/fuzzers/aflplusplus2/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout b1730d99b672b75467ff6bb380629ab90da26c56 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus2/description.md b/fuzzers/aflplusplus2/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus2/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflpp_random_wrs/fuzzer.py b/fuzzers/aflplusplus2/fuzzer.py similarity index 91% rename from fuzzers/aflpp_random_wrs/fuzzer.py rename to fuzzers/aflplusplus2/fuzzer.py index f561625fa..566607790 100755 --- a/fuzzers/aflpp_random_wrs/fuzzer.py +++ b/fuzzers/aflplusplus2/fuzzer.py @@ -49,10 +49,12 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements # For bug type benchmarks we have to instrument via native clang pcguard :( build_flags = os.environ['CFLAGS'] + if build_flags.find( 'array-bounds' ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: - build_modes[0] = 'native' + if 'gcc' not in build_modes: + build_modes[0] = 'native' # Instrumentation coverage modes: if 'lto' in build_modes: @@ -78,6 +80,13 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements elif 'gcc' in build_modes: os.environ['CC'] = 'afl-gcc-fast' os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' else: os.environ['CC'] = '/afl/afl-clang-fast' os.environ['CXX'] = '/afl/afl-clang-fast++' @@ -107,6 +116,7 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements # Generate an extra dictionary. if 'dict2file' in build_modes or 'native' in build_modes: os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' # Enable context sentitivity for LLVM mode (non LTO only) if 'ctx' in build_modes: os.environ['AFL_LLVM_CTX'] = '1' @@ -204,15 +214,15 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' new_env['SYMCC_SILENT'] = '1' - # For CmpLog build, set the OUT and FUZZ_TARGET environment - # variable to point to the new CmpLog build directory. + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. new_env['OUT'] = symcc_build_directory fuzz_target = os.getenv('FUZZ_TARGET') if fuzz_target: new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, os.path.basename(fuzz_target)) - print('Re-building benchmark for CmpLog fuzzing target') + print('Re-building benchmark for symcc fuzzing target') utils.build_benchmark(env=new_env) shutil.copy('/afl/afl-fuzz', build_directory) @@ -252,18 +262,21 @@ def fuzz(input_corpus, flags += ['-x', './afl++.dict'] # Move the following to skip for upcoming _double tests: - if os.path.exists(cmplog_target_binary) and no_cmplog is not False: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: flags += ['-c', cmplog_target_binary] + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + if not skip: os.environ['AFL_DISABLE_TRIM'] = '1' - # os.environ['AFL_FAST_CAL'] = '1' os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' if 'ADDITIONAL_ARGS' in os.environ: flags += os.environ['ADDITIONAL_ARGS'].split(' ') - os.environ['AFL_DISABLE_RF'] = '1' - os.environ['AFL_DISABLE_RP'] = '1' afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, diff --git a/fuzzers/aflplusplus2/runner.Dockerfile b/fuzzers/aflplusplus2/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus2/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus2_nosimp/builder.Dockerfile b/fuzzers/aflplusplus2_nosimp/builder.Dockerfile new file mode 100644 index 000000000..3d3569ba4 --- /dev/null +++ b/fuzzers/aflplusplus2_nosimp/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b nosimp https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout 8b70056509ecf400b6c47b1739a85c5972032a85 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus2_nosimp/description.md b/fuzzers/aflplusplus2_nosimp/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus2_nosimp/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflpp_random_wrs_rf/fuzzer.py b/fuzzers/aflplusplus2_nosimp/fuzzer.py similarity index 91% rename from fuzzers/aflpp_random_wrs_rf/fuzzer.py rename to fuzzers/aflplusplus2_nosimp/fuzzer.py index 50a073a99..566607790 100755 --- a/fuzzers/aflpp_random_wrs_rf/fuzzer.py +++ b/fuzzers/aflplusplus2_nosimp/fuzzer.py @@ -49,10 +49,12 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements # For bug type benchmarks we have to instrument via native clang pcguard :( build_flags = os.environ['CFLAGS'] + if build_flags.find( 'array-bounds' ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: - build_modes[0] = 'native' + if 'gcc' not in build_modes: + build_modes[0] = 'native' # Instrumentation coverage modes: if 'lto' in build_modes: @@ -78,6 +80,13 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements elif 'gcc' in build_modes: os.environ['CC'] = 'afl-gcc-fast' os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' else: os.environ['CC'] = '/afl/afl-clang-fast' os.environ['CXX'] = '/afl/afl-clang-fast++' @@ -107,6 +116,7 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements # Generate an extra dictionary. if 'dict2file' in build_modes or 'native' in build_modes: os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' # Enable context sentitivity for LLVM mode (non LTO only) if 'ctx' in build_modes: os.environ['AFL_LLVM_CTX'] = '1' @@ -204,15 +214,15 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' new_env['SYMCC_SILENT'] = '1' - # For CmpLog build, set the OUT and FUZZ_TARGET environment - # variable to point to the new CmpLog build directory. + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. new_env['OUT'] = symcc_build_directory fuzz_target = os.getenv('FUZZ_TARGET') if fuzz_target: new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, os.path.basename(fuzz_target)) - print('Re-building benchmark for CmpLog fuzzing target') + print('Re-building benchmark for symcc fuzzing target') utils.build_benchmark(env=new_env) shutil.copy('/afl/afl-fuzz', build_directory) @@ -252,17 +262,21 @@ def fuzz(input_corpus, flags += ['-x', './afl++.dict'] # Move the following to skip for upcoming _double tests: - if os.path.exists(cmplog_target_binary) and no_cmplog is not False: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: flags += ['-c', cmplog_target_binary] + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + if not skip: os.environ['AFL_DISABLE_TRIM'] = '1' - # os.environ['AFL_FAST_CAL'] = '1' os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' if 'ADDITIONAL_ARGS' in os.environ: flags += os.environ['ADDITIONAL_ARGS'].split(' ') - os.environ['AFL_DISABLE_RP'] = '1' afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, diff --git a/fuzzers/aflplusplus2_nosimp/runner.Dockerfile b/fuzzers/aflplusplus2_nosimp/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus2_nosimp/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus3/builder.Dockerfile b/fuzzers/aflplusplus3/builder.Dockerfile new file mode 100644 index 000000000..f2dce9fb4 --- /dev/null +++ b/fuzzers/aflplusplus3/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b hidden https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout ea6d182b4a85d9e73662b633fb40f0e7e43934ef + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus3/description.md b/fuzzers/aflplusplus3/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus3/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus3/fuzzer.py b/fuzzers/aflplusplus3/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus3/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus3/runner.Dockerfile b/fuzzers/aflplusplus3/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus3/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_um_prioritize_75/builder.Dockerfile b/fuzzers/aflplusplus_410c/builder.Dockerfile similarity index 51% rename from fuzzers/aflplusplus_um_prioritize_75/builder.Dockerfile rename to fuzzers/aflplusplus_410c/builder.Dockerfile index 33c94647b..c2f5c922c 100644 --- a/fuzzers/aflplusplus_um_prioritize_75/builder.Dockerfile +++ b/fuzzers/aflplusplus_410c/builder.Dockerfile @@ -15,26 +15,35 @@ ARG parent_image FROM $parent_image -RUN apt-get update && apt-get install -y python3 -RUN pip3 install --upgrade --force pip -RUN pip install universalmutator - -# Install libstdc++ to use llvm_mode. RUN apt-get update && \ - apt-get install -y wget libstdc++-10-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 https://github.com/AFLplusplus/AFLplusplus /afl && \ cd /afl && \ - git checkout b847e0f414e7b310e1a68bc501d4e2453bfce70e + git checkout 775861ea94d00672c9e868db329073afd699b994 || \ + 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 / - diff --git a/fuzzers/aflplusplus_410c/description.md b/fuzzers/aflplusplus_410c/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_410c/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflpp_random_default/fuzzer.py b/fuzzers/aflplusplus_410c/fuzzer.py similarity index 92% rename from fuzzers/aflpp_random_default/fuzzer.py rename to fuzzers/aflplusplus_410c/fuzzer.py index f51c59195..7016da75e 100755 --- a/fuzzers/aflpp_random_default/fuzzer.py +++ b/fuzzers/aflplusplus_410c/fuzzer.py @@ -49,10 +49,12 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements # For bug type benchmarks we have to instrument via native clang pcguard :( build_flags = os.environ['CFLAGS'] + if build_flags.find( 'array-bounds' ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: - build_modes[0] = 'native' + if 'gcc' not in build_modes: + build_modes[0] = 'native' # Instrumentation coverage modes: if 'lto' in build_modes: @@ -78,6 +80,13 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements elif 'gcc' in build_modes: os.environ['CC'] = 'afl-gcc-fast' os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' else: os.environ['CC'] = '/afl/afl-clang-fast' os.environ['CXX'] = '/afl/afl-clang-fast++' @@ -107,6 +116,7 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements # Generate an extra dictionary. if 'dict2file' in build_modes or 'native' in build_modes: os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' # Enable context sentitivity for LLVM mode (non LTO only) if 'ctx' in build_modes: os.environ['AFL_LLVM_CTX'] = '1' @@ -204,15 +214,15 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' new_env['SYMCC_SILENT'] = '1' - # For CmpLog build, set the OUT and FUZZ_TARGET environment - # variable to point to the new CmpLog build directory. + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. new_env['OUT'] = symcc_build_directory fuzz_target = os.getenv('FUZZ_TARGET') if fuzz_target: new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, os.path.basename(fuzz_target)) - print('Re-building benchmark for CmpLog fuzzing target') + print('Re-building benchmark for symcc fuzzing target') utils.build_benchmark(env=new_env) shutil.copy('/afl/afl-fuzz', build_directory) @@ -252,12 +262,16 @@ def fuzz(input_corpus, flags += ['-x', './afl++.dict'] # Move the following to skip for upcoming _double tests: - if os.path.exists(cmplog_target_binary) and no_cmplog is not False: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: flags += ['-c', cmplog_target_binary] + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + if not skip: os.environ['AFL_DISABLE_TRIM'] = '1' - # os.environ['AFL_FAST_CAL'] = '1' os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' if 'ADDITIONAL_ARGS' in os.environ: flags += os.environ['ADDITIONAL_ARGS'].split(' ') diff --git a/fuzzers/aflplusplus_410c/runner.Dockerfile b/fuzzers/aflplusplus_410c/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_410c/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_um_parallel/builder.Dockerfile b/fuzzers/aflplusplus_420c/builder.Dockerfile similarity index 51% rename from fuzzers/aflplusplus_um_parallel/builder.Dockerfile rename to fuzzers/aflplusplus_420c/builder.Dockerfile index 33c94647b..2b41dcc7a 100644 --- a/fuzzers/aflplusplus_um_parallel/builder.Dockerfile +++ b/fuzzers/aflplusplus_420c/builder.Dockerfile @@ -15,26 +15,35 @@ ARG parent_image FROM $parent_image -RUN apt-get update && apt-get install -y python3 -RUN pip3 install --upgrade --force pip -RUN pip install universalmutator - -# Install libstdc++ to use llvm_mode. RUN apt-get update && \ - apt-get install -y wget libstdc++-10-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 https://github.com/AFLplusplus/AFLplusplus /afl && \ cd /afl && \ - git checkout b847e0f414e7b310e1a68bc501d4e2453bfce70e + git checkout e01307a993387bfe842df1deb23ec7facffd4859 || \ + 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 / - diff --git a/fuzzers/aflplusplus_420c/description.md b/fuzzers/aflplusplus_420c/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_420c/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflpp_random_no_favs/fuzzer.py b/fuzzers/aflplusplus_420c/fuzzer.py similarity index 92% rename from fuzzers/aflpp_random_no_favs/fuzzer.py rename to fuzzers/aflplusplus_420c/fuzzer.py index d8a93b36c..7016da75e 100755 --- a/fuzzers/aflpp_random_no_favs/fuzzer.py +++ b/fuzzers/aflplusplus_420c/fuzzer.py @@ -49,10 +49,12 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements # For bug type benchmarks we have to instrument via native clang pcguard :( build_flags = os.environ['CFLAGS'] + if build_flags.find( 'array-bounds' ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: - build_modes[0] = 'native' + if 'gcc' not in build_modes: + build_modes[0] = 'native' # Instrumentation coverage modes: if 'lto' in build_modes: @@ -78,6 +80,13 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements elif 'gcc' in build_modes: os.environ['CC'] = 'afl-gcc-fast' os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' else: os.environ['CC'] = '/afl/afl-clang-fast' os.environ['CXX'] = '/afl/afl-clang-fast++' @@ -107,6 +116,7 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements # Generate an extra dictionary. if 'dict2file' in build_modes or 'native' in build_modes: os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' # Enable context sentitivity for LLVM mode (non LTO only) if 'ctx' in build_modes: os.environ['AFL_LLVM_CTX'] = '1' @@ -204,15 +214,15 @@ def build(*args): # pylint: disable=too-many-branches,too-many-statements new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' new_env['SYMCC_SILENT'] = '1' - # For CmpLog build, set the OUT and FUZZ_TARGET environment - # variable to point to the new CmpLog build directory. + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. new_env['OUT'] = symcc_build_directory fuzz_target = os.getenv('FUZZ_TARGET') if fuzz_target: new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, os.path.basename(fuzz_target)) - print('Re-building benchmark for CmpLog fuzzing target') + print('Re-building benchmark for symcc fuzzing target') utils.build_benchmark(env=new_env) shutil.copy('/afl/afl-fuzz', build_directory) @@ -252,20 +262,20 @@ def fuzz(input_corpus, flags += ['-x', './afl++.dict'] # Move the following to skip for upcoming _double tests: - if os.path.exists(cmplog_target_binary) and no_cmplog is not False: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: flags += ['-c', cmplog_target_binary] + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + if not skip: os.environ['AFL_DISABLE_TRIM'] = '1' - # os.environ['AFL_FAST_CAL'] = '1' os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' if 'ADDITIONAL_ARGS' in os.environ: flags += os.environ['ADDITIONAL_ARGS'].split(' ') - os.environ['AFL_DISABLE_WRS'] = '1' - os.environ['AFL_DISABLE_RF'] = '1' - os.environ['AFL_DISABLE_RP'] = '1' - os.environ['AFL_DISABLE_FAVS'] = '1' afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, diff --git a/fuzzers/aflplusplus_420c/runner.Dockerfile b/fuzzers/aflplusplus_420c/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_420c/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_421c/builder.Dockerfile b/fuzzers/aflplusplus_421c/builder.Dockerfile new file mode 100644 index 000000000..a742cfcee --- /dev/null +++ b/fuzzers/aflplusplus_421c/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout f2cd5e1d8e8a97ed86990c0eeb6f00e7c289fc44 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_421c/description.md b/fuzzers/aflplusplus_421c/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_421c/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_421c/fuzzer.py b/fuzzers/aflplusplus_421c/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_421c/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_421c/runner.Dockerfile b/fuzzers/aflplusplus_421c/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_421c/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_430c/builder.Dockerfile b/fuzzers/aflplusplus_430c/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_430c/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_430c/description.md b/fuzzers/aflplusplus_430c/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_430c/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_430c/fuzzer.py b/fuzzers/aflplusplus_430c/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_430c/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_430c/runner.Dockerfile b/fuzzers/aflplusplus_430c/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_430c/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_431c/builder.Dockerfile b/fuzzers/aflplusplus_431c/builder.Dockerfile new file mode 100644 index 000000000..d13cb0c11 --- /dev/null +++ b/fuzzers/aflplusplus_431c/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout 9cac7ced05eb9f36c1d0b02ad594b3b09cd3938b + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_431c/description.md b/fuzzers/aflplusplus_431c/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_431c/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_431c/fuzzer.py b/fuzzers/aflplusplus_431c/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_431c/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_431c/runner.Dockerfile b/fuzzers/aflplusplus_431c/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_431c/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_432c/builder.Dockerfile b/fuzzers/aflplusplus_432c/builder.Dockerfile new file mode 100644 index 000000000..c7fa238a9 --- /dev/null +++ b/fuzzers/aflplusplus_432c/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout c340a022e2546488c15f85593d0f37e30eeaab3a + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_432c/description.md b/fuzzers/aflplusplus_432c/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_432c/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_432c/fuzzer.py b/fuzzers/aflplusplus_432c/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_432c/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_432c/runner.Dockerfile b/fuzzers/aflplusplus_432c/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_432c/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_fixseed1/builder.Dockerfile b/fuzzers/aflplusplus_fixseed1/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_fixseed1/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_fixseed1/description.md b/fuzzers/aflplusplus_fixseed1/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_fixseed1/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_fixseed1/fuzzer.py b/fuzzers/aflplusplus_fixseed1/fuzzer.py new file mode 100755 index 000000000..ec49594ec --- /dev/null +++ b/fuzzers/aflplusplus_fixseed1/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-s', '0', '-Z'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_fixseed1/runner.Dockerfile b/fuzzers/aflplusplus_fixseed1/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_fixseed1/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_fixseed2/builder.Dockerfile b/fuzzers/aflplusplus_fixseed2/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_fixseed2/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_fixseed2/description.md b/fuzzers/aflplusplus_fixseed2/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_fixseed2/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_fixseed2/fuzzer.py b/fuzzers/aflplusplus_fixseed2/fuzzer.py new file mode 100755 index 000000000..ec49594ec --- /dev/null +++ b/fuzzers/aflplusplus_fixseed2/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-s', '0', '-Z'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_fixseed2/runner.Dockerfile b/fuzzers/aflplusplus_fixseed2/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_fixseed2/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_fixseed3/builder.Dockerfile b/fuzzers/aflplusplus_fixseed3/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_fixseed3/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_fixseed3/description.md b/fuzzers/aflplusplus_fixseed3/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_fixseed3/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_fixseed3/fuzzer.py b/fuzzers/aflplusplus_fixseed3/fuzzer.py new file mode 100755 index 000000000..ec49594ec --- /dev/null +++ b/fuzzers/aflplusplus_fixseed3/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-s', '0', '-Z'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_fixseed3/runner.Dockerfile b/fuzzers/aflplusplus_fixseed3/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_fixseed3/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_fixseed4/builder.Dockerfile b/fuzzers/aflplusplus_fixseed4/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_fixseed4/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_fixseed4/description.md b/fuzzers/aflplusplus_fixseed4/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_fixseed4/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_fixseed4/fuzzer.py b/fuzzers/aflplusplus_fixseed4/fuzzer.py new file mode 100755 index 000000000..ec49594ec --- /dev/null +++ b/fuzzers/aflplusplus_fixseed4/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-s', '0', '-Z'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_fixseed4/runner.Dockerfile b/fuzzers/aflplusplus_fixseed4/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_fixseed4/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_fixseed5/builder.Dockerfile b/fuzzers/aflplusplus_fixseed5/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_fixseed5/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_fixseed5/description.md b/fuzzers/aflplusplus_fixseed5/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_fixseed5/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_fixseed5/fuzzer.py b/fuzzers/aflplusplus_fixseed5/fuzzer.py new file mode 100755 index 000000000..ec49594ec --- /dev/null +++ b/fuzzers/aflplusplus_fixseed5/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-s', '0', '-Z'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_fixseed5/runner.Dockerfile b/fuzzers/aflplusplus_fixseed5/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_fixseed5/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_mopt/builder.Dockerfile b/fuzzers/aflplusplus_mopt/builder.Dockerfile new file mode 100644 index 000000000..bb3491cbe --- /dev/null +++ b/fuzzers/aflplusplus_mopt/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b mopt https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout 40e07e4128a518e120d4148e01d38357763e3e87 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_mopt/description.md b/fuzzers/aflplusplus_mopt/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_mopt/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_mopt/fuzzer.py b/fuzzers/aflplusplus_mopt/fuzzer.py new file mode 100755 index 000000000..900f08881 --- /dev/null +++ b/fuzzers/aflplusplus_mopt/fuzzer.py @@ -0,0 +1,286 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + flags += ['-z'] + flags += ['-L1'] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_mopt/runner.Dockerfile b/fuzzers/aflplusplus_mopt/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_mopt/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_mopt2/builder.Dockerfile b/fuzzers/aflplusplus_mopt2/builder.Dockerfile new file mode 100644 index 000000000..af507ae44 --- /dev/null +++ b/fuzzers/aflplusplus_mopt2/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b mopt2 https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout 4217d6a9f8524786efeba75a5fb0bef15499af00 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_mopt2/description.md b/fuzzers/aflplusplus_mopt2/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_mopt2/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_mopt2/fuzzer.py b/fuzzers/aflplusplus_mopt2/fuzzer.py new file mode 100755 index 000000000..98b7d4208 --- /dev/null +++ b/fuzzers/aflplusplus_mopt2/fuzzer.py @@ -0,0 +1,286 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + flags += ['-z'] + flags += ['-L0'] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_mopt2/runner.Dockerfile b/fuzzers/aflplusplus_mopt2/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_mopt2/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_nosplice/builder.Dockerfile b/fuzzers/aflplusplus_nosplice/builder.Dockerfile new file mode 100644 index 000000000..c36db8368 --- /dev/null +++ b/fuzzers/aflplusplus_nosplice/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout 79a24685b24540a9ba980c6ae8f2f79d3a0e53ff + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make NO_SPLICING=1 && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_nosplice/description.md b/fuzzers/aflplusplus_nosplice/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_nosplice/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_nosplice/fuzzer.py b/fuzzers/aflplusplus_nosplice/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_nosplice/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_nosplice/runner.Dockerfile b/fuzzers/aflplusplus_nosplice/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_nosplice/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflpp_random_wrs_rf/builder.Dockerfile b/fuzzers/aflplusplus_nothing1/builder.Dockerfile similarity index 50% rename from fuzzers/aflpp_random_wrs_rf/builder.Dockerfile rename to fuzzers/aflplusplus_nothing1/builder.Dockerfile index c4066c277..0fdea7001 100644 --- a/fuzzers/aflpp_random_wrs_rf/builder.Dockerfile +++ b/fuzzers/aflplusplus_nothing1/builder.Dockerfile @@ -15,21 +15,33 @@ 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/jiradeto/AFLplusplus /afl && \ +# Download afl++. +RUN git clone -b dev https://github.com/tokatoka/AFLplusplus /afl && \ cd /afl && \ - git checkout port_random_fuzzing_to_afl++ + git checkout 679d4e7919f5828529af203d638122e2626ad191 # 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 / diff --git a/fuzzers/aflplusplus_nothing1/description.md b/fuzzers/aflplusplus_nothing1/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_nothing1/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_nothing1/fuzzer.py b/fuzzers/aflplusplus_nothing1/fuzzer.py new file mode 100755 index 000000000..2d1bf7afe --- /dev/null +++ b/fuzzers/aflplusplus_nothing1/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-s', '0'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_nothing1/runner.Dockerfile b/fuzzers/aflplusplus_nothing1/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_nothing1/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflpp_random_wrs/builder.Dockerfile b/fuzzers/aflplusplus_nothing2/builder.Dockerfile similarity index 50% rename from fuzzers/aflpp_random_wrs/builder.Dockerfile rename to fuzzers/aflplusplus_nothing2/builder.Dockerfile index c4066c277..0fdea7001 100644 --- a/fuzzers/aflpp_random_wrs/builder.Dockerfile +++ b/fuzzers/aflplusplus_nothing2/builder.Dockerfile @@ -15,21 +15,33 @@ 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/jiradeto/AFLplusplus /afl && \ +# Download afl++. +RUN git clone -b dev https://github.com/tokatoka/AFLplusplus /afl && \ cd /afl && \ - git checkout port_random_fuzzing_to_afl++ + git checkout 679d4e7919f5828529af203d638122e2626ad191 # 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 / diff --git a/fuzzers/aflplusplus_nothing2/description.md b/fuzzers/aflplusplus_nothing2/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_nothing2/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_nothing2/fuzzer.py b/fuzzers/aflplusplus_nothing2/fuzzer.py new file mode 100755 index 000000000..2d1bf7afe --- /dev/null +++ b/fuzzers/aflplusplus_nothing2/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-s', '0'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_nothing2/runner.Dockerfile b/fuzzers/aflplusplus_nothing2/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_nothing2/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_nothing3/builder.Dockerfile b/fuzzers/aflplusplus_nothing3/builder.Dockerfile new file mode 100644 index 000000000..0fdea7001 --- /dev/null +++ b/fuzzers/aflplusplus_nothing3/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/tokatoka/AFLplusplus /afl && \ + cd /afl && \ + git checkout 679d4e7919f5828529af203d638122e2626ad191 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_nothing3/description.md b/fuzzers/aflplusplus_nothing3/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_nothing3/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_nothing3/fuzzer.py b/fuzzers/aflplusplus_nothing3/fuzzer.py new file mode 100755 index 000000000..2d1bf7afe --- /dev/null +++ b/fuzzers/aflplusplus_nothing3/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-s', '0'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_nothing3/runner.Dockerfile b/fuzzers/aflplusplus_nothing3/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_nothing3/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_nothing4/builder.Dockerfile b/fuzzers/aflplusplus_nothing4/builder.Dockerfile new file mode 100644 index 000000000..0fdea7001 --- /dev/null +++ b/fuzzers/aflplusplus_nothing4/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/tokatoka/AFLplusplus /afl && \ + cd /afl && \ + git checkout 679d4e7919f5828529af203d638122e2626ad191 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_nothing4/description.md b/fuzzers/aflplusplus_nothing4/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_nothing4/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_nothing4/fuzzer.py b/fuzzers/aflplusplus_nothing4/fuzzer.py new file mode 100755 index 000000000..2d1bf7afe --- /dev/null +++ b/fuzzers/aflplusplus_nothing4/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-s', '0'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_nothing4/runner.Dockerfile b/fuzzers/aflplusplus_nothing4/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_nothing4/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_nothing5/builder.Dockerfile b/fuzzers/aflplusplus_nothing5/builder.Dockerfile new file mode 100644 index 000000000..0fdea7001 --- /dev/null +++ b/fuzzers/aflplusplus_nothing5/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/tokatoka/AFLplusplus /afl && \ + cd /afl && \ + git checkout 679d4e7919f5828529af203d638122e2626ad191 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_nothing5/description.md b/fuzzers/aflplusplus_nothing5/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_nothing5/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_nothing5/fuzzer.py b/fuzzers/aflplusplus_nothing5/fuzzer.py new file mode 100755 index 000000000..2d1bf7afe --- /dev/null +++ b/fuzzers/aflplusplus_nothing5/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-s', '0'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_nothing5/runner.Dockerfile b/fuzzers/aflplusplus_nothing5/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_nothing5/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_old/builder.Dockerfile b/fuzzers/aflplusplus_old/builder.Dockerfile new file mode 100644 index 000000000..bf3815d08 --- /dev/null +++ b/fuzzers/aflplusplus_old/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout 7ad694716bf9772d8db5fbbe3f7aec4be99e61df + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_old/description.md b/fuzzers/aflplusplus_old/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_old/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_old/fuzzer.py b/fuzzers/aflplusplus_old/fuzzer.py new file mode 100755 index 000000000..ae548932e --- /dev/null +++ b/fuzzers/aflplusplus_old/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + flags += ['-z'] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_old/runner.Dockerfile b/fuzzers/aflplusplus_old/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_old/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_p3/builder.Dockerfile b/fuzzers/aflplusplus_p3/builder.Dockerfile new file mode 100644 index 000000000..447a370ed --- /dev/null +++ b/fuzzers/aflplusplus_p3/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b pow https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout 57a9a773359948b8c95c9298cd1b1264dcee198e + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make AFL_HAVOC=3 && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_p3/description.md b/fuzzers/aflplusplus_p3/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_p3/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_p3/fuzzer.py b/fuzzers/aflplusplus_p3/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_p3/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_p3/runner.Dockerfile b/fuzzers/aflplusplus_p3/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_p3/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_p4/builder.Dockerfile b/fuzzers/aflplusplus_p4/builder.Dockerfile new file mode 100644 index 000000000..f4144db80 --- /dev/null +++ b/fuzzers/aflplusplus_p4/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b pow https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout 57a9a773359948b8c95c9298cd1b1264dcee198e + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make AFL_HAVOC=4 && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_p4/description.md b/fuzzers/aflplusplus_p4/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_p4/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_p4/fuzzer.py b/fuzzers/aflplusplus_p4/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_p4/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_p4/runner.Dockerfile b/fuzzers/aflplusplus_p4/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_p4/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_p5/builder.Dockerfile b/fuzzers/aflplusplus_p5/builder.Dockerfile new file mode 100644 index 000000000..78915229a --- /dev/null +++ b/fuzzers/aflplusplus_p5/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b pow https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout 57a9a773359948b8c95c9298cd1b1264dcee198e + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make AFL_HAVOC=5 && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_p5/description.md b/fuzzers/aflplusplus_p5/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_p5/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_p5/fuzzer.py b/fuzzers/aflplusplus_p5/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_p5/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_p5/runner.Dockerfile b/fuzzers/aflplusplus_p5/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_p5/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_t1/builder.Dockerfile b/fuzzers/aflplusplus_t1/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_t1/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_t1/description.md b/fuzzers/aflplusplus_t1/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_t1/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_t1/fuzzer.py b/fuzzers/aflplusplus_t1/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_t1/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_t1/runner.Dockerfile b/fuzzers/aflplusplus_t1/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_t1/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_t2/builder.Dockerfile b/fuzzers/aflplusplus_t2/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_t2/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_t2/description.md b/fuzzers/aflplusplus_t2/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_t2/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_t2/fuzzer.py b/fuzzers/aflplusplus_t2/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_t2/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_t2/runner.Dockerfile b/fuzzers/aflplusplus_t2/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_t2/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_t3/builder.Dockerfile b/fuzzers/aflplusplus_t3/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_t3/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_t3/description.md b/fuzzers/aflplusplus_t3/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_t3/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_t3/fuzzer.py b/fuzzers/aflplusplus_t3/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_t3/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_t3/runner.Dockerfile b/fuzzers/aflplusplus_t3/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_t3/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_t4/builder.Dockerfile b/fuzzers/aflplusplus_t4/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_t4/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_t4/description.md b/fuzzers/aflplusplus_t4/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_t4/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_t4/fuzzer.py b/fuzzers/aflplusplus_t4/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_t4/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_t4/runner.Dockerfile b/fuzzers/aflplusplus_t4/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_t4/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_t5/builder.Dockerfile b/fuzzers/aflplusplus_t5/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_t5/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_t5/description.md b/fuzzers/aflplusplus_t5/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_t5/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_t5/fuzzer.py b/fuzzers/aflplusplus_t5/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_t5/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_t5/runner.Dockerfile b/fuzzers/aflplusplus_t5/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_t5/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_toka1/builder.Dockerfile b/fuzzers/aflplusplus_toka1/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_toka1/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_toka1/description.md b/fuzzers/aflplusplus_toka1/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_toka1/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_toka1/fuzzer.py b/fuzzers/aflplusplus_toka1/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_toka1/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_toka1/runner.Dockerfile b/fuzzers/aflplusplus_toka1/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_toka1/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_toka2/builder.Dockerfile b/fuzzers/aflplusplus_toka2/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_toka2/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_toka2/description.md b/fuzzers/aflplusplus_toka2/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_toka2/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_toka2/fuzzer.py b/fuzzers/aflplusplus_toka2/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_toka2/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_toka2/runner.Dockerfile b/fuzzers/aflplusplus_toka2/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_toka2/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_toka3/builder.Dockerfile b/fuzzers/aflplusplus_toka3/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_toka3/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_toka3/description.md b/fuzzers/aflplusplus_toka3/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_toka3/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_toka3/fuzzer.py b/fuzzers/aflplusplus_toka3/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_toka3/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_toka3/runner.Dockerfile b/fuzzers/aflplusplus_toka3/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_toka3/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_toka4/builder.Dockerfile b/fuzzers/aflplusplus_toka4/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_toka4/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_toka4/description.md b/fuzzers/aflplusplus_toka4/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_toka4/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_toka4/fuzzer.py b/fuzzers/aflplusplus_toka4/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_toka4/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_toka4/runner.Dockerfile b/fuzzers/aflplusplus_toka4/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_toka4/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_toka5/builder.Dockerfile b/fuzzers/aflplusplus_toka5/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_toka5/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_toka5/description.md b/fuzzers/aflplusplus_toka5/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_toka5/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_toka5/fuzzer.py b/fuzzers/aflplusplus_toka5/fuzzer.py new file mode 100755 index 000000000..566607790 --- /dev/null +++ b/fuzzers/aflplusplus_toka5/fuzzer.py @@ -0,0 +1,283 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_toka5/runner.Dockerfile b/fuzzers/aflplusplus_toka5/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_toka5/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_um_parallel/description.md b/fuzzers/aflplusplus_um_parallel/description.md deleted file mode 100644 index 2ff91d2fd..000000000 --- a/fuzzers/aflplusplus_um_parallel/description.md +++ /dev/null @@ -1,9 +0,0 @@ -# aflplusplus UM (parallel) - -Run aflplusplus over mutated code with parallel. - -NOTE: This only works with C or C++ benchmarks. - -[builder.Dockerfile](builder.Dockerfile) -[fuzzer.py](fuzzer.py) -[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_um_parallel/fuzzer.py b/fuzzers/aflplusplus_um_parallel/fuzzer.py deleted file mode 100644 index ea24a2bd0..000000000 --- a/fuzzers/aflplusplus_um_parallel/fuzzer.py +++ /dev/null @@ -1,212 +0,0 @@ -# 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 glob -import os -from pathlib import Path -import random -import shutil -import filecmp -from subprocess import CalledProcessError -import time -import signal -import math -from contextlib import contextmanager - -from fuzzers.aflplusplus import fuzzer as aflplusplus_fuzzer -from fuzzers import utils - - -class TimeoutException(Exception): - """"Exception thrown when timeouts occur""" - - -TOTAL_FUZZING_TIME_DEFAULT = 82800 # 23 hours -TOTAL_BUILD_TIME = 43200 # 12 hours -FUZZ_PROP = 0.5 -DEFAULT_MUTANT_TIMEOUT = 300 -GRACE_TIME = 3600 # 1 hour in seconds -MAX_MUTANTS = 200000 - - -@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 build(): # pylint: disable=too-many-locals,too-many-statements - """Build benchmark.""" - start_time = time.time() - - out = os.getenv("OUT") - src = os.getenv("SRC") - work = os.getenv("WORK") - storage_dir = "/storage" - os.mkdir(storage_dir) - mutate_dir = f"{storage_dir}/mutant_files" - os.mkdir(mutate_dir) - mutate_bins = f"{storage_dir}/mutant_bins" - os.mkdir(mutate_bins) - mutate_scripts = f"{storage_dir}/mutant_scripts" - os.mkdir(mutate_scripts) - orig_out = f"{storage_dir}/orig_out" - os.mkdir(orig_out) - - orig_fuzz_target = os.getenv("FUZZ_TARGET") - with utils.restore_directory(src), utils.restore_directory(work): - aflplusplus_fuzzer.build() - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{orig_fuzz_target}") - os.system(f"cp -r {out}/* {orig_out}/") - benchmark = os.getenv("BENCHMARK") - - source_extensions = [".c", ".cc", ".cpp"] - # Use heuristic to try to find benchmark directory, - # otherwise look for all files in the current directory. - subdirs = [ - name for name in os.listdir(src) - if os.path.isdir(os.path.join(src, name)) - ] - benchmark_src_dir = src - for directory in subdirs: - if directory in benchmark: - benchmark_src_dir = os.path.join(src, directory) - break - - source_files = [] - for extension in source_extensions: - source_files += glob.glob(f"{benchmark_src_dir}/**/*{extension}", - recursive=True) - random.shuffle(source_files) - - mutants = [] - for source_file in source_files: - source_dir = os.path.dirname(source_file).split(src, 1)[1] - Path(f"{mutate_dir}/{source_dir}").mkdir(parents=True, exist_ok=True) - os.system(f"mutate {source_file} --mutantDir \ - {mutate_dir}/{source_dir} --noCheck > /dev/null") - source_base = os.path.basename(source_file).split(".")[0] - mutants_glob = glob.glob( - f"{mutate_dir}/{source_dir}/{source_base}.mutant.*") - mutants += [ - f"{source_dir}/{mutant.split('/')[-1]}"[1:] - for mutant in mutants_glob - ] - - if len(mutants) > MAX_MUTANTS: - break - - random.shuffle(mutants) - with open(f"{mutate_dir}/mutants.txt", "w", encoding="utf-8") as f_name: - f_name.writelines(f"{l}\n" for l in mutants) - - curr_time = time.time() - - # Add grace time for final build at end - remaining_time = int(TOTAL_BUILD_TIME - (start_time - curr_time) - - GRACE_TIME) - try: - with time_limit(remaining_time): - num_non_buggy = 1 - ind = 0 - while ind < len(mutants): - with utils.restore_directory(src), utils.restore_directory( - work): - mutant = mutants[ind] - suffix = "." + mutant.split(".")[-1] - mpart = ".mutant." + mutant.split(".mutant.")[1] - source_file = f"{src}/{mutant.replace(mpart, suffix)}" - print(source_file) - print(f"{mutate_dir}/{mutant}") - os.system(f"cp {source_file} {mutate_dir}/orig") - os.system(f"cp {mutate_dir}/{mutant} {source_file}") - - try: - new_fuzz_target = f"{os.getenv('FUZZ_TARGET')}"\ - f".{num_non_buggy}" - - os.system(f"rm -rf {out}/*") - aflplusplus_fuzzer.build() - if not filecmp.cmp(f'{mutate_bins}/{orig_fuzz_target}', - f'{out}/{orig_fuzz_target}', - shallow=False): - print(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - num_non_buggy += 1 - else: - print("EQUAL") - except RuntimeError: - pass - except CalledProcessError: - pass - os.system(f"cp {mutate_dir}/orig {source_file}") - ind += 1 - except TimeoutException: - pass - - os.system(f"rm -rf {out}/*") - os.system(f"cp -r {orig_out}/* {out}/") - os.system(f"cp {mutate_bins}/* {out}/") - - -def fuzz(input_corpus, output_corpus, target_binary): - """Run fuzzer.""" - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - total_mutant_time = int(FUZZ_PROP * total_fuzzing_time) - - mutants = glob.glob(f"{target_binary}.*") - random.shuffle(mutants) - timeout = max(DEFAULT_MUTANT_TIMEOUT, - int(total_mutant_time / max(len(mutants), 1))) - num_mutants = min(math.ceil(total_mutant_time / timeout), len(mutants)) - - input_corpus_dir = "/storage/input_corpus" - os.makedirs(input_corpus_dir, exist_ok=True) - os.environ['AFL_SKIP_CRASHES'] = "1" - - for mutant in mutants[:num_mutants]: - with utils.restore_directory(input_corpus), utils.restore_directory( - output_corpus): - try: - with time_limit(timeout): - aflplusplus_fuzzer.fuzz(input_corpus, output_corpus, mutant) - except TimeoutException: - pass - except CalledProcessError: - pass - os.system(f"cp -r {output_corpus}/* {input_corpus_dir}/*") - - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - aflplusplus_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/aflplusplus_um_prioritize/builder.Dockerfile b/fuzzers/aflplusplus_um_prioritize/builder.Dockerfile deleted file mode 100644 index 33c94647b..000000000 --- a/fuzzers/aflplusplus_um_prioritize/builder.Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -# 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 apt-get update && apt-get install -y python3 -RUN pip3 install --upgrade --force pip -RUN pip install universalmutator - -# Install libstdc++ to use llvm_mode. -RUN apt-get update && \ - apt-get install -y wget libstdc++-10-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 b847e0f414e7b310e1a68bc501d4e2453bfce70e - -# 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 / - diff --git a/fuzzers/aflplusplus_um_prioritize/description.md b/fuzzers/aflplusplus_um_prioritize/description.md deleted file mode 100644 index d5bfe6fea..000000000 --- a/fuzzers/aflplusplus_um_prioritize/description.md +++ /dev/null @@ -1,9 +0,0 @@ -# aflplusplus UM (prioritize) - -Run aflplusplus over mutated code with UM prioritization - -NOTE: This only works with C or C++ benchmarks. - -[builder.Dockerfile](builder.Dockerfile) -[fuzzer.py](fuzzer.py) -[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_um_prioritize/fuzzer.py b/fuzzers/aflplusplus_um_prioritize/fuzzer.py deleted file mode 100755 index 18a463b6d..000000000 --- a/fuzzers/aflplusplus_um_prioritize/fuzzer.py +++ /dev/null @@ -1,259 +0,0 @@ -# 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 glob -import os -from pathlib import Path -import random -import shutil -import filecmp -from subprocess import CalledProcessError -import time -import math -import signal -from contextlib import contextmanager - -from fuzzers.aflplusplus import fuzzer as aflplusplus_fuzzer -from fuzzers import utils - - -class TimeoutException(Exception): - """"Exception thrown when timeouts occur""" - - -TOTAL_FUZZING_TIME_DEFAULT = 82800 # 23 hours -TOTAL_BUILD_TIME = 43200 # 12 hours -FUZZ_PROP = 0.5 -DEFAULT_MUTANT_TIMEOUT = 300 -PRIORITIZE_MULTIPLIER = 5 -GRACE_TIME = 3600 # 1 hour in seconds -MAX_MUTANTS = 200000 -MAX_PRIORITIZE = 30 - - -@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 build(): # pylint: disable=too-many-locals,too-many-statements,too-many-branches - """Build benchmark.""" - start_time = time.time() - - out = os.getenv("OUT") - src = os.getenv("SRC") - work = os.getenv("WORK") - storage_dir = "/storage" - os.mkdir(storage_dir) - mutate_dir = f"{storage_dir}/mutant_files" - os.mkdir(mutate_dir) - mutate_bins = f"{storage_dir}/mutant_bins" - os.mkdir(mutate_bins) - mutate_scripts = f"{storage_dir}/mutant_scripts" - os.mkdir(mutate_scripts) - orig_out = f"{storage_dir}/orig_out" - os.mkdir(orig_out) - - orig_fuzz_target = os.getenv("FUZZ_TARGET") - with utils.restore_directory(src), utils.restore_directory(work): - aflplusplus_fuzzer.build() - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{orig_fuzz_target}") - os.system(f"cp -r {out}/* {orig_out}/") - benchmark = os.getenv("BENCHMARK") - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - - source_extensions = [".c", ".cc", ".cpp"] - num_mutants = math.ceil( - (total_fuzzing_time * FUZZ_PROP) / DEFAULT_MUTANT_TIMEOUT) - # Use heuristic to try to find benchmark directory, otherwise look for all - # files in the current directory. - subdirs = [ - name for name in os.listdir(src) - if os.path.isdir(os.path.join(src, name)) - ] - benchmark_src_dir = src - for directory in subdirs: - if directory in benchmark: - benchmark_src_dir = os.path.join(src, directory) - break - - source_files = [] - for extension in source_extensions: - source_files += glob.glob(f"{benchmark_src_dir}/**/*{extension}", - recursive=True) - random.shuffle(source_files) - - mutants_map = {} - num_mutants = 0 - for source_file in source_files: - source_dir = os.path.dirname(source_file).split(src, 1)[1] - Path(f"{mutate_dir}/{source_dir}").mkdir(parents=True, exist_ok=True) - os.system(f"mutate {source_file} --mutantDir \ - {mutate_dir}/{source_dir} --noCheck > /dev/null") - source_base = os.path.basename(source_file).split(".")[0] - mutants_glob = glob.glob( - f"{mutate_dir}/{source_dir}/{source_base}.mutant.*") - mutants = [ - f"{source_dir}/{mutant.split('/')[-1]}"[1:] - for mutant in mutants_glob - ] - num_mutants += len(mutants) - mutants_map[source_file] = mutants - if num_mutants > MAX_MUTANTS: - break - - prioritize_map = {} - num_prioritized = min( - math.ceil((num_mutants * PRIORITIZE_MULTIPLIER) / len(mutants_map)), - MAX_PRIORITIZE) - for source_file in mutants_map: - mutants = mutants_map[source_file] - with open(f"{mutate_dir}/mutants.txt", "w", encoding="utf_8") as f_name: - f_name.writelines(f"{l}\n" for l in mutants) - os.system(f"prioritize_mutants {mutate_dir}/mutants.txt \ - {mutate_dir}/prioritize_mutants_sorted.txt {num_prioritized}\ - --noSDPriority --sourceDir {src} --mutantDir {mutate_dir}") - prioritized_list = [] - with open(f"{mutate_dir}/prioritize_mutants_sorted.txt", - "r", - encoding="utf_8") as f_name: - prioritized_list = f_name.read().splitlines() - prioritize_map[source_file] = prioritized_list - - prioritized_keys = list(prioritize_map.keys()) - random.shuffle(prioritized_keys) - order = [] - ind = 0 - finished = False - - while not finished: - finished = True - for key in prioritized_keys: - if ind < len(prioritize_map[key]): - finished = False - order.append((key, ind)) - ind += 1 - curr_time = time.time() - - # Add grace time for final build at end - remaining_time = int(TOTAL_BUILD_TIME - (start_time - curr_time) - - GRACE_TIME) - try: - with time_limit(remaining_time): - num_non_buggy = 1 - ind = 0 - while ind < len(order): - with utils.restore_directory(src), utils.restore_directory( - work): - key, line = order[ind] - mutant = prioritize_map[key][line] - print(mutant) - suffix = "." + mutant.split(".")[-1] - mpart = ".mutant." + mutant.split(".mutant.")[1] - source_file = f"{src}/{mutant.replace(mpart, suffix)}" - print(source_file) - print(f"{mutate_dir}/{mutant}") - os.system(f"cp {source_file} {mutate_dir}/orig") - os.system(f"cp {mutate_dir}/{mutant} {source_file}") - try: - new_fuzz_target = f"{os.getenv('FUZZ_TARGET')}"\ - f".{num_non_buggy}" - - os.system(f"rm -rf {out}/*") - aflplusplus_fuzzer.build() - if not filecmp.cmp(f'{mutate_bins}/{orig_fuzz_target}', - f'{out}/{orig_fuzz_target}', - shallow=False): - print(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - num_non_buggy += 1 - print(f"FOUND NOT EQUAL {num_non_buggy}, \ - ind: {ind}") - else: - print(f"EQUAL {num_non_buggy}, ind: {ind}") - except RuntimeError: - pass - except CalledProcessError: - pass - os.system(f"cp {mutate_dir}/orig {source_file}") - ind += 1 - except TimeoutException: - pass - - os.system(f"rm -rf {out}/*") - os.system(f"cp -r {orig_out}/* {out}/") - os.system(f"cp {mutate_bins}/* {out}/") - - -def fuzz(input_corpus, output_corpus, target_binary): - """Run fuzzer.""" - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - total_mutant_time = int(FUZZ_PROP * total_fuzzing_time) - - mutants = glob.glob(f"{target_binary}.*") - random.shuffle(mutants) - timeout = max(DEFAULT_MUTANT_TIMEOUT, - int(total_mutant_time / max(len(mutants), 1))) - num_mutants = min(math.ceil(total_mutant_time / timeout), len(mutants)) - - input_corpus_dir = "/storage/input_corpus" - os.makedirs(input_corpus_dir, exist_ok=True) - crashes_dir = "/storage/crashes" - os.makedirs(crashes_dir, exist_ok=True) - os.environ['AFL_SKIP_CRASHES'] = "1" - - for mutant in mutants[:num_mutants]: - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - os.system(f"rm -rf {input_corpus_dir}/*") - with utils.restore_directory(input_corpus), utils.restore_directory( - output_corpus): - try: - with time_limit(timeout): - aflplusplus_fuzzer.fuzz(input_corpus, output_corpus, mutant) - except TimeoutException: - pass - except CalledProcessError: - pass - - os.system(f"cp {output_corpus}/default/crashes/crashes.*/id* \ - {crashes_dir}/") - os.system(f"cp {output_corpus}/default/crashes/crashes.*/id* \ - {input_corpus_dir}/") - os.system(f"cp {output_corpus}/default/queue/* {input_corpus_dir}/") - - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/") - aflplusplus_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/aflplusplus_um_prioritize_75/description.md b/fuzzers/aflplusplus_um_prioritize_75/description.md deleted file mode 100644 index d5bfe6fea..000000000 --- a/fuzzers/aflplusplus_um_prioritize_75/description.md +++ /dev/null @@ -1,9 +0,0 @@ -# aflplusplus UM (prioritize) - -Run aflplusplus over mutated code with UM prioritization - -NOTE: This only works with C or C++ benchmarks. - -[builder.Dockerfile](builder.Dockerfile) -[fuzzer.py](fuzzer.py) -[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_um_prioritize_75/fuzzer.py b/fuzzers/aflplusplus_um_prioritize_75/fuzzer.py deleted file mode 100755 index fdbed1a6a..000000000 --- a/fuzzers/aflplusplus_um_prioritize_75/fuzzer.py +++ /dev/null @@ -1,259 +0,0 @@ -# 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 glob -import os -from pathlib import Path -import random -import shutil -import filecmp -from subprocess import CalledProcessError -import time -import math -import signal -from contextlib import contextmanager - -from fuzzers.aflplusplus import fuzzer as aflplusplus_fuzzer -from fuzzers import utils - - -class TimeoutException(Exception): - """"Exception thrown when timeouts occur""" - - -TOTAL_FUZZING_TIME_DEFAULT = 82800 # 23 hours -TOTAL_BUILD_TIME = 43200 # 12 hours -FUZZ_PROP = 0.75 -DEFAULT_MUTANT_TIMEOUT = 300 -PRIORITIZE_MULTIPLIER = 5 -GRACE_TIME = 3600 # 1 hour in seconds -MAX_MUTANTS = 200000 -MAX_PRIORITIZE = 30 - - -@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 build(): # pylint: disable=too-many-locals,too-many-statements,too-many-branches - """Build benchmark.""" - start_time = time.time() - - out = os.getenv("OUT") - src = os.getenv("SRC") - work = os.getenv("WORK") - storage_dir = "/storage" - os.mkdir(storage_dir) - mutate_dir = f"{storage_dir}/mutant_files" - os.mkdir(mutate_dir) - mutate_bins = f"{storage_dir}/mutant_bins" - os.mkdir(mutate_bins) - mutate_scripts = f"{storage_dir}/mutant_scripts" - os.mkdir(mutate_scripts) - orig_out = f"{storage_dir}/orig_out" - os.mkdir(orig_out) - - orig_fuzz_target = os.getenv("FUZZ_TARGET") - with utils.restore_directory(src), utils.restore_directory(work): - aflplusplus_fuzzer.build() - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{orig_fuzz_target}") - os.system(f"cp -r {out}/* {orig_out}/") - benchmark = os.getenv("BENCHMARK") - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - - source_extensions = [".c", ".cc", ".cpp"] - num_mutants = math.ceil( - (total_fuzzing_time * FUZZ_PROP) / DEFAULT_MUTANT_TIMEOUT) - # Use heuristic to try to find benchmark directory, otherwise look for all - # files in the current directory. - subdirs = [ - name for name in os.listdir(src) - if os.path.isdir(os.path.join(src, name)) - ] - benchmark_src_dir = src - for directory in subdirs: - if directory in benchmark: - benchmark_src_dir = os.path.join(src, directory) - break - - source_files = [] - for extension in source_extensions: - source_files += glob.glob(f"{benchmark_src_dir}/**/*{extension}", - recursive=True) - random.shuffle(source_files) - - mutants_map = {} - num_mutants = 0 - for source_file in source_files: - source_dir = os.path.dirname(source_file).split(src, 1)[1] - Path(f"{mutate_dir}/{source_dir}").mkdir(parents=True, exist_ok=True) - os.system(f"mutate {source_file} --mutantDir \ - {mutate_dir}/{source_dir} --noCheck > /dev/null") - source_base = os.path.basename(source_file).split(".")[0] - mutants_glob = glob.glob( - f"{mutate_dir}/{source_dir}/{source_base}.mutant.*") - mutants = [ - f"{source_dir}/{mutant.split('/')[-1]}"[1:] - for mutant in mutants_glob - ] - num_mutants += len(mutants) - mutants_map[source_file] = mutants - if num_mutants > MAX_MUTANTS: - break - - prioritize_map = {} - num_prioritized = min( - math.ceil((num_mutants * PRIORITIZE_MULTIPLIER) / len(mutants_map)), - MAX_PRIORITIZE) - for source_file in mutants_map: - mutants = mutants_map[source_file] - with open(f"{mutate_dir}/mutants.txt", "w", encoding="utf_8") as f_name: - f_name.writelines(f"{l}\n" for l in mutants) - os.system(f"prioritize_mutants {mutate_dir}/mutants.txt \ - {mutate_dir}/prioritize_mutants_sorted.txt {num_prioritized}\ - --noSDPriority --sourceDir {src} --mutantDir {mutate_dir}") - prioritized_list = [] - with open(f"{mutate_dir}/prioritize_mutants_sorted.txt", - "r", - encoding="utf_8") as f_name: - prioritized_list = f_name.read().splitlines() - prioritize_map[source_file] = prioritized_list - - prioritized_keys = list(prioritize_map.keys()) - random.shuffle(prioritized_keys) - order = [] - ind = 0 - finished = False - - while not finished: - finished = True - for key in prioritized_keys: - if ind < len(prioritize_map[key]): - finished = False - order.append((key, ind)) - ind += 1 - curr_time = time.time() - - # Add grace time for final build at end - remaining_time = int(TOTAL_BUILD_TIME - (start_time - curr_time) - - GRACE_TIME) - try: - with time_limit(remaining_time): - num_non_buggy = 1 - ind = 0 - while ind < len(order): - with utils.restore_directory(src), utils.restore_directory( - work): - key, line = order[ind] - mutant = prioritize_map[key][line] - print(mutant) - suffix = "." + mutant.split(".")[-1] - mpart = ".mutant." + mutant.split(".mutant.")[1] - source_file = f"{src}/{mutant.replace(mpart, suffix)}" - print(source_file) - print(f"{mutate_dir}/{mutant}") - os.system(f"cp {source_file} {mutate_dir}/orig") - os.system(f"cp {mutate_dir}/{mutant} {source_file}") - try: - new_fuzz_target = f"{os.getenv('FUZZ_TARGET')}"\ - f".{num_non_buggy}" - - os.system(f"rm -rf {out}/*") - aflplusplus_fuzzer.build() - if not filecmp.cmp(f'{mutate_bins}/{orig_fuzz_target}', - f'{out}/{orig_fuzz_target}', - shallow=False): - print(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - num_non_buggy += 1 - print(f"FOUND NOT EQUAL {num_non_buggy}, \ - ind: {ind}") - else: - print(f"EQUAL {num_non_buggy}, ind: {ind}") - except RuntimeError: - pass - except CalledProcessError: - pass - os.system(f"cp {mutate_dir}/orig {source_file}") - ind += 1 - except TimeoutException: - pass - - os.system(f"rm -rf {out}/*") - os.system(f"cp -r {orig_out}/* {out}/") - os.system(f"cp {mutate_bins}/* {out}/") - - -def fuzz(input_corpus, output_corpus, target_binary): - """Run fuzzer.""" - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - total_mutant_time = int(FUZZ_PROP * total_fuzzing_time) - - mutants = glob.glob(f"{target_binary}.*") - random.shuffle(mutants) - timeout = max(DEFAULT_MUTANT_TIMEOUT, - int(total_mutant_time / max(len(mutants), 1))) - num_mutants = min(math.ceil(total_mutant_time / timeout), len(mutants)) - - input_corpus_dir = "/storage/input_corpus" - os.makedirs(input_corpus_dir, exist_ok=True) - crashes_dir = "/storage/crashes" - os.makedirs(crashes_dir, exist_ok=True) - os.environ['AFL_SKIP_CRASHES'] = "1" - - for mutant in mutants[:num_mutants]: - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - os.system(f"rm -rf {input_corpus_dir}/*") - with utils.restore_directory(input_corpus), utils.restore_directory( - output_corpus): - try: - with time_limit(timeout): - aflplusplus_fuzzer.fuzz(input_corpus, output_corpus, mutant) - except TimeoutException: - pass - except CalledProcessError: - pass - - os.system(f"cp {output_corpus}/default/crashes/crashes.*/id* \ - {crashes_dir}/") - os.system(f"cp {output_corpus}/default/crashes/crashes.*/id* \ - {input_corpus_dir}/") - os.system(f"cp {output_corpus}/default/queue/* {input_corpus_dir}/") - - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/") - aflplusplus_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/aflplusplus_um_random/builder.Dockerfile b/fuzzers/aflplusplus_um_random/builder.Dockerfile deleted file mode 100644 index abd77021b..000000000 --- a/fuzzers/aflplusplus_um_random/builder.Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -# 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 apt-get update && apt-get install -y python3 -RUN pip3 install --upgrade --force pip -RUN pip install universalmutator - -# 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 b847e0f414e7b310e1a68bc501d4e2453bfce70e - -# 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 / - diff --git a/fuzzers/aflplusplus_um_random/description.md b/fuzzers/aflplusplus_um_random/description.md deleted file mode 100644 index 686a166cb..000000000 --- a/fuzzers/aflplusplus_um_random/description.md +++ /dev/null @@ -1,10 +0,0 @@ -# aflplusplus UM (random) - -Run aflplusplus over mutated code without UM prioritization. Randomly sample -list of generated mutants. - -NOTE: This only works with C or C++ benchmarks. - -[builder.Dockerfile](builder.Dockerfile) -[fuzzer.py](fuzzer.py) -[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_um_random/fuzzer.py b/fuzzers/aflplusplus_um_random/fuzzer.py deleted file mode 100644 index 511a6fd6c..000000000 --- a/fuzzers/aflplusplus_um_random/fuzzer.py +++ /dev/null @@ -1,221 +0,0 @@ -# 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 glob -import os -from pathlib import Path -import random -import shutil -import filecmp -from subprocess import CalledProcessError -import time -import signal -import math -from contextlib import contextmanager - -from fuzzers.aflplusplus import fuzzer as aflplusplus_fuzzer -from fuzzers import utils - - -class TimeoutException(Exception): - """"Exception thrown when timeouts occur""" - - -TOTAL_FUZZING_TIME_DEFAULT = 82800 # 23 hours -TOTAL_BUILD_TIME = 43200 # 12 hours -FUZZ_PROP = 0.5 -DEFAULT_MUTANT_TIMEOUT = 300 -GRACE_TIME = 3600 # 1 hour in seconds -MAX_MUTANTS = 200000 - - -@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 build(): # pylint: disable=too-many-locals,too-many-statements - """Build benchmark.""" - start_time = time.time() - - out = os.getenv("OUT") - src = os.getenv("SRC") - work = os.getenv("WORK") - storage_dir = "/storage" - os.mkdir(storage_dir) - mutate_dir = f"{storage_dir}/mutant_files" - os.mkdir(mutate_dir) - mutate_bins = f"{storage_dir}/mutant_bins" - os.mkdir(mutate_bins) - mutate_scripts = f"{storage_dir}/mutant_scripts" - os.mkdir(mutate_scripts) - orig_out = f"{storage_dir}/orig_out" - os.mkdir(orig_out) - - orig_fuzz_target = os.getenv("FUZZ_TARGET") - with utils.restore_directory(src), utils.restore_directory(work): - aflplusplus_fuzzer.build() - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{orig_fuzz_target}") - os.system(f"cp -r {out}/* {orig_out}/") - benchmark = os.getenv("BENCHMARK") - - source_extensions = [".c", ".cc", ".cpp"] - # Use heuristic to try to find benchmark directory, - # otherwise look for all files in the current directory. - subdirs = [ - name for name in os.listdir(src) - if os.path.isdir(os.path.join(src, name)) - ] - benchmark_src_dir = src - for directory in subdirs: - if directory in benchmark: - benchmark_src_dir = os.path.join(src, directory) - break - - source_files = [] - for extension in source_extensions: - source_files += glob.glob(f"{benchmark_src_dir}/**/*{extension}", - recursive=True) - random.shuffle(source_files) - - mutants = [] - for source_file in source_files: - source_dir = os.path.dirname(source_file).split(src, 1)[1] - Path(f"{mutate_dir}/{source_dir}").mkdir(parents=True, exist_ok=True) - os.system(f"mutate {source_file} --mutantDir \ - {mutate_dir}/{source_dir} --noCheck > /dev/null") - source_base = os.path.basename(source_file).split(".")[0] - mutants_glob = glob.glob( - f"{mutate_dir}/{source_dir}/{source_base}.mutant.*") - mutants += [ - f"{source_dir}/{mutant.split('/')[-1]}"[1:] - for mutant in mutants_glob - ] - - if len(mutants) > MAX_MUTANTS: - break - - random.shuffle(mutants) - with open(f"{mutate_dir}/mutants.txt", "w", encoding="utf-8") as f_name: - f_name.writelines(f"{l}\n" for l in mutants) - - curr_time = time.time() - - # Add grace time for final build at end - remaining_time = int(TOTAL_BUILD_TIME - (start_time - curr_time) - - GRACE_TIME) - try: - with time_limit(remaining_time): - num_non_buggy = 1 - ind = 0 - while ind < len(mutants): - with utils.restore_directory(src), utils.restore_directory( - work): - mutant = mutants[ind] - suffix = "." + mutant.split(".")[-1] - mpart = ".mutant." + mutant.split(".mutant.")[1] - source_file = f"{src}/{mutant.replace(mpart, suffix)}" - print(source_file) - print(f"{mutate_dir}/{mutant}") - os.system(f"cp {source_file} {mutate_dir}/orig") - os.system(f"cp {mutate_dir}/{mutant} {source_file}") - - try: - new_fuzz_target = f"{os.getenv('FUZZ_TARGET')}"\ - f".{num_non_buggy}" - - os.system(f"rm -rf {out}/*") - aflplusplus_fuzzer.build() - if not filecmp.cmp(f'{mutate_bins}/{orig_fuzz_target}', - f'{out}/{orig_fuzz_target}', - shallow=False): - print(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - num_non_buggy += 1 - else: - print("EQUAL") - except RuntimeError: - pass - except CalledProcessError: - pass - os.system(f"cp {mutate_dir}/orig {source_file}") - ind += 1 - except TimeoutException: - pass - - os.system(f"rm -rf {out}/*") - os.system(f"cp -r {orig_out}/* {out}/") - os.system(f"cp {mutate_bins}/* {out}/") - - -def fuzz(input_corpus, output_corpus, target_binary): - """Run fuzzer.""" - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - total_mutant_time = int(FUZZ_PROP * total_fuzzing_time) - - mutants = glob.glob(f"{target_binary}.*") - random.shuffle(mutants) - timeout = max(DEFAULT_MUTANT_TIMEOUT, - int(total_mutant_time / max(len(mutants), 1))) - num_mutants = min(math.ceil(total_mutant_time / timeout), len(mutants)) - - input_corpus_dir = "/storage/input_corpus" - os.makedirs(input_corpus_dir, exist_ok=True) - crashes_dir = "/storage/crashes" - os.makedirs(crashes_dir, exist_ok=True) - os.environ['AFL_SKIP_CRASHES'] = "1" - - for mutant in mutants[:num_mutants]: - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - os.system(f"rm -rf {input_corpus_dir}/*") - with utils.restore_directory(input_corpus), utils.restore_directory( - output_corpus): - try: - with time_limit(timeout): - aflplusplus_fuzzer.fuzz(input_corpus, output_corpus, mutant) - except TimeoutException: - pass - except CalledProcessError: - pass - - os.system(f"cp {output_corpus}/default/crashes/crashes.*/id* \ - {crashes_dir}/") - os.system(f"cp {output_corpus}/default/crashes/crashes.*/id* \ - {input_corpus_dir}/") - os.system(f"cp {output_corpus}/default/queue/* {input_corpus_dir}/") - - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/") - aflplusplus_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/aflplusplus_um_random_75/builder.Dockerfile b/fuzzers/aflplusplus_um_random_75/builder.Dockerfile deleted file mode 100644 index 33c94647b..000000000 --- a/fuzzers/aflplusplus_um_random_75/builder.Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -# 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 apt-get update && apt-get install -y python3 -RUN pip3 install --upgrade --force pip -RUN pip install universalmutator - -# Install libstdc++ to use llvm_mode. -RUN apt-get update && \ - apt-get install -y wget libstdc++-10-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 b847e0f414e7b310e1a68bc501d4e2453bfce70e - -# 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 / - diff --git a/fuzzers/aflplusplus_um_random_75/description.md b/fuzzers/aflplusplus_um_random_75/description.md deleted file mode 100644 index 686a166cb..000000000 --- a/fuzzers/aflplusplus_um_random_75/description.md +++ /dev/null @@ -1,10 +0,0 @@ -# aflplusplus UM (random) - -Run aflplusplus over mutated code without UM prioritization. Randomly sample -list of generated mutants. - -NOTE: This only works with C or C++ benchmarks. - -[builder.Dockerfile](builder.Dockerfile) -[fuzzer.py](fuzzer.py) -[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_um_random_75/fuzzer.py b/fuzzers/aflplusplus_um_random_75/fuzzer.py deleted file mode 100644 index 15e2cd873..000000000 --- a/fuzzers/aflplusplus_um_random_75/fuzzer.py +++ /dev/null @@ -1,213 +0,0 @@ -# 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 glob -import os -from pathlib import Path -import random -import shutil -import filecmp -from subprocess import CalledProcessError -import time -import signal -import math -from contextlib import contextmanager - -from fuzzers.aflplusplus import fuzzer as aflplusplus_fuzzer -from fuzzers import utils - - -class TimeoutException(Exception): - """"Exception thrown when timeouts occur""" - - -TOTAL_FUZZING_TIME_DEFAULT = 82800 # 23 hours -TOTAL_BUILD_TIME = 43200 # 12 hours -FUZZ_PROP = 0.75 -DEFAULT_MUTANT_TIMEOUT = 300 -GRACE_TIME = 3600 # 1 hour in seconds -MAX_MUTANTS = 200000 - - -@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 build(): # pylint: disable=too-many-locals,too-many-statements - """Build benchmark.""" - start_time = time.time() - - out = os.getenv("OUT") - src = os.getenv("SRC") - work = os.getenv("WORK") - storage_dir = "/storage" - os.mkdir(storage_dir) - mutate_dir = f"{storage_dir}/mutant_files" - os.mkdir(mutate_dir) - mutate_bins = f"{storage_dir}/mutant_bins" - os.mkdir(mutate_bins) - mutate_scripts = f"{storage_dir}/mutant_scripts" - os.mkdir(mutate_scripts) - orig_out = f"{storage_dir}/orig_out" - os.mkdir(orig_out) - - orig_fuzz_target = os.getenv("FUZZ_TARGET") - with utils.restore_directory(src), utils.restore_directory(work): - aflplusplus_fuzzer.build() - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{orig_fuzz_target}") - os.system(f"cp -r {out}/* {orig_out}/") - benchmark = os.getenv("BENCHMARK") - - source_extensions = [".c", ".cc", ".cpp"] - # Use heuristic to try to find benchmark directory, - # otherwise look for all files in the current directory. - subdirs = [ - name for name in os.listdir(src) - if os.path.isdir(os.path.join(src, name)) - ] - benchmark_src_dir = src - for directory in subdirs: - if directory in benchmark: - benchmark_src_dir = os.path.join(src, directory) - break - - source_files = [] - for extension in source_extensions: - source_files += glob.glob(f"{benchmark_src_dir}/**/*{extension}", - recursive=True) - random.shuffle(source_files) - - mutants = [] - for source_file in source_files: - source_dir = os.path.dirname(source_file).split(src, 1)[1] - Path(f"{mutate_dir}/{source_dir}").mkdir(parents=True, exist_ok=True) - os.system(f"mutate {source_file} --mutantDir \ - {mutate_dir}/{source_dir} --noCheck > /dev/null") - source_base = os.path.basename(source_file).split(".")[0] - mutants_glob = glob.glob( - f"{mutate_dir}/{source_dir}/{source_base}.mutant.*") - mutants += [ - f"{source_dir}/{mutant.split('/')[-1]}"[1:] - for mutant in mutants_glob - ] - - if len(mutants) > MAX_MUTANTS: - break - - random.shuffle(mutants) - with open(f"{mutate_dir}/mutants.txt", "w", encoding="utf-8") as f_name: - f_name.writelines(f"{l}\n" for l in mutants) - - curr_time = time.time() - - # Add grace time for final build at end - remaining_time = int(TOTAL_BUILD_TIME - (start_time - curr_time) - - GRACE_TIME) - try: - with time_limit(remaining_time): - num_non_buggy = 1 - ind = 0 - while ind < len(mutants): - with utils.restore_directory(src), utils.restore_directory( - work): - mutant = mutants[ind] - suffix = "." + mutant.split(".")[-1] - mpart = ".mutant." + mutant.split(".mutant.")[1] - source_file = f"{src}/{mutant.replace(mpart, suffix)}" - print(source_file) - print(f"{mutate_dir}/{mutant}") - os.system(f"cp {source_file} {mutate_dir}/orig") - os.system(f"cp {mutate_dir}/{mutant} {source_file}") - - try: - new_fuzz_target = f"{os.getenv('FUZZ_TARGET')}"\ - f".{num_non_buggy}" - - os.system(f"rm -rf {out}/*") - aflplusplus_fuzzer.build() - if not filecmp.cmp(f'{mutate_bins}/{orig_fuzz_target}', - f'{out}/{orig_fuzz_target}', - shallow=False): - print(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - num_non_buggy += 1 - else: - print("EQUAL") - except RuntimeError: - pass - except CalledProcessError: - pass - os.system(f"cp {mutate_dir}/orig {source_file}") - ind += 1 - except TimeoutException: - pass - - os.system(f"rm -rf {out}/*") - os.system(f"cp -r {orig_out}/* {out}/") - os.system(f"cp {mutate_bins}/* {out}/") - - -def fuzz(input_corpus, output_corpus, target_binary): - """Run fuzzer.""" - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - total_mutant_time = int(FUZZ_PROP * total_fuzzing_time) - - mutants = glob.glob(f"{target_binary}.*") - random.shuffle(mutants) - timeout = max(DEFAULT_MUTANT_TIMEOUT, - int(total_mutant_time / max(len(mutants), 1))) - num_mutants = min(math.ceil(total_mutant_time / timeout), len(mutants)) - - input_corpus_dir = "/storage/input_corpus" - os.makedirs(input_corpus_dir, exist_ok=True) - os.environ['AFL_SKIP_CRASHES'] = "1" - - for mutant in mutants[:num_mutants]: - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - with utils.restore_directory(input_corpus), utils.restore_directory( - output_corpus): - try: - with time_limit(timeout): - aflplusplus_fuzzer.fuzz(input_corpus, output_corpus, mutant) - except TimeoutException: - pass - except CalledProcessError: - pass - os.system(f"cp -r {output_corpus}/* {input_corpus_dir}/*") - - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - aflplusplus_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/aflplusplus_um_random_75/runner.Dockerfile b/fuzzers/aflplusplus_um_random_75/runner.Dockerfile deleted file mode 100644 index 7aa1da8e4..000000000 --- a/fuzzers/aflplusplus_um_random_75/runner.Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# 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 diff --git a/fuzzers/aflplusplus_vp0/builder.Dockerfile b/fuzzers/aflplusplus_vp0/builder.Dockerfile new file mode 100644 index 000000000..e7db04f45 --- /dev/null +++ b/fuzzers/aflplusplus_vp0/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b vp https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout 595cc3aaddb27f2f1b9a74d218f7279975c10cb5 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_vp0/description.md b/fuzzers/aflplusplus_vp0/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_vp0/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_vp0/fuzzer.py b/fuzzers/aflplusplus_vp0/fuzzer.py new file mode 100755 index 000000000..41433ac09 --- /dev/null +++ b/fuzzers/aflplusplus_vp0/fuzzer.py @@ -0,0 +1,288 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'dict2file'] + #build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + os.environ['AFL_LLVM_VALUEPROFILE'] = '1' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + flags += ['-k', '0'] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_vp0/runner.Dockerfile b/fuzzers/aflplusplus_vp0/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_vp0/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_vp1/builder.Dockerfile b/fuzzers/aflplusplus_vp1/builder.Dockerfile new file mode 100644 index 000000000..559781809 --- /dev/null +++ b/fuzzers/aflplusplus_vp1/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b vp https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout e8caa32b0e7c12225068937bacb71bc29b938845 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_vp1/description.md b/fuzzers/aflplusplus_vp1/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_vp1/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_vp1/fuzzer.py b/fuzzers/aflplusplus_vp1/fuzzer.py new file mode 100755 index 000000000..bf1c1b168 --- /dev/null +++ b/fuzzers/aflplusplus_vp1/fuzzer.py @@ -0,0 +1,288 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'dict2file'] + #build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + os.environ['AFL_LLVM_VALUEPROFILE'] = '1' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + flags += ['-k', '1'] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_vp1/runner.Dockerfile b/fuzzers/aflplusplus_vp1/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_vp1/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_z1/builder.Dockerfile b/fuzzers/aflplusplus_z1/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_z1/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_z1/description.md b/fuzzers/aflplusplus_z1/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_z1/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_z1/fuzzer.py b/fuzzers/aflplusplus_z1/fuzzer.py new file mode 100755 index 000000000..d77a1f071 --- /dev/null +++ b/fuzzers/aflplusplus_z1/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-Z'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_z1/runner.Dockerfile b/fuzzers/aflplusplus_z1/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_z1/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_z2/builder.Dockerfile b/fuzzers/aflplusplus_z2/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_z2/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_z2/description.md b/fuzzers/aflplusplus_z2/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_z2/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_z2/fuzzer.py b/fuzzers/aflplusplus_z2/fuzzer.py new file mode 100755 index 000000000..d77a1f071 --- /dev/null +++ b/fuzzers/aflplusplus_z2/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-Z'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_z2/runner.Dockerfile b/fuzzers/aflplusplus_z2/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_z2/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_z3/builder.Dockerfile b/fuzzers/aflplusplus_z3/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_z3/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_z3/description.md b/fuzzers/aflplusplus_z3/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_z3/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_z3/fuzzer.py b/fuzzers/aflplusplus_z3/fuzzer.py new file mode 100755 index 000000000..d77a1f071 --- /dev/null +++ b/fuzzers/aflplusplus_z3/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-Z'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_z3/runner.Dockerfile b/fuzzers/aflplusplus_z3/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_z3/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_z4/builder.Dockerfile b/fuzzers/aflplusplus_z4/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_z4/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_z4/description.md b/fuzzers/aflplusplus_z4/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_z4/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_z4/fuzzer.py b/fuzzers/aflplusplus_z4/fuzzer.py new file mode 100755 index 000000000..d77a1f071 --- /dev/null +++ b/fuzzers/aflplusplus_z4/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-Z'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_z4/runner.Dockerfile b/fuzzers/aflplusplus_z4/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_z4/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflplusplus_z5/builder.Dockerfile b/fuzzers/aflplusplus_z5/builder.Dockerfile new file mode 100644 index 000000000..8e88d048a --- /dev/null +++ b/fuzzers/aflplusplus_z5/builder.Dockerfile @@ -0,0 +1,47 @@ +# 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 apt-get update && \ + 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 afl++. +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl && \ + cd /afl && \ + git checkout d206d5fc46f40e4b085c284abfd9409841a07877 + +# Build without Python support as we don't need it. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / diff --git a/fuzzers/aflplusplus_z5/description.md b/fuzzers/aflplusplus_z5/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/aflplusplus_z5/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/aflplusplus_z5/fuzzer.py b/fuzzers/aflplusplus_z5/fuzzer.py new file mode 100755 index 000000000..d77a1f071 --- /dev/null +++ b/fuzzers/aflplusplus_z5/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + flags += ['-Z'] + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/aflplusplus_z5/runner.Dockerfile b/fuzzers/aflplusplus_z5/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/aflplusplus_z5/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflpp_random_default/runner.Dockerfile b/fuzzers/aflpp_random_default/runner.Dockerfile deleted file mode 100644 index 7aa1da8e4..000000000 --- a/fuzzers/aflpp_random_default/runner.Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# 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 diff --git a/fuzzers/aflpp_random_no_favs/runner.Dockerfile b/fuzzers/aflpp_random_no_favs/runner.Dockerfile deleted file mode 100644 index 7aa1da8e4..000000000 --- a/fuzzers/aflpp_random_no_favs/runner.Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# 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 diff --git a/fuzzers/aflpp_random_wrs/runner.Dockerfile b/fuzzers/aflpp_random_wrs/runner.Dockerfile deleted file mode 100644 index 7aa1da8e4..000000000 --- a/fuzzers/aflpp_random_wrs/runner.Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# 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 diff --git a/fuzzers/aflpp_random_wrs_rf/runner.Dockerfile b/fuzzers/aflpp_random_wrs_rf/runner.Dockerfile deleted file mode 100644 index 7aa1da8e4..000000000 --- a/fuzzers/aflpp_random_wrs_rf/runner.Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# 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 diff --git a/fuzzers/aflpp_random_wrs_rf_rp/builder.Dockerfile b/fuzzers/aflpp_random_wrs_rf_rp/builder.Dockerfile deleted file mode 100644 index c4066c277..000000000 --- a/fuzzers/aflpp_random_wrs_rf_rp/builder.Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -# 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/jiradeto/AFLplusplus /afl && \ - cd /afl && \ - git checkout port_random_fuzzing_to_afl++ - -# 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 / diff --git a/fuzzers/aflpp_random_wrs_rf_rp/fuzzer.py b/fuzzers/aflpp_random_wrs_rf_rp/fuzzer.py deleted file mode 100755 index f51c59195..000000000 --- a/fuzzers/aflpp_random_wrs_rf_rp/fuzzer.py +++ /dev/null @@ -1,268 +0,0 @@ -# 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.""" - -import os -import shutil - -from fuzzers.afl import fuzzer as afl_fuzzer -from fuzzers import utils - - -def get_cmplog_build_directory(target_directory): - """Return path to CmpLog target directory.""" - return os.path.join(target_directory, 'cmplog') - - -def get_uninstrumented_build_directory(target_directory): - """Return path to CmpLog target directory.""" - return os.path.join(target_directory, 'uninstrumented') - - -def build(*args): # pylint: disable=too-many-branches,too-many-statements - """Build benchmark.""" - # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide - # a default configuration. - - build_modes = list(args) - if 'BUILD_MODES' in os.environ: - build_modes = os.environ['BUILD_MODES'].split(',') - - # Placeholder comment. - build_directory = os.environ['OUT'] - - # If nothing was set this is the default: - if not build_modes: - build_modes = ['tracepc', 'cmplog', 'dict2file'] - - # For bug type benchmarks we have to instrument via native clang pcguard :( - build_flags = os.environ['CFLAGS'] - if build_flags.find( - 'array-bounds' - ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: - build_modes[0] = 'native' - - # Instrumentation coverage modes: - if 'lto' in build_modes: - os.environ['CC'] = '/afl/afl-clang-lto' - os.environ['CXX'] = '/afl/afl-clang-lto++' - edge_file = build_directory + '/aflpp_edges.txt' - os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file - if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): - os.environ['RANLIB'] = 'llvm-ranlib-13' - os.environ['AR'] = 'llvm-ar-13' - os.environ['AS'] = 'llvm-as-13' - elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): - os.environ['RANLIB'] = 'llvm-ranlib-12' - os.environ['AR'] = 'llvm-ar-12' - os.environ['AS'] = 'llvm-as-12' - else: - os.environ['RANLIB'] = 'llvm-ranlib' - os.environ['AR'] = 'llvm-ar' - os.environ['AS'] = 'llvm-as' - elif 'qemu' in build_modes: - os.environ['CC'] = 'clang' - os.environ['CXX'] = 'clang++' - elif 'gcc' in build_modes: - os.environ['CC'] = 'afl-gcc-fast' - os.environ['CXX'] = 'afl-g++-fast' - else: - os.environ['CC'] = '/afl/afl-clang-fast' - os.environ['CXX'] = '/afl/afl-clang-fast++' - - print('AFL++ build: ') - print(build_modes) - - if 'qemu' in build_modes or 'symcc' in build_modes: - os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) - cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS - os.environ['CXXFLAGS'] = ' '.join(cxxflags) - - if 'tracepc' in build_modes or 'pcguard' in build_modes: - os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' - elif 'classic' in build_modes: - os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' - elif 'native' in build_modes: - os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' - - # Instrumentation coverage options: - # Do not use a fixed map location (LTO only) - if 'dynamic' in build_modes: - os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' - # Use a fixed map location (LTO only) - if 'fixed' in build_modes: - os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' - # Generate an extra dictionary. - if 'dict2file' in build_modes or 'native' in build_modes: - os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' - # Enable context sentitivity for LLVM mode (non LTO only) - if 'ctx' in build_modes: - os.environ['AFL_LLVM_CTX'] = '1' - # Enable N-gram coverage for LLVM mode (non LTO only) - if 'ngram2' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' - elif 'ngram3' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' - elif 'ngram4' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' - elif 'ngram5' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' - elif 'ngram6' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' - elif 'ngram7' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' - elif 'ngram8' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' - elif 'ngram16' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' - if 'ctx1' in build_modes: - os.environ['AFL_LLVM_CTX_K'] = '1' - elif 'ctx2' in build_modes: - os.environ['AFL_LLVM_CTX_K'] = '2' - elif 'ctx3' in build_modes: - os.environ['AFL_LLVM_CTX_K'] = '3' - elif 'ctx4' in build_modes: - os.environ['AFL_LLVM_CTX_K'] = '4' - - # Only one of the following OR cmplog - # enable laf-intel compare splitting - if 'laf' in build_modes: - os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' - os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' - os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' - if 'autodict' not in build_modes: - os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' - - if 'eclipser' in build_modes: - os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' - else: - os.environ['FUZZER_LIB'] = '/libAFLDriver.a' - - # Some benchmarks like lcms. (see: - # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) - # fail to compile if the compiler outputs things to stderr in unexpected - # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast - # from writing AFL specific messages to stderr. - os.environ['AFL_QUIET'] = '1' - os.environ['AFL_MAP_SIZE'] = '2621440' - - src = os.getenv('SRC') - work = os.getenv('WORK') - - with utils.restore_directory(src), utils.restore_directory(work): - # Restore SRC to its initial state so we can build again without any - # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run - # twice in the same directory without this. - utils.build_benchmark() - - if 'cmplog' in build_modes and 'qemu' not in build_modes: - - # CmpLog requires an build with different instrumentation. - new_env = os.environ.copy() - new_env['AFL_LLVM_CMPLOG'] = '1' - - # For CmpLog build, set the OUT and FUZZ_TARGET environment - # variable to point to the new CmpLog build directory. - cmplog_build_directory = get_cmplog_build_directory(build_directory) - os.mkdir(cmplog_build_directory) - new_env['OUT'] = cmplog_build_directory - fuzz_target = os.getenv('FUZZ_TARGET') - if fuzz_target: - new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, - os.path.basename(fuzz_target)) - - print('Re-building benchmark for CmpLog fuzzing target') - utils.build_benchmark(env=new_env) - - if 'symcc' in build_modes: - - symcc_build_directory = get_uninstrumented_build_directory( - build_directory) - os.mkdir(symcc_build_directory) - - # symcc requires an build with different instrumentation. - new_env = os.environ.copy() - new_env['CC'] = '/symcc/build/symcc' - new_env['CXX'] = '/symcc/build/sym++' - new_env['SYMCC_OUTPUT_DIR'] = '/tmp' - new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') - new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' - new_env['OUT'] = symcc_build_directory - new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' - new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' - new_env['SYMCC_SILENT'] = '1' - - # For CmpLog build, set the OUT and FUZZ_TARGET environment - # variable to point to the new CmpLog build directory. - new_env['OUT'] = symcc_build_directory - fuzz_target = os.getenv('FUZZ_TARGET') - if fuzz_target: - new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, - os.path.basename(fuzz_target)) - - print('Re-building benchmark for CmpLog fuzzing target') - utils.build_benchmark(env=new_env) - - shutil.copy('/afl/afl-fuzz', build_directory) - if os.path.exists('/afl/afl-qemu-trace'): - shutil.copy('/afl/afl-qemu-trace', build_directory) - if os.path.exists('/aflpp_qemu_driver_hook.so'): - shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) - if os.path.exists('/get_frida_entry.sh'): - shutil.copy('/afl/afl-frida-trace.so', build_directory) - shutil.copy('/get_frida_entry.sh', build_directory) - - -# pylint: disable=too-many-arguments -def fuzz(input_corpus, - output_corpus, - target_binary, - flags=tuple(), - skip=False, - no_cmplog=False): # pylint: disable=too-many-arguments - """Run fuzzer.""" - # Calculate CmpLog binary path from the instrumented target binary. - target_binary_directory = os.path.dirname(target_binary) - cmplog_target_binary_directory = ( - get_cmplog_build_directory(target_binary_directory)) - target_binary_name = os.path.basename(target_binary) - cmplog_target_binary = os.path.join(cmplog_target_binary_directory, - target_binary_name) - - afl_fuzzer.prepare_fuzz_environment(input_corpus) - # decomment this to enable libdislocator. - # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t - # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' - - flags = list(flags) - - if os.path.exists('./afl++.dict'): - flags += ['-x', './afl++.dict'] - - # Move the following to skip for upcoming _double tests: - if os.path.exists(cmplog_target_binary) and no_cmplog is not False: - flags += ['-c', cmplog_target_binary] - - if not skip: - os.environ['AFL_DISABLE_TRIM'] = '1' - # os.environ['AFL_FAST_CAL'] = '1' - os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' - if 'ADDITIONAL_ARGS' in os.environ: - flags += os.environ['ADDITIONAL_ARGS'].split(' ') - - afl_fuzzer.run_afl_fuzz(input_corpus, - output_corpus, - target_binary, - additional_flags=flags) diff --git a/fuzzers/aflpp_random_wrs_rf_rp/runner.Dockerfile b/fuzzers/aflpp_random_wrs_rf_rp/runner.Dockerfile deleted file mode 100644 index 7aa1da8e4..000000000 --- a/fuzzers/aflpp_random_wrs_rf_rp/runner.Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# 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 diff --git a/fuzzers/aflpp_random_wrs_rp/builder.Dockerfile b/fuzzers/aflpp_random_wrs_rp/builder.Dockerfile deleted file mode 100644 index c4066c277..000000000 --- a/fuzzers/aflpp_random_wrs_rp/builder.Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -# 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/jiradeto/AFLplusplus /afl && \ - cd /afl && \ - git checkout port_random_fuzzing_to_afl++ - -# 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 / diff --git a/fuzzers/aflpp_random_wrs_rp/fuzzer.py b/fuzzers/aflpp_random_wrs_rp/fuzzer.py deleted file mode 100755 index e6fe85980..000000000 --- a/fuzzers/aflpp_random_wrs_rp/fuzzer.py +++ /dev/null @@ -1,269 +0,0 @@ -# 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.""" - -import os -import shutil - -from fuzzers.afl import fuzzer as afl_fuzzer -from fuzzers import utils - - -def get_cmplog_build_directory(target_directory): - """Return path to CmpLog target directory.""" - return os.path.join(target_directory, 'cmplog') - - -def get_uninstrumented_build_directory(target_directory): - """Return path to CmpLog target directory.""" - return os.path.join(target_directory, 'uninstrumented') - - -def build(*args): # pylint: disable=too-many-branches,too-many-statements - """Build benchmark.""" - # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide - # a default configuration. - - build_modes = list(args) - if 'BUILD_MODES' in os.environ: - build_modes = os.environ['BUILD_MODES'].split(',') - - # Placeholder comment. - build_directory = os.environ['OUT'] - - # If nothing was set this is the default: - if not build_modes: - build_modes = ['tracepc', 'cmplog', 'dict2file'] - - # For bug type benchmarks we have to instrument via native clang pcguard :( - build_flags = os.environ['CFLAGS'] - if build_flags.find( - 'array-bounds' - ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: - build_modes[0] = 'native' - - # Instrumentation coverage modes: - if 'lto' in build_modes: - os.environ['CC'] = '/afl/afl-clang-lto' - os.environ['CXX'] = '/afl/afl-clang-lto++' - edge_file = build_directory + '/aflpp_edges.txt' - os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file - if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): - os.environ['RANLIB'] = 'llvm-ranlib-13' - os.environ['AR'] = 'llvm-ar-13' - os.environ['AS'] = 'llvm-as-13' - elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): - os.environ['RANLIB'] = 'llvm-ranlib-12' - os.environ['AR'] = 'llvm-ar-12' - os.environ['AS'] = 'llvm-as-12' - else: - os.environ['RANLIB'] = 'llvm-ranlib' - os.environ['AR'] = 'llvm-ar' - os.environ['AS'] = 'llvm-as' - elif 'qemu' in build_modes: - os.environ['CC'] = 'clang' - os.environ['CXX'] = 'clang++' - elif 'gcc' in build_modes: - os.environ['CC'] = 'afl-gcc-fast' - os.environ['CXX'] = 'afl-g++-fast' - else: - os.environ['CC'] = '/afl/afl-clang-fast' - os.environ['CXX'] = '/afl/afl-clang-fast++' - - print('AFL++ build: ') - print(build_modes) - - if 'qemu' in build_modes or 'symcc' in build_modes: - os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) - cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS - os.environ['CXXFLAGS'] = ' '.join(cxxflags) - - if 'tracepc' in build_modes or 'pcguard' in build_modes: - os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' - elif 'classic' in build_modes: - os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' - elif 'native' in build_modes: - os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' - - # Instrumentation coverage options: - # Do not use a fixed map location (LTO only) - if 'dynamic' in build_modes: - os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' - # Use a fixed map location (LTO only) - if 'fixed' in build_modes: - os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' - # Generate an extra dictionary. - if 'dict2file' in build_modes or 'native' in build_modes: - os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' - # Enable context sentitivity for LLVM mode (non LTO only) - if 'ctx' in build_modes: - os.environ['AFL_LLVM_CTX'] = '1' - # Enable N-gram coverage for LLVM mode (non LTO only) - if 'ngram2' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' - elif 'ngram3' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' - elif 'ngram4' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' - elif 'ngram5' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' - elif 'ngram6' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' - elif 'ngram7' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' - elif 'ngram8' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' - elif 'ngram16' in build_modes: - os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' - if 'ctx1' in build_modes: - os.environ['AFL_LLVM_CTX_K'] = '1' - elif 'ctx2' in build_modes: - os.environ['AFL_LLVM_CTX_K'] = '2' - elif 'ctx3' in build_modes: - os.environ['AFL_LLVM_CTX_K'] = '3' - elif 'ctx4' in build_modes: - os.environ['AFL_LLVM_CTX_K'] = '4' - - # Only one of the following OR cmplog - # enable laf-intel compare splitting - if 'laf' in build_modes: - os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' - os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' - os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' - if 'autodict' not in build_modes: - os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' - - if 'eclipser' in build_modes: - os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' - else: - os.environ['FUZZER_LIB'] = '/libAFLDriver.a' - - # Some benchmarks like lcms. (see: - # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) - # fail to compile if the compiler outputs things to stderr in unexpected - # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast - # from writing AFL specific messages to stderr. - os.environ['AFL_QUIET'] = '1' - os.environ['AFL_MAP_SIZE'] = '2621440' - - src = os.getenv('SRC') - work = os.getenv('WORK') - - with utils.restore_directory(src), utils.restore_directory(work): - # Restore SRC to its initial state so we can build again without any - # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run - # twice in the same directory without this. - utils.build_benchmark() - - if 'cmplog' in build_modes and 'qemu' not in build_modes: - - # CmpLog requires an build with different instrumentation. - new_env = os.environ.copy() - new_env['AFL_LLVM_CMPLOG'] = '1' - - # For CmpLog build, set the OUT and FUZZ_TARGET environment - # variable to point to the new CmpLog build directory. - cmplog_build_directory = get_cmplog_build_directory(build_directory) - os.mkdir(cmplog_build_directory) - new_env['OUT'] = cmplog_build_directory - fuzz_target = os.getenv('FUZZ_TARGET') - if fuzz_target: - new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, - os.path.basename(fuzz_target)) - - print('Re-building benchmark for CmpLog fuzzing target') - utils.build_benchmark(env=new_env) - - if 'symcc' in build_modes: - - symcc_build_directory = get_uninstrumented_build_directory( - build_directory) - os.mkdir(symcc_build_directory) - - # symcc requires an build with different instrumentation. - new_env = os.environ.copy() - new_env['CC'] = '/symcc/build/symcc' - new_env['CXX'] = '/symcc/build/sym++' - new_env['SYMCC_OUTPUT_DIR'] = '/tmp' - new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') - new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' - new_env['OUT'] = symcc_build_directory - new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' - new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' - new_env['SYMCC_SILENT'] = '1' - - # For CmpLog build, set the OUT and FUZZ_TARGET environment - # variable to point to the new CmpLog build directory. - new_env['OUT'] = symcc_build_directory - fuzz_target = os.getenv('FUZZ_TARGET') - if fuzz_target: - new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, - os.path.basename(fuzz_target)) - - print('Re-building benchmark for CmpLog fuzzing target') - utils.build_benchmark(env=new_env) - - shutil.copy('/afl/afl-fuzz', build_directory) - if os.path.exists('/afl/afl-qemu-trace'): - shutil.copy('/afl/afl-qemu-trace', build_directory) - if os.path.exists('/aflpp_qemu_driver_hook.so'): - shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) - if os.path.exists('/get_frida_entry.sh'): - shutil.copy('/afl/afl-frida-trace.so', build_directory) - shutil.copy('/get_frida_entry.sh', build_directory) - - -# pylint: disable=too-many-arguments -def fuzz(input_corpus, - output_corpus, - target_binary, - flags=tuple(), - skip=False, - no_cmplog=False): # pylint: disable=too-many-arguments - """Run fuzzer.""" - # Calculate CmpLog binary path from the instrumented target binary. - target_binary_directory = os.path.dirname(target_binary) - cmplog_target_binary_directory = ( - get_cmplog_build_directory(target_binary_directory)) - target_binary_name = os.path.basename(target_binary) - cmplog_target_binary = os.path.join(cmplog_target_binary_directory, - target_binary_name) - - afl_fuzzer.prepare_fuzz_environment(input_corpus) - # decomment this to enable libdislocator. - # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t - # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' - - flags = list(flags) - - if os.path.exists('./afl++.dict'): - flags += ['-x', './afl++.dict'] - - # Move the following to skip for upcoming _double tests: - if os.path.exists(cmplog_target_binary) and no_cmplog is not False: - flags += ['-c', cmplog_target_binary] - - if not skip: - os.environ['AFL_DISABLE_TRIM'] = '1' - # os.environ['AFL_FAST_CAL'] = '1' - os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' - if 'ADDITIONAL_ARGS' in os.environ: - flags += os.environ['ADDITIONAL_ARGS'].split(' ') - - os.environ['AFL_DISABLE_RF'] = '1' - afl_fuzzer.run_afl_fuzz(input_corpus, - output_corpus, - target_binary, - additional_flags=flags) diff --git a/fuzzers/aflpp_random_wrs_rp/runner.Dockerfile b/fuzzers/aflpp_random_wrs_rp/runner.Dockerfile deleted file mode 100644 index 7aa1da8e4..000000000 --- a/fuzzers/aflpp_random_wrs_rp/runner.Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# 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 diff --git a/fuzzers/aflsmart_t0/README.md b/fuzzers/aflsmart_t0/README.md new file mode 100644 index 000000000..df780998f --- /dev/null +++ b/fuzzers/aflsmart_t0/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_t0/builder.Dockerfile b/fuzzers/aflsmart_t0/builder.Dockerfile new file mode 100644 index 000000000..dcb8eb7a9 --- /dev/null +++ b/fuzzers/aflsmart_t0/builder.Dockerfile @@ -0,0 +1,70 @@ +# 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 diff --git a/fuzzers/aflsmart_t0/fuzzer.py b/fuzzers/aflsmart_t0/fuzzer.py new file mode 100755 index 000000000..9f60116a2 --- /dev/null +++ b/fuzzers/aflsmart_t0/fuzzer.py @@ -0,0 +1,79 @@ +# 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.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + # Copy Peach binaries to OUT + shutil.copytree('/afl/peach-3.0.202-source/output/linux_x86_64_debug/bin', + os.environ['OUT'] + '/peach-3.0.202') + + # Copy supported input models + for file in glob.glob('/afl/input_models/*.xml'): + print(file) + shutil.copy(file, os.environ['OUT']) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run afl-fuzz on target.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + os.environ['PATH'] += os.pathsep + '/out/peach-3.0.202/' + + composite_mode = False + input_model = '' + benchmark_name = os.environ['BENCHMARK'] + if benchmark_name == 'libpng-1.6.38': + input_model = 'png.xml' + if benchmark_name == 'libpcap_fuzz_both': + input_model = 'pcap.xml' + if benchmark_name == 'libjpeg-turbo-07-2017': + input_model = 'jpeg.xml' + if benchmark_name == 'freetype2-2017': + input_model = 'xtf.xml' + if benchmark_name == 'vorbis-2017-12-11': + input_model = 'ogg.xml' + if benchmark_name == 'bloaty_fuzz_target': + input_model = 'bloaty_composite.xml' + composite_mode = True + + additional_flags = [ + # Enable stacked mutations + '-h', + # Enable structure-aware fuzzing + '-w', + 'peach', + # Select input model + '-g', + input_model, + ] + + # Enable composite mode for targets + # taking multiple input formats like bloaty + if composite_mode: + additional_flags.append('-c') + + if input_model != '': + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, + additional_flags) + else: + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/aflsmart_t0/runner.Dockerfile b/fuzzers/aflsmart_t0/runner.Dockerfile new file mode 100644 index 000000000..1e9046888 --- /dev/null +++ b/fuzzers/aflsmart_t0/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/aflsmart_t1/README.md b/fuzzers/aflsmart_t1/README.md new file mode 100644 index 000000000..df780998f --- /dev/null +++ b/fuzzers/aflsmart_t1/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_t1/builder.Dockerfile b/fuzzers/aflsmart_t1/builder.Dockerfile new file mode 100644 index 000000000..dcb8eb7a9 --- /dev/null +++ b/fuzzers/aflsmart_t1/builder.Dockerfile @@ -0,0 +1,70 @@ +# 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 diff --git a/fuzzers/aflsmart_t1/fuzzer.py b/fuzzers/aflsmart_t1/fuzzer.py new file mode 100755 index 000000000..9f60116a2 --- /dev/null +++ b/fuzzers/aflsmart_t1/fuzzer.py @@ -0,0 +1,79 @@ +# 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.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + # Copy Peach binaries to OUT + shutil.copytree('/afl/peach-3.0.202-source/output/linux_x86_64_debug/bin', + os.environ['OUT'] + '/peach-3.0.202') + + # Copy supported input models + for file in glob.glob('/afl/input_models/*.xml'): + print(file) + shutil.copy(file, os.environ['OUT']) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run afl-fuzz on target.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + os.environ['PATH'] += os.pathsep + '/out/peach-3.0.202/' + + composite_mode = False + input_model = '' + benchmark_name = os.environ['BENCHMARK'] + if benchmark_name == 'libpng-1.6.38': + input_model = 'png.xml' + if benchmark_name == 'libpcap_fuzz_both': + input_model = 'pcap.xml' + if benchmark_name == 'libjpeg-turbo-07-2017': + input_model = 'jpeg.xml' + if benchmark_name == 'freetype2-2017': + input_model = 'xtf.xml' + if benchmark_name == 'vorbis-2017-12-11': + input_model = 'ogg.xml' + if benchmark_name == 'bloaty_fuzz_target': + input_model = 'bloaty_composite.xml' + composite_mode = True + + additional_flags = [ + # Enable stacked mutations + '-h', + # Enable structure-aware fuzzing + '-w', + 'peach', + # Select input model + '-g', + input_model, + ] + + # Enable composite mode for targets + # taking multiple input formats like bloaty + if composite_mode: + additional_flags.append('-c') + + if input_model != '': + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, + additional_flags) + else: + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/aflsmart_t1/runner.Dockerfile b/fuzzers/aflsmart_t1/runner.Dockerfile new file mode 100644 index 000000000..1e9046888 --- /dev/null +++ b/fuzzers/aflsmart_t1/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/aflsmart_t2/README.md b/fuzzers/aflsmart_t2/README.md new file mode 100644 index 000000000..df780998f --- /dev/null +++ b/fuzzers/aflsmart_t2/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_t2/builder.Dockerfile b/fuzzers/aflsmart_t2/builder.Dockerfile new file mode 100644 index 000000000..dcb8eb7a9 --- /dev/null +++ b/fuzzers/aflsmart_t2/builder.Dockerfile @@ -0,0 +1,70 @@ +# 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 diff --git a/fuzzers/aflsmart_t2/fuzzer.py b/fuzzers/aflsmart_t2/fuzzer.py new file mode 100755 index 000000000..9f60116a2 --- /dev/null +++ b/fuzzers/aflsmart_t2/fuzzer.py @@ -0,0 +1,79 @@ +# 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.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + # Copy Peach binaries to OUT + shutil.copytree('/afl/peach-3.0.202-source/output/linux_x86_64_debug/bin', + os.environ['OUT'] + '/peach-3.0.202') + + # Copy supported input models + for file in glob.glob('/afl/input_models/*.xml'): + print(file) + shutil.copy(file, os.environ['OUT']) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run afl-fuzz on target.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + os.environ['PATH'] += os.pathsep + '/out/peach-3.0.202/' + + composite_mode = False + input_model = '' + benchmark_name = os.environ['BENCHMARK'] + if benchmark_name == 'libpng-1.6.38': + input_model = 'png.xml' + if benchmark_name == 'libpcap_fuzz_both': + input_model = 'pcap.xml' + if benchmark_name == 'libjpeg-turbo-07-2017': + input_model = 'jpeg.xml' + if benchmark_name == 'freetype2-2017': + input_model = 'xtf.xml' + if benchmark_name == 'vorbis-2017-12-11': + input_model = 'ogg.xml' + if benchmark_name == 'bloaty_fuzz_target': + input_model = 'bloaty_composite.xml' + composite_mode = True + + additional_flags = [ + # Enable stacked mutations + '-h', + # Enable structure-aware fuzzing + '-w', + 'peach', + # Select input model + '-g', + input_model, + ] + + # Enable composite mode for targets + # taking multiple input formats like bloaty + if composite_mode: + additional_flags.append('-c') + + if input_model != '': + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, + additional_flags) + else: + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/aflsmart_t2/runner.Dockerfile b/fuzzers/aflsmart_t2/runner.Dockerfile new file mode 100644 index 000000000..1e9046888 --- /dev/null +++ b/fuzzers/aflsmart_t2/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/aflsmart_t3/README.md b/fuzzers/aflsmart_t3/README.md new file mode 100644 index 000000000..df780998f --- /dev/null +++ b/fuzzers/aflsmart_t3/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_t3/builder.Dockerfile b/fuzzers/aflsmart_t3/builder.Dockerfile new file mode 100644 index 000000000..dcb8eb7a9 --- /dev/null +++ b/fuzzers/aflsmart_t3/builder.Dockerfile @@ -0,0 +1,70 @@ +# 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 diff --git a/fuzzers/aflsmart_t3/fuzzer.py b/fuzzers/aflsmart_t3/fuzzer.py new file mode 100755 index 000000000..9f60116a2 --- /dev/null +++ b/fuzzers/aflsmart_t3/fuzzer.py @@ -0,0 +1,79 @@ +# 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.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + # Copy Peach binaries to OUT + shutil.copytree('/afl/peach-3.0.202-source/output/linux_x86_64_debug/bin', + os.environ['OUT'] + '/peach-3.0.202') + + # Copy supported input models + for file in glob.glob('/afl/input_models/*.xml'): + print(file) + shutil.copy(file, os.environ['OUT']) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run afl-fuzz on target.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + os.environ['PATH'] += os.pathsep + '/out/peach-3.0.202/' + + composite_mode = False + input_model = '' + benchmark_name = os.environ['BENCHMARK'] + if benchmark_name == 'libpng-1.6.38': + input_model = 'png.xml' + if benchmark_name == 'libpcap_fuzz_both': + input_model = 'pcap.xml' + if benchmark_name == 'libjpeg-turbo-07-2017': + input_model = 'jpeg.xml' + if benchmark_name == 'freetype2-2017': + input_model = 'xtf.xml' + if benchmark_name == 'vorbis-2017-12-11': + input_model = 'ogg.xml' + if benchmark_name == 'bloaty_fuzz_target': + input_model = 'bloaty_composite.xml' + composite_mode = True + + additional_flags = [ + # Enable stacked mutations + '-h', + # Enable structure-aware fuzzing + '-w', + 'peach', + # Select input model + '-g', + input_model, + ] + + # Enable composite mode for targets + # taking multiple input formats like bloaty + if composite_mode: + additional_flags.append('-c') + + if input_model != '': + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, + additional_flags) + else: + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/aflsmart_t3/runner.Dockerfile b/fuzzers/aflsmart_t3/runner.Dockerfile new file mode 100644 index 000000000..1e9046888 --- /dev/null +++ b/fuzzers/aflsmart_t3/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/aflsmart_t4/README.md b/fuzzers/aflsmart_t4/README.md new file mode 100644 index 000000000..df780998f --- /dev/null +++ b/fuzzers/aflsmart_t4/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_t4/builder.Dockerfile b/fuzzers/aflsmart_t4/builder.Dockerfile new file mode 100644 index 000000000..dcb8eb7a9 --- /dev/null +++ b/fuzzers/aflsmart_t4/builder.Dockerfile @@ -0,0 +1,70 @@ +# 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 diff --git a/fuzzers/aflsmart_t4/fuzzer.py b/fuzzers/aflsmart_t4/fuzzer.py new file mode 100755 index 000000000..9f60116a2 --- /dev/null +++ b/fuzzers/aflsmart_t4/fuzzer.py @@ -0,0 +1,79 @@ +# 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.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + # Copy Peach binaries to OUT + shutil.copytree('/afl/peach-3.0.202-source/output/linux_x86_64_debug/bin', + os.environ['OUT'] + '/peach-3.0.202') + + # Copy supported input models + for file in glob.glob('/afl/input_models/*.xml'): + print(file) + shutil.copy(file, os.environ['OUT']) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run afl-fuzz on target.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + os.environ['PATH'] += os.pathsep + '/out/peach-3.0.202/' + + composite_mode = False + input_model = '' + benchmark_name = os.environ['BENCHMARK'] + if benchmark_name == 'libpng-1.6.38': + input_model = 'png.xml' + if benchmark_name == 'libpcap_fuzz_both': + input_model = 'pcap.xml' + if benchmark_name == 'libjpeg-turbo-07-2017': + input_model = 'jpeg.xml' + if benchmark_name == 'freetype2-2017': + input_model = 'xtf.xml' + if benchmark_name == 'vorbis-2017-12-11': + input_model = 'ogg.xml' + if benchmark_name == 'bloaty_fuzz_target': + input_model = 'bloaty_composite.xml' + composite_mode = True + + additional_flags = [ + # Enable stacked mutations + '-h', + # Enable structure-aware fuzzing + '-w', + 'peach', + # Select input model + '-g', + input_model, + ] + + # Enable composite mode for targets + # taking multiple input formats like bloaty + if composite_mode: + additional_flags.append('-c') + + if input_model != '': + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, + additional_flags) + else: + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/aflsmart_t4/runner.Dockerfile b/fuzzers/aflsmart_t4/runner.Dockerfile new file mode 100644 index 000000000..1e9046888 --- /dev/null +++ b/fuzzers/aflsmart_t4/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/eclipser_t0/builder.Dockerfile b/fuzzers/eclipser_t0/builder.Dockerfile new file mode 100644 index 000000000..572706c52 --- /dev/null +++ b/fuzzers/eclipser_t0/builder.Dockerfile @@ -0,0 +1,39 @@ +# 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 + +# Upgrade to avoid certs errors +RUN apt-get update && apt-get upgrade -y && \ + apt-get install -y apt-utils apt-transport-https ca-certificates + +# Download and compile AFL v2.56b, since Eclipser now adopts AFL as its random +# fuzzing module. Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/google/AFL.git /afl && \ + cd /afl && \ + git checkout 82b5e359463238d790cadbe2dd494d6a4928bff3 && \ + AFL_NO_X86=1 make + +# Use afl_driver.cpp for AFL, and StandaloneFuzzTargetMain.c for Eclipser. +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/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 && \ + wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c -O /StandaloneFuzzTargetMain.c && \ + clang -O2 -c /StandaloneFuzzTargetMain.c && \ + ar rc /libStandaloneFuzzTarget.a StandaloneFuzzTargetMain.o && \ + rm /StandaloneFuzzTargetMain.c diff --git a/fuzzers/eclipser_t0/fuzzer.py b/fuzzers/eclipser_t0/fuzzer.py new file mode 100644 index 000000000..19e69f6fa --- /dev/null +++ b/fuzzers/eclipser_t0/fuzzer.py @@ -0,0 +1,132 @@ +# 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 Eclipser fuzzer. Note that starting from v2.0, Eclipser +relies on AFL to perform random-based fuzzing.""" + +import shutil +import subprocess +import os +import threading + +from fuzzers import utils +from fuzzers.afl import fuzzer as afl_fuzzer + + +def get_uninstrumented_outdir(target_directory): + """Return path to uninstrumented target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(): + """Build benchmark.""" + + # Backup the environment. + new_env = os.environ.copy() + + # First, build an instrumented binary for AFL. + afl_fuzzer.prepare_build_environment() + src = os.getenv('SRC') + work = os.getenv('WORK') + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + print('[build] Copying afl-fuzz to $OUT directory') + shutil.copy('/afl/afl-fuzz', os.environ['OUT']) + + # Next, build an uninstrumented binary for Eclipser. + new_env['CC'] = 'clang' + new_env['CXX'] = 'clang++' + new_env['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + # Ensure to compile with NO_SANITIZER_COMPAT* flags even for bug benchmarks, + # as QEMU is incompatible with sanitizers. Also, Eclipser prefers clean and + # unoptimized binaries. We leave fast random fuzzing as AFL's job. + new_env['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + new_env['CXXFLAGS'] = ' '.join(cxxflags) + uninstrumented_outdir = get_uninstrumented_outdir(os.environ['OUT']) + os.mkdir(uninstrumented_outdir) + new_env['OUT'] = uninstrumented_outdir + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + targ_name = os.path.basename(fuzz_target) + new_env['FUZZ_TARGET'] = os.path.join(uninstrumented_outdir, targ_name) + print('[build] Re-building benchmark for uninstrumented fuzzing target') + utils.build_benchmark(env=new_env) + + +def eclipser(input_corpus, output_corpus, target_binary): + """Run Eclipser.""" + # We will use output_corpus as a directory where AFL and Eclipser sync their + # test cases with each other. For Eclipser, we should explicitly specify an + # output directory under this sync directory. + eclipser_out = os.path.join(output_corpus, 'eclipser_output') + command = [ + 'dotnet', + '/Eclipser/build/Eclipser.dll', + '-p', + target_binary, + '-s', + output_corpus, + '-o', + eclipser_out, + '--arg', # Specifies the command-line of the program. + 'foo', + '-f', # Specifies the path of file input to fuzz. + 'foo', + '-v', # Controls the verbosity. + '2', + '--exectimeout', + '5000', + ] + if os.listdir(input_corpus): # Specify inputs only if any seed exists. + command += ['-i', input_corpus] + print('[eclipser] Run Eclipser with command: ' + ' '.join(command)) + with subprocess.Popen(command): + pass + + +def afl_worker(input_corpus, output_corpus, target_binary): + """Run AFL worker instance.""" + print('[afl_worker] Run AFL worker') + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, + ['-S', 'afl-worker'], True) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + + # Calculate uninstrumented binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + uninstrumented_target_binary_directory = ( + get_uninstrumented_outdir(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + uninstrumented_target_binary = os.path.join( + uninstrumented_target_binary_directory, target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + afl_args = (input_corpus, output_corpus, target_binary) + eclipser_args = (input_corpus, output_corpus, uninstrumented_target_binary) + # Do not launch AFL master instance for now, to reduce memory usage and + # align with the vanilla AFL. + print('[fuzz] Running AFL worker') + afl_worker_thread = threading.Thread(target=afl_worker, args=afl_args) + afl_worker_thread.start() + print('[fuzz] Running Eclipser') + eclipser_thread = threading.Thread(target=eclipser, args=eclipser_args) + eclipser_thread.start() + print('[fuzz] Now waiting for threads to finish...') + afl_worker_thread.join() + eclipser_thread.join() diff --git a/fuzzers/eclipser_t0/runner.Dockerfile b/fuzzers/eclipser_t0/runner.Dockerfile new file mode 100644 index 000000000..dce0e0ac9 --- /dev/null +++ b/fuzzers/eclipser_t0/runner.Dockerfile @@ -0,0 +1,48 @@ +# 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 + +# Install dotnet, qemu and other Eclipser deps. +RUN sed -i -- 's/# deb-src/deb-src/g' /etc/apt/sources.list +RUN apt-get update -y && \ + apt-get build-dep -y qemu && \ + apt-get install -y \ + apt-transport-https \ + libtool \ + libtool-bin \ + wget \ + automake \ + autoconf \ + bison \ + git \ + gdb \ + python2 + +# Use a copy of +# https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb +# to avoid network flakiness. +RUN wget -q https://storage.googleapis.com/fuzzbench-files/packages-microsoft-prod.deb -O packages-microsoft-prod.deb && \ + dpkg -i packages-microsoft-prod.deb && \ + apt-get update -y && \ + apt-get install -y dotnet-sdk-2.1 dotnet-runtime-2.1 && \ + rm packages-microsoft-prod.deb + +# Build Eclipser. +RUN git clone https://github.com/SoftSec-KAIST/Eclipser.git /Eclipser && \ + cd /Eclipser && \ + git checkout ba1d7a55c168f7c19ecceb788a81ea07c2625e45 && \ + ln -sf /usr/bin/python2.7 /usr/local/bin/python && \ + make -j && \ + ln -sf /usr/local/bin/python3.10 /usr/local/bin/python diff --git a/fuzzers/eclipser_t1/builder.Dockerfile b/fuzzers/eclipser_t1/builder.Dockerfile new file mode 100644 index 000000000..572706c52 --- /dev/null +++ b/fuzzers/eclipser_t1/builder.Dockerfile @@ -0,0 +1,39 @@ +# 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 + +# Upgrade to avoid certs errors +RUN apt-get update && apt-get upgrade -y && \ + apt-get install -y apt-utils apt-transport-https ca-certificates + +# Download and compile AFL v2.56b, since Eclipser now adopts AFL as its random +# fuzzing module. Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/google/AFL.git /afl && \ + cd /afl && \ + git checkout 82b5e359463238d790cadbe2dd494d6a4928bff3 && \ + AFL_NO_X86=1 make + +# Use afl_driver.cpp for AFL, and StandaloneFuzzTargetMain.c for Eclipser. +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/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 && \ + wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c -O /StandaloneFuzzTargetMain.c && \ + clang -O2 -c /StandaloneFuzzTargetMain.c && \ + ar rc /libStandaloneFuzzTarget.a StandaloneFuzzTargetMain.o && \ + rm /StandaloneFuzzTargetMain.c diff --git a/fuzzers/eclipser_t1/fuzzer.py b/fuzzers/eclipser_t1/fuzzer.py new file mode 100644 index 000000000..19e69f6fa --- /dev/null +++ b/fuzzers/eclipser_t1/fuzzer.py @@ -0,0 +1,132 @@ +# 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 Eclipser fuzzer. Note that starting from v2.0, Eclipser +relies on AFL to perform random-based fuzzing.""" + +import shutil +import subprocess +import os +import threading + +from fuzzers import utils +from fuzzers.afl import fuzzer as afl_fuzzer + + +def get_uninstrumented_outdir(target_directory): + """Return path to uninstrumented target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(): + """Build benchmark.""" + + # Backup the environment. + new_env = os.environ.copy() + + # First, build an instrumented binary for AFL. + afl_fuzzer.prepare_build_environment() + src = os.getenv('SRC') + work = os.getenv('WORK') + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + print('[build] Copying afl-fuzz to $OUT directory') + shutil.copy('/afl/afl-fuzz', os.environ['OUT']) + + # Next, build an uninstrumented binary for Eclipser. + new_env['CC'] = 'clang' + new_env['CXX'] = 'clang++' + new_env['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + # Ensure to compile with NO_SANITIZER_COMPAT* flags even for bug benchmarks, + # as QEMU is incompatible with sanitizers. Also, Eclipser prefers clean and + # unoptimized binaries. We leave fast random fuzzing as AFL's job. + new_env['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + new_env['CXXFLAGS'] = ' '.join(cxxflags) + uninstrumented_outdir = get_uninstrumented_outdir(os.environ['OUT']) + os.mkdir(uninstrumented_outdir) + new_env['OUT'] = uninstrumented_outdir + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + targ_name = os.path.basename(fuzz_target) + new_env['FUZZ_TARGET'] = os.path.join(uninstrumented_outdir, targ_name) + print('[build] Re-building benchmark for uninstrumented fuzzing target') + utils.build_benchmark(env=new_env) + + +def eclipser(input_corpus, output_corpus, target_binary): + """Run Eclipser.""" + # We will use output_corpus as a directory where AFL and Eclipser sync their + # test cases with each other. For Eclipser, we should explicitly specify an + # output directory under this sync directory. + eclipser_out = os.path.join(output_corpus, 'eclipser_output') + command = [ + 'dotnet', + '/Eclipser/build/Eclipser.dll', + '-p', + target_binary, + '-s', + output_corpus, + '-o', + eclipser_out, + '--arg', # Specifies the command-line of the program. + 'foo', + '-f', # Specifies the path of file input to fuzz. + 'foo', + '-v', # Controls the verbosity. + '2', + '--exectimeout', + '5000', + ] + if os.listdir(input_corpus): # Specify inputs only if any seed exists. + command += ['-i', input_corpus] + print('[eclipser] Run Eclipser with command: ' + ' '.join(command)) + with subprocess.Popen(command): + pass + + +def afl_worker(input_corpus, output_corpus, target_binary): + """Run AFL worker instance.""" + print('[afl_worker] Run AFL worker') + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, + ['-S', 'afl-worker'], True) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + + # Calculate uninstrumented binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + uninstrumented_target_binary_directory = ( + get_uninstrumented_outdir(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + uninstrumented_target_binary = os.path.join( + uninstrumented_target_binary_directory, target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + afl_args = (input_corpus, output_corpus, target_binary) + eclipser_args = (input_corpus, output_corpus, uninstrumented_target_binary) + # Do not launch AFL master instance for now, to reduce memory usage and + # align with the vanilla AFL. + print('[fuzz] Running AFL worker') + afl_worker_thread = threading.Thread(target=afl_worker, args=afl_args) + afl_worker_thread.start() + print('[fuzz] Running Eclipser') + eclipser_thread = threading.Thread(target=eclipser, args=eclipser_args) + eclipser_thread.start() + print('[fuzz] Now waiting for threads to finish...') + afl_worker_thread.join() + eclipser_thread.join() diff --git a/fuzzers/eclipser_t1/runner.Dockerfile b/fuzzers/eclipser_t1/runner.Dockerfile new file mode 100644 index 000000000..dce0e0ac9 --- /dev/null +++ b/fuzzers/eclipser_t1/runner.Dockerfile @@ -0,0 +1,48 @@ +# 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 + +# Install dotnet, qemu and other Eclipser deps. +RUN sed -i -- 's/# deb-src/deb-src/g' /etc/apt/sources.list +RUN apt-get update -y && \ + apt-get build-dep -y qemu && \ + apt-get install -y \ + apt-transport-https \ + libtool \ + libtool-bin \ + wget \ + automake \ + autoconf \ + bison \ + git \ + gdb \ + python2 + +# Use a copy of +# https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb +# to avoid network flakiness. +RUN wget -q https://storage.googleapis.com/fuzzbench-files/packages-microsoft-prod.deb -O packages-microsoft-prod.deb && \ + dpkg -i packages-microsoft-prod.deb && \ + apt-get update -y && \ + apt-get install -y dotnet-sdk-2.1 dotnet-runtime-2.1 && \ + rm packages-microsoft-prod.deb + +# Build Eclipser. +RUN git clone https://github.com/SoftSec-KAIST/Eclipser.git /Eclipser && \ + cd /Eclipser && \ + git checkout ba1d7a55c168f7c19ecceb788a81ea07c2625e45 && \ + ln -sf /usr/bin/python2.7 /usr/local/bin/python && \ + make -j && \ + ln -sf /usr/local/bin/python3.10 /usr/local/bin/python diff --git a/fuzzers/eclipser_t2/builder.Dockerfile b/fuzzers/eclipser_t2/builder.Dockerfile new file mode 100644 index 000000000..572706c52 --- /dev/null +++ b/fuzzers/eclipser_t2/builder.Dockerfile @@ -0,0 +1,39 @@ +# 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 + +# Upgrade to avoid certs errors +RUN apt-get update && apt-get upgrade -y && \ + apt-get install -y apt-utils apt-transport-https ca-certificates + +# Download and compile AFL v2.56b, since Eclipser now adopts AFL as its random +# fuzzing module. Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/google/AFL.git /afl && \ + cd /afl && \ + git checkout 82b5e359463238d790cadbe2dd494d6a4928bff3 && \ + AFL_NO_X86=1 make + +# Use afl_driver.cpp for AFL, and StandaloneFuzzTargetMain.c for Eclipser. +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/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 && \ + wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c -O /StandaloneFuzzTargetMain.c && \ + clang -O2 -c /StandaloneFuzzTargetMain.c && \ + ar rc /libStandaloneFuzzTarget.a StandaloneFuzzTargetMain.o && \ + rm /StandaloneFuzzTargetMain.c diff --git a/fuzzers/eclipser_t2/fuzzer.py b/fuzzers/eclipser_t2/fuzzer.py new file mode 100644 index 000000000..19e69f6fa --- /dev/null +++ b/fuzzers/eclipser_t2/fuzzer.py @@ -0,0 +1,132 @@ +# 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 Eclipser fuzzer. Note that starting from v2.0, Eclipser +relies on AFL to perform random-based fuzzing.""" + +import shutil +import subprocess +import os +import threading + +from fuzzers import utils +from fuzzers.afl import fuzzer as afl_fuzzer + + +def get_uninstrumented_outdir(target_directory): + """Return path to uninstrumented target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(): + """Build benchmark.""" + + # Backup the environment. + new_env = os.environ.copy() + + # First, build an instrumented binary for AFL. + afl_fuzzer.prepare_build_environment() + src = os.getenv('SRC') + work = os.getenv('WORK') + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + print('[build] Copying afl-fuzz to $OUT directory') + shutil.copy('/afl/afl-fuzz', os.environ['OUT']) + + # Next, build an uninstrumented binary for Eclipser. + new_env['CC'] = 'clang' + new_env['CXX'] = 'clang++' + new_env['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + # Ensure to compile with NO_SANITIZER_COMPAT* flags even for bug benchmarks, + # as QEMU is incompatible with sanitizers. Also, Eclipser prefers clean and + # unoptimized binaries. We leave fast random fuzzing as AFL's job. + new_env['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + new_env['CXXFLAGS'] = ' '.join(cxxflags) + uninstrumented_outdir = get_uninstrumented_outdir(os.environ['OUT']) + os.mkdir(uninstrumented_outdir) + new_env['OUT'] = uninstrumented_outdir + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + targ_name = os.path.basename(fuzz_target) + new_env['FUZZ_TARGET'] = os.path.join(uninstrumented_outdir, targ_name) + print('[build] Re-building benchmark for uninstrumented fuzzing target') + utils.build_benchmark(env=new_env) + + +def eclipser(input_corpus, output_corpus, target_binary): + """Run Eclipser.""" + # We will use output_corpus as a directory where AFL and Eclipser sync their + # test cases with each other. For Eclipser, we should explicitly specify an + # output directory under this sync directory. + eclipser_out = os.path.join(output_corpus, 'eclipser_output') + command = [ + 'dotnet', + '/Eclipser/build/Eclipser.dll', + '-p', + target_binary, + '-s', + output_corpus, + '-o', + eclipser_out, + '--arg', # Specifies the command-line of the program. + 'foo', + '-f', # Specifies the path of file input to fuzz. + 'foo', + '-v', # Controls the verbosity. + '2', + '--exectimeout', + '5000', + ] + if os.listdir(input_corpus): # Specify inputs only if any seed exists. + command += ['-i', input_corpus] + print('[eclipser] Run Eclipser with command: ' + ' '.join(command)) + with subprocess.Popen(command): + pass + + +def afl_worker(input_corpus, output_corpus, target_binary): + """Run AFL worker instance.""" + print('[afl_worker] Run AFL worker') + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, + ['-S', 'afl-worker'], True) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + + # Calculate uninstrumented binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + uninstrumented_target_binary_directory = ( + get_uninstrumented_outdir(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + uninstrumented_target_binary = os.path.join( + uninstrumented_target_binary_directory, target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + afl_args = (input_corpus, output_corpus, target_binary) + eclipser_args = (input_corpus, output_corpus, uninstrumented_target_binary) + # Do not launch AFL master instance for now, to reduce memory usage and + # align with the vanilla AFL. + print('[fuzz] Running AFL worker') + afl_worker_thread = threading.Thread(target=afl_worker, args=afl_args) + afl_worker_thread.start() + print('[fuzz] Running Eclipser') + eclipser_thread = threading.Thread(target=eclipser, args=eclipser_args) + eclipser_thread.start() + print('[fuzz] Now waiting for threads to finish...') + afl_worker_thread.join() + eclipser_thread.join() diff --git a/fuzzers/eclipser_t2/runner.Dockerfile b/fuzzers/eclipser_t2/runner.Dockerfile new file mode 100644 index 000000000..dce0e0ac9 --- /dev/null +++ b/fuzzers/eclipser_t2/runner.Dockerfile @@ -0,0 +1,48 @@ +# 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 + +# Install dotnet, qemu and other Eclipser deps. +RUN sed -i -- 's/# deb-src/deb-src/g' /etc/apt/sources.list +RUN apt-get update -y && \ + apt-get build-dep -y qemu && \ + apt-get install -y \ + apt-transport-https \ + libtool \ + libtool-bin \ + wget \ + automake \ + autoconf \ + bison \ + git \ + gdb \ + python2 + +# Use a copy of +# https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb +# to avoid network flakiness. +RUN wget -q https://storage.googleapis.com/fuzzbench-files/packages-microsoft-prod.deb -O packages-microsoft-prod.deb && \ + dpkg -i packages-microsoft-prod.deb && \ + apt-get update -y && \ + apt-get install -y dotnet-sdk-2.1 dotnet-runtime-2.1 && \ + rm packages-microsoft-prod.deb + +# Build Eclipser. +RUN git clone https://github.com/SoftSec-KAIST/Eclipser.git /Eclipser && \ + cd /Eclipser && \ + git checkout ba1d7a55c168f7c19ecceb788a81ea07c2625e45 && \ + ln -sf /usr/bin/python2.7 /usr/local/bin/python && \ + make -j && \ + ln -sf /usr/local/bin/python3.10 /usr/local/bin/python diff --git a/fuzzers/eclipser_t3/builder.Dockerfile b/fuzzers/eclipser_t3/builder.Dockerfile new file mode 100644 index 000000000..572706c52 --- /dev/null +++ b/fuzzers/eclipser_t3/builder.Dockerfile @@ -0,0 +1,39 @@ +# 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 + +# Upgrade to avoid certs errors +RUN apt-get update && apt-get upgrade -y && \ + apt-get install -y apt-utils apt-transport-https ca-certificates + +# Download and compile AFL v2.56b, since Eclipser now adopts AFL as its random +# fuzzing module. Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/google/AFL.git /afl && \ + cd /afl && \ + git checkout 82b5e359463238d790cadbe2dd494d6a4928bff3 && \ + AFL_NO_X86=1 make + +# Use afl_driver.cpp for AFL, and StandaloneFuzzTargetMain.c for Eclipser. +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/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 && \ + wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c -O /StandaloneFuzzTargetMain.c && \ + clang -O2 -c /StandaloneFuzzTargetMain.c && \ + ar rc /libStandaloneFuzzTarget.a StandaloneFuzzTargetMain.o && \ + rm /StandaloneFuzzTargetMain.c diff --git a/fuzzers/eclipser_t3/fuzzer.py b/fuzzers/eclipser_t3/fuzzer.py new file mode 100644 index 000000000..19e69f6fa --- /dev/null +++ b/fuzzers/eclipser_t3/fuzzer.py @@ -0,0 +1,132 @@ +# 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 Eclipser fuzzer. Note that starting from v2.0, Eclipser +relies on AFL to perform random-based fuzzing.""" + +import shutil +import subprocess +import os +import threading + +from fuzzers import utils +from fuzzers.afl import fuzzer as afl_fuzzer + + +def get_uninstrumented_outdir(target_directory): + """Return path to uninstrumented target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(): + """Build benchmark.""" + + # Backup the environment. + new_env = os.environ.copy() + + # First, build an instrumented binary for AFL. + afl_fuzzer.prepare_build_environment() + src = os.getenv('SRC') + work = os.getenv('WORK') + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + print('[build] Copying afl-fuzz to $OUT directory') + shutil.copy('/afl/afl-fuzz', os.environ['OUT']) + + # Next, build an uninstrumented binary for Eclipser. + new_env['CC'] = 'clang' + new_env['CXX'] = 'clang++' + new_env['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + # Ensure to compile with NO_SANITIZER_COMPAT* flags even for bug benchmarks, + # as QEMU is incompatible with sanitizers. Also, Eclipser prefers clean and + # unoptimized binaries. We leave fast random fuzzing as AFL's job. + new_env['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + new_env['CXXFLAGS'] = ' '.join(cxxflags) + uninstrumented_outdir = get_uninstrumented_outdir(os.environ['OUT']) + os.mkdir(uninstrumented_outdir) + new_env['OUT'] = uninstrumented_outdir + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + targ_name = os.path.basename(fuzz_target) + new_env['FUZZ_TARGET'] = os.path.join(uninstrumented_outdir, targ_name) + print('[build] Re-building benchmark for uninstrumented fuzzing target') + utils.build_benchmark(env=new_env) + + +def eclipser(input_corpus, output_corpus, target_binary): + """Run Eclipser.""" + # We will use output_corpus as a directory where AFL and Eclipser sync their + # test cases with each other. For Eclipser, we should explicitly specify an + # output directory under this sync directory. + eclipser_out = os.path.join(output_corpus, 'eclipser_output') + command = [ + 'dotnet', + '/Eclipser/build/Eclipser.dll', + '-p', + target_binary, + '-s', + output_corpus, + '-o', + eclipser_out, + '--arg', # Specifies the command-line of the program. + 'foo', + '-f', # Specifies the path of file input to fuzz. + 'foo', + '-v', # Controls the verbosity. + '2', + '--exectimeout', + '5000', + ] + if os.listdir(input_corpus): # Specify inputs only if any seed exists. + command += ['-i', input_corpus] + print('[eclipser] Run Eclipser with command: ' + ' '.join(command)) + with subprocess.Popen(command): + pass + + +def afl_worker(input_corpus, output_corpus, target_binary): + """Run AFL worker instance.""" + print('[afl_worker] Run AFL worker') + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, + ['-S', 'afl-worker'], True) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + + # Calculate uninstrumented binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + uninstrumented_target_binary_directory = ( + get_uninstrumented_outdir(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + uninstrumented_target_binary = os.path.join( + uninstrumented_target_binary_directory, target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + afl_args = (input_corpus, output_corpus, target_binary) + eclipser_args = (input_corpus, output_corpus, uninstrumented_target_binary) + # Do not launch AFL master instance for now, to reduce memory usage and + # align with the vanilla AFL. + print('[fuzz] Running AFL worker') + afl_worker_thread = threading.Thread(target=afl_worker, args=afl_args) + afl_worker_thread.start() + print('[fuzz] Running Eclipser') + eclipser_thread = threading.Thread(target=eclipser, args=eclipser_args) + eclipser_thread.start() + print('[fuzz] Now waiting for threads to finish...') + afl_worker_thread.join() + eclipser_thread.join() diff --git a/fuzzers/eclipser_t3/runner.Dockerfile b/fuzzers/eclipser_t3/runner.Dockerfile new file mode 100644 index 000000000..dce0e0ac9 --- /dev/null +++ b/fuzzers/eclipser_t3/runner.Dockerfile @@ -0,0 +1,48 @@ +# 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 + +# Install dotnet, qemu and other Eclipser deps. +RUN sed -i -- 's/# deb-src/deb-src/g' /etc/apt/sources.list +RUN apt-get update -y && \ + apt-get build-dep -y qemu && \ + apt-get install -y \ + apt-transport-https \ + libtool \ + libtool-bin \ + wget \ + automake \ + autoconf \ + bison \ + git \ + gdb \ + python2 + +# Use a copy of +# https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb +# to avoid network flakiness. +RUN wget -q https://storage.googleapis.com/fuzzbench-files/packages-microsoft-prod.deb -O packages-microsoft-prod.deb && \ + dpkg -i packages-microsoft-prod.deb && \ + apt-get update -y && \ + apt-get install -y dotnet-sdk-2.1 dotnet-runtime-2.1 && \ + rm packages-microsoft-prod.deb + +# Build Eclipser. +RUN git clone https://github.com/SoftSec-KAIST/Eclipser.git /Eclipser && \ + cd /Eclipser && \ + git checkout ba1d7a55c168f7c19ecceb788a81ea07c2625e45 && \ + ln -sf /usr/bin/python2.7 /usr/local/bin/python && \ + make -j && \ + ln -sf /usr/local/bin/python3.10 /usr/local/bin/python diff --git a/fuzzers/eclipser_t4/builder.Dockerfile b/fuzzers/eclipser_t4/builder.Dockerfile new file mode 100644 index 000000000..572706c52 --- /dev/null +++ b/fuzzers/eclipser_t4/builder.Dockerfile @@ -0,0 +1,39 @@ +# 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 + +# Upgrade to avoid certs errors +RUN apt-get update && apt-get upgrade -y && \ + apt-get install -y apt-utils apt-transport-https ca-certificates + +# Download and compile AFL v2.56b, since Eclipser now adopts AFL as its random +# fuzzing module. Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/google/AFL.git /afl && \ + cd /afl && \ + git checkout 82b5e359463238d790cadbe2dd494d6a4928bff3 && \ + AFL_NO_X86=1 make + +# Use afl_driver.cpp for AFL, and StandaloneFuzzTargetMain.c for Eclipser. +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/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 && \ + wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c -O /StandaloneFuzzTargetMain.c && \ + clang -O2 -c /StandaloneFuzzTargetMain.c && \ + ar rc /libStandaloneFuzzTarget.a StandaloneFuzzTargetMain.o && \ + rm /StandaloneFuzzTargetMain.c diff --git a/fuzzers/eclipser_t4/fuzzer.py b/fuzzers/eclipser_t4/fuzzer.py new file mode 100644 index 000000000..19e69f6fa --- /dev/null +++ b/fuzzers/eclipser_t4/fuzzer.py @@ -0,0 +1,132 @@ +# 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 Eclipser fuzzer. Note that starting from v2.0, Eclipser +relies on AFL to perform random-based fuzzing.""" + +import shutil +import subprocess +import os +import threading + +from fuzzers import utils +from fuzzers.afl import fuzzer as afl_fuzzer + + +def get_uninstrumented_outdir(target_directory): + """Return path to uninstrumented target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(): + """Build benchmark.""" + + # Backup the environment. + new_env = os.environ.copy() + + # First, build an instrumented binary for AFL. + afl_fuzzer.prepare_build_environment() + src = os.getenv('SRC') + work = os.getenv('WORK') + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + print('[build] Copying afl-fuzz to $OUT directory') + shutil.copy('/afl/afl-fuzz', os.environ['OUT']) + + # Next, build an uninstrumented binary for Eclipser. + new_env['CC'] = 'clang' + new_env['CXX'] = 'clang++' + new_env['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + # Ensure to compile with NO_SANITIZER_COMPAT* flags even for bug benchmarks, + # as QEMU is incompatible with sanitizers. Also, Eclipser prefers clean and + # unoptimized binaries. We leave fast random fuzzing as AFL's job. + new_env['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + new_env['CXXFLAGS'] = ' '.join(cxxflags) + uninstrumented_outdir = get_uninstrumented_outdir(os.environ['OUT']) + os.mkdir(uninstrumented_outdir) + new_env['OUT'] = uninstrumented_outdir + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + targ_name = os.path.basename(fuzz_target) + new_env['FUZZ_TARGET'] = os.path.join(uninstrumented_outdir, targ_name) + print('[build] Re-building benchmark for uninstrumented fuzzing target') + utils.build_benchmark(env=new_env) + + +def eclipser(input_corpus, output_corpus, target_binary): + """Run Eclipser.""" + # We will use output_corpus as a directory where AFL and Eclipser sync their + # test cases with each other. For Eclipser, we should explicitly specify an + # output directory under this sync directory. + eclipser_out = os.path.join(output_corpus, 'eclipser_output') + command = [ + 'dotnet', + '/Eclipser/build/Eclipser.dll', + '-p', + target_binary, + '-s', + output_corpus, + '-o', + eclipser_out, + '--arg', # Specifies the command-line of the program. + 'foo', + '-f', # Specifies the path of file input to fuzz. + 'foo', + '-v', # Controls the verbosity. + '2', + '--exectimeout', + '5000', + ] + if os.listdir(input_corpus): # Specify inputs only if any seed exists. + command += ['-i', input_corpus] + print('[eclipser] Run Eclipser with command: ' + ' '.join(command)) + with subprocess.Popen(command): + pass + + +def afl_worker(input_corpus, output_corpus, target_binary): + """Run AFL worker instance.""" + print('[afl_worker] Run AFL worker') + afl_fuzzer.run_afl_fuzz(input_corpus, output_corpus, target_binary, + ['-S', 'afl-worker'], True) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + + # Calculate uninstrumented binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + uninstrumented_target_binary_directory = ( + get_uninstrumented_outdir(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + uninstrumented_target_binary = os.path.join( + uninstrumented_target_binary_directory, target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + afl_args = (input_corpus, output_corpus, target_binary) + eclipser_args = (input_corpus, output_corpus, uninstrumented_target_binary) + # Do not launch AFL master instance for now, to reduce memory usage and + # align with the vanilla AFL. + print('[fuzz] Running AFL worker') + afl_worker_thread = threading.Thread(target=afl_worker, args=afl_args) + afl_worker_thread.start() + print('[fuzz] Running Eclipser') + eclipser_thread = threading.Thread(target=eclipser, args=eclipser_args) + eclipser_thread.start() + print('[fuzz] Now waiting for threads to finish...') + afl_worker_thread.join() + eclipser_thread.join() diff --git a/fuzzers/eclipser_t4/runner.Dockerfile b/fuzzers/eclipser_t4/runner.Dockerfile new file mode 100644 index 000000000..dce0e0ac9 --- /dev/null +++ b/fuzzers/eclipser_t4/runner.Dockerfile @@ -0,0 +1,48 @@ +# 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 + +# Install dotnet, qemu and other Eclipser deps. +RUN sed -i -- 's/# deb-src/deb-src/g' /etc/apt/sources.list +RUN apt-get update -y && \ + apt-get build-dep -y qemu && \ + apt-get install -y \ + apt-transport-https \ + libtool \ + libtool-bin \ + wget \ + automake \ + autoconf \ + bison \ + git \ + gdb \ + python2 + +# Use a copy of +# https://packages.microsoft.com/config/ubuntu/16.04/packages-microsoft-prod.deb +# to avoid network flakiness. +RUN wget -q https://storage.googleapis.com/fuzzbench-files/packages-microsoft-prod.deb -O packages-microsoft-prod.deb && \ + dpkg -i packages-microsoft-prod.deb && \ + apt-get update -y && \ + apt-get install -y dotnet-sdk-2.1 dotnet-runtime-2.1 && \ + rm packages-microsoft-prod.deb + +# Build Eclipser. +RUN git clone https://github.com/SoftSec-KAIST/Eclipser.git /Eclipser && \ + cd /Eclipser && \ + git checkout ba1d7a55c168f7c19ecceb788a81ea07c2625e45 && \ + ln -sf /usr/bin/python2.7 /usr/local/bin/python && \ + make -j && \ + ln -sf /usr/local/bin/python3.10 /usr/local/bin/python diff --git a/fuzzers/afl_virginmap/builder.Dockerfile b/fuzzers/fairfuzz_t0/builder.Dockerfile similarity index 89% rename from fuzzers/afl_virginmap/builder.Dockerfile rename to fuzzers/fairfuzz_t0/builder.Dockerfile index 2dd23e712..c73ec5c4d 100644 --- a/fuzzers/afl_virginmap/builder.Dockerfile +++ b/fuzzers/fairfuzz_t0/builder.Dockerfile @@ -15,11 +15,10 @@ ARG parent_image FROM $parent_image -# Download and compile AFL v2.57b. # Set AFL_NO_X86 to skip flaky tests. -RUN git clone https://github.com/vanhauser-thc/AFL.git /afl && \ +RUN git clone https://github.com/carolemieux/afl-rb.git /afl && \ cd /afl && \ - git checkout virgin && \ + git checkout e529c1f1b3666ad94e4d6e7ef24ea648aff39ae2 && \ AFL_NO_X86=1 make # Use afl_driver.cpp from LLVM as our fuzzing library. diff --git a/fuzzers/fairfuzz_t0/fuzzer.py b/fuzzers/fairfuzz_t0/fuzzer.py new file mode 100755 index 000000000..6f95023ed --- /dev/null +++ b/fuzzers/fairfuzz_t0/fuzzer.py @@ -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. +"""Integration code for FairFuzz fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/fairfuzz_t0/runner.Dockerfile b/fuzzers/fairfuzz_t0/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/fairfuzz_t0/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 diff --git a/fuzzers/afl_random_favored/builder.Dockerfile b/fuzzers/fairfuzz_t1/builder.Dockerfile similarity index 84% rename from fuzzers/afl_random_favored/builder.Dockerfile rename to fuzzers/fairfuzz_t1/builder.Dockerfile index 93bd6f3fc..c73ec5c4d 100644 --- a/fuzzers/afl_random_favored/builder.Dockerfile +++ b/fuzzers/fairfuzz_t1/builder.Dockerfile @@ -15,12 +15,10 @@ ARG parent_image FROM $parent_image -RUN apt-get update && \ - apt-get install wget libstdc++-5-dev -y - -RUN git clone https://github.com/Practical-Formal-Methods/AFL-public.git /afl && \ +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/carolemieux/afl-rb.git /afl && \ cd /afl && \ - git checkout randomized_top_rated && \ + git checkout e529c1f1b3666ad94e4d6e7ef24ea648aff39ae2 && \ AFL_NO_X86=1 make # Use afl_driver.cpp from LLVM as our fuzzing library. diff --git a/fuzzers/fairfuzz_t1/fuzzer.py b/fuzzers/fairfuzz_t1/fuzzer.py new file mode 100755 index 000000000..6f95023ed --- /dev/null +++ b/fuzzers/fairfuzz_t1/fuzzer.py @@ -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. +"""Integration code for FairFuzz fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/fairfuzz_t1/runner.Dockerfile b/fuzzers/fairfuzz_t1/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/fairfuzz_t1/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 diff --git a/fuzzers/fairfuzz_t2/builder.Dockerfile b/fuzzers/fairfuzz_t2/builder.Dockerfile new file mode 100644 index 000000000..c73ec5c4d --- /dev/null +++ b/fuzzers/fairfuzz_t2/builder.Dockerfile @@ -0,0 +1,30 @@ +# 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 + +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/carolemieux/afl-rb.git /afl && \ + cd /afl && \ + git checkout e529c1f1b3666ad94e4d6e7ef24ea648aff39ae2 && \ + AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/fairfuzz_t2/fuzzer.py b/fuzzers/fairfuzz_t2/fuzzer.py new file mode 100755 index 000000000..6f95023ed --- /dev/null +++ b/fuzzers/fairfuzz_t2/fuzzer.py @@ -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. +"""Integration code for FairFuzz fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/fairfuzz_t2/runner.Dockerfile b/fuzzers/fairfuzz_t2/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/fairfuzz_t2/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 diff --git a/fuzzers/fairfuzz_t3/builder.Dockerfile b/fuzzers/fairfuzz_t3/builder.Dockerfile new file mode 100644 index 000000000..c73ec5c4d --- /dev/null +++ b/fuzzers/fairfuzz_t3/builder.Dockerfile @@ -0,0 +1,30 @@ +# 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 + +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/carolemieux/afl-rb.git /afl && \ + cd /afl && \ + git checkout e529c1f1b3666ad94e4d6e7ef24ea648aff39ae2 && \ + AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/fairfuzz_t3/fuzzer.py b/fuzzers/fairfuzz_t3/fuzzer.py new file mode 100755 index 000000000..6f95023ed --- /dev/null +++ b/fuzzers/fairfuzz_t3/fuzzer.py @@ -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. +"""Integration code for FairFuzz fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/fairfuzz_t3/runner.Dockerfile b/fuzzers/fairfuzz_t3/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/fairfuzz_t3/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 diff --git a/fuzzers/fairfuzz_t4/builder.Dockerfile b/fuzzers/fairfuzz_t4/builder.Dockerfile new file mode 100644 index 000000000..c73ec5c4d --- /dev/null +++ b/fuzzers/fairfuzz_t4/builder.Dockerfile @@ -0,0 +1,30 @@ +# 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 + +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/carolemieux/afl-rb.git /afl && \ + cd /afl && \ + git checkout e529c1f1b3666ad94e4d6e7ef24ea648aff39ae2 && \ + AFL_NO_X86=1 make + +# 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/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 diff --git a/fuzzers/fairfuzz_t4/fuzzer.py b/fuzzers/fairfuzz_t4/fuzzer.py new file mode 100755 index 000000000..6f95023ed --- /dev/null +++ b/fuzzers/fairfuzz_t4/fuzzer.py @@ -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. +"""Integration code for FairFuzz fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/fairfuzz_t4/runner.Dockerfile b/fuzzers/fairfuzz_t4/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/fairfuzz_t4/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 diff --git a/fuzzers/fox/builder.Dockerfile b/fuzzers/fox/builder.Dockerfile new file mode 100644 index 000000000..c8619223b --- /dev/null +++ b/fuzzers/fox/builder.Dockerfile @@ -0,0 +1,102 @@ +# 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 ubuntu:focal +# ARG DEBIAN_FRONTEND=noninteractive + +ARG parent_image +FROM $parent_image + +RUN apt-get update && \ + apt-get -y install --no-install-suggests --no-install-recommends \ + automake \ + cmake \ + meson \ + ninja-build \ + bison flex \ + build-essential \ + git \ + binutils \ + python3 python3-dev python3-setuptools python-is-python3 \ + libtool libtool-bin \ + libglib2.0-dev \ + wget vim jupp nano bash-completion less \ + apt-utils apt-transport-https ca-certificates gnupg dialog \ + libpixman-1-dev \ + gnuplot-nox \ + sudo \ + && rm -rf /var/lib/apt/lists/* + +# Add ~/.local/bin and /usr/local/go/bin to the PATH +RUN mkdir -p /home/$USER_NAME/.local/bin +ENV PATH="/home/.local/bin:/usr/local/go/bin:/fox/gllvm_bins:${PATH}" +RUN echo "export PATH=$PATH" >> ~/.bashrc + +RUN apt-get update && \ + apt-get -y install --no-install-suggests --no-install-recommends \ + lsb-release wget software-properties-common gnupg + +RUN wget https://apt.llvm.org/llvm.sh +RUN chmod +x llvm.sh +RUN sudo ./llvm.sh 15 + +RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-15 10 \ + --slave /usr/bin/clang++ clang++ /usr/bin/clang++-15 \ + --slave /usr/bin/opt opt /usr/bin/opt-15 +RUN update-alternatives --install /usr/lib/llvm llvm /usr/lib/llvm-15 20 \ + --slave /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-15 \ + --slave /usr/bin/llvm-link llvm-link /usr/bin/llvm-link-15 + +ENV LLVM_CONFIG=llvm-config-15 + +# Import and setup FOX : TODO : add publie repo +RUN git clone https://github.com/adamstorek/FOX.git /fox +RUN git -C /fox checkout sbft24_stable +RUN rm -f /dev/shm/* + +RUN git clone https://github.com/adamstorek/FOX.git /fox_cmplog +RUN git -C /fox_cmplog checkout 4.10c_hybrid_mode +RUN rm -f /dev/shm/* + +# XXX: Set up vanilla AFL++ as a vanilla option to invoke in case the compilation +# fails (Current known failing targets: harfbuzz, systemd, php) +RUN git clone -b dev https://github.com/AFLplusplus/AFLplusplus /afl_vanilla && \ + cd /afl_vanilla && \ + git checkout tags/v4.10c || \ + true + +# Build without Python support as we don't need it. +# Set AFL_NO_X86 to skip flaky tests. +RUN cd /afl_vanilla && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang-15 AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / + +RUN cd /fox && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang-15 AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / + +RUN cd /fox_cmplog && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang-15 AFL_NO_X86=1 && \ + PYTHON_INCLUDE=/ make && \ + cp utils/aflpp_driver/libAFLDriver.a / + +RUN rm /usr/local/bin/llvm-nm +RUN sudo ln -s /usr/bin/llvm-nm-15 /usr/local/bin/llvm-nm + +RUN rm -rf /usr/local/bin/clang* diff --git a/fuzzers/fox/fuzzer.py b/fuzzers/fox/fuzzer.py new file mode 100644 index 000000000..384be773c --- /dev/null +++ b/fuzzers/fox/fuzzer.py @@ -0,0 +1,390 @@ +# 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 FOX fuzzer.""" + +import os +import shutil +import subprocess +import sys + +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 get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, "cmplog") + + +def get_vanilla_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, "vanilla") + + +def install(package): + """Install Dependencies""" + subprocess.check_call([sys.executable, "-m", "pip", "install", package]) + + +def install_all(): + """Dependencies""" + # packages = ["decorator==5.1.1", "ipdb==0.13.13", "ipython==8.12.2", + # "networkit==10.1", "numpy==1.24.4","pickleshare==0.7.5", "scipy==1.10.1", + # "tomli==2.0.1"] + packages = [ + "asttokens==2.2.1", "backcall==0.2.0", "decorator==5.1.1", + "executing==1.2.0", "greenstalk==2.0.2", "ipdb==0.13.13", + "ipython==8.12.2", "jedi==0.18.2", "networkit==10.1", "numpy==1.24.4", + "parso==0.8.3", "pexpect==4.8.0", "pickleshare==0.7.5", + "prompt-toolkit==3.0.39", "psutil==5.9.5", "ptyprocess==0.7.0", + "pure-eval==0.2.2", "Pygments==2.15.1", "PyYAML==5.3.1", + "scipy==1.10.1", "six==1.16.0", "stack-data==0.6.2", "tabulate==0.9.0", + "tomli==2.0.1", "traitlets==5.9.0", "typing-extensions==4.7.1", + "wcwidth==0.2.6" + ] + for package in packages: + install(package) + + +def prepare_build_environment(): + """Set environment variables used to build targets for AFL-based + fuzzers.""" + os.environ["AFL_CC"] = "gclang" + os.environ["AFL_CXX"] = "gclang++" + + os.environ["CC"] = "/fox/afl-clang-fast" + os.environ["CXX"] = "/fox/afl-clang-fast++" + os.environ["FUZZER_LIB"] = "/fox/libAFLDriver.a" + + # Fixup a file for mbedtls + if is_benchmark("mbedtls"): + file_path = os.path.join(os.getenv("SRC"), "mbedtls", + "library/CMakeLists.txt") + assert os.path.isfile(file_path), "The file does not exist" + # Remove -Wdocumentation to make compilation pass with clang 15.0.7 + # subst_cmd = r"sed -i 's/\(-Wdocumentation\)//g' {}".format(file_path) + subst_cmd = r"sed -i 's/\(-Wdocumentation\)//g'" + " " + file_path + subprocess.check_call(subst_cmd, shell=True) + + # Fixup a file for openthread + if is_benchmark("openthread"): + mbed_cmake_one = os.path.join(os.getenv("SRC"), + "openthread/third_party/mbedtls/repo", + "library/CMakeLists.txt") + mbed_cmake_two = os.path.join(os.getenv("SRC"), + "openthread/third_party/mbedtls/repo", + "CMakeLists.txt") + assert os.path.isfile(mbed_cmake_one), "The file does not exist" + assert os.path.isfile(mbed_cmake_two), "The file does not exist" + subst_cmd = r"sed -i 's/\(-Wdocumentation\)//g'" + " " + mbed_cmake_one + subprocess.check_call(subst_cmd, shell=True) + subst_cmd = r"sed -i 's/\(-Werror\)//g'" + " " + mbed_cmake_two + subprocess.check_call(subst_cmd, shell=True) + + +def build_fox_binary(): + """Build fox binary""" + + is_vanilla = False + subprocess.check_call(["rm", "-f", "/dev/shm/*"]) + + print("[build 0/2] build target binary") + src = os.getenv("SRC") + work = os.getenv("WORK") + pwd = os.getcwd() + + os.environ["AFL_LLVM_DICT2FILE"] = os.environ["OUT"] + "/keyval.dict" + os.environ["AFL_LLVM_DICT2FILE_NO_MAIN"] = "1" + + # Create personal backups in case + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + try: + utils.build_benchmark() + + subprocess.check_call([ + "cp", "/dev/shm/br_src_map", + os.path.join(os.environ["OUT"], "br_src_map") + ]) + subprocess.check_call([ + "cp", "/dev/shm/strcmp_err_log", + os.path.join(os.environ["OUT"], "strcmp_err_log") + ]) + subprocess.check_call([ + "cp", "/dev/shm/instrument_meta_data", + os.path.join(os.environ["OUT"], "instrument_meta_data") + ]) + + print("[build 1/2] generate metadata") + # use FUZZ_TARGET env to generate metadata + env = os.environ.copy() + + fuzz_target = os.path.join(os.environ["OUT"], + os.environ["FUZZ_TARGET"]) + subprocess.check_call(["get-bc", fuzz_target], env=env) + + bc_file = fuzz_target + ".bc" + subprocess.check_call(["llvm-dis-15", bc_file], env=env) + + ll_file = fuzz_target + ".ll" + + os.chdir("/out") + gen_graph_python = "/fox/gen_graph_dev_no_dot_15_noasan.py" + subprocess.check_call([ + "python3", gen_graph_python, ll_file, fuzz_target, + "instrument_meta_data" + ], + env=env) + os.chdir(pwd) + except subprocess.CalledProcessError: + print("[X] Compilation or metadata gen failed..using fallback") + # Go back to the base dir where the outfiles are being kept + os.chdir(pwd) + is_vanilla = True + return is_vanilla + + is_vanilla = create_cmplog_binaries() + return is_vanilla + + +def create_cmplog_binaries(): + """Build cmplog binaries""" + + is_vanilla = False + src = os.getenv("SRC") + work = os.getenv("WORK") + pwd = os.getcwd() + + # Create main cmplog binary + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + new_env = os.environ.copy() + cmplog_hybrid_directory_main = os.path.join(os.getenv("OUT"), + "cmplog_hybrid_main") + new_env["OUT"] = cmplog_hybrid_directory_main + fuzz_target = os.getenv("FUZZ_TARGET") + os.mkdir(cmplog_hybrid_directory_main) + if fuzz_target: + new_env["FUZZ_TARGET"] = os.path.join(cmplog_hybrid_directory_main, + os.path.basename(fuzz_target)) + new_env["CC"] = "/fox_cmplog/afl-clang-fast" + new_env["CXX"] = "/fox_cmplog/afl-clang-fast++" + new_env["FUZZER_LIB"] = "/fox_cmplog/libAFLDriver.a" + try: + utils.build_benchmark(env=new_env) + os.chdir(pwd) + except subprocess.CalledProcessError: + print("[X] Compilation or metadata gen failed for main cmplog") + # Go back to the base dir where the outfiles are being kept + os.chdir(pwd) + is_vanilla = True + return is_vanilla + + # Create cmplog build + # Create personal backups in case + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + new_env = os.environ.copy() + new_env["AFL_LLVM_CMPLOG"] = "1" + cmplog_hybrid_directory_support = os.path.join(os.getenv("OUT"), + "cmplog_hybrid_support") + new_env["OUT"] = cmplog_hybrid_directory_support + fuzz_target = os.getenv("FUZZ_TARGET") + os.mkdir(cmplog_hybrid_directory_support) + if fuzz_target: + new_env["FUZZ_TARGET"] = os.path.join( + cmplog_hybrid_directory_support, os.path.basename(fuzz_target)) + new_env["CC"] = "/fox_cmplog/afl-clang-fast" + new_env["CXX"] = "/fox_cmplog/afl-clang-fast++" + new_env["FUZZER_LIB"] = "/fox_cmplog/libAFLDriver.a" + try: + utils.build_benchmark(env=new_env) + os.chdir(pwd) + except subprocess.CalledProcessError: + print("[X] Compilation or metadata gen failed for support cmplog") + # Go back to the base dir where the outfiles are being kept + os.chdir(pwd) + is_vanilla = True + return is_vanilla + return is_vanilla + + +def build(): + """Build benchmark.""" + is_vanilla = False + install_all() + prepare_build_environment() + + src = os.getenv("SRC") + work = os.getenv("WORK") + + is_vanilla = build_fox_binary() + + if is_vanilla: + new_env = os.environ.copy() + new_env["CC"] = "/afl_vanilla/afl-clang-fast" + new_env["CXX"] = "/afl_vanilla/afl-clang-fast++" + new_env["FUZZER_LIB"] = "/afl_vanilla/libAFLDriver.a" + vanilla_build_directory = get_vanilla_build_directory(os.getenv("OUT")) + os.mkdir(vanilla_build_directory) + new_env["OUT"] = vanilla_build_directory + fuzz_target = os.getenv("FUZZ_TARGET") + if fuzz_target: + new_env["FUZZ_TARGET"] = os.path.join(vanilla_build_directory, + os.path.basename(fuzz_target)) + with utils.restore_directory(src), utils.restore_directory(work): + utils.build_benchmark(env=new_env) + shutil.copy(new_env["FUZZ_TARGET"], os.getenv("OUT")) + + # Build the vanilla binary + new_env["AFL_LLVM_CMPLOG"] = "1" + + cmplog_build_directory = get_cmplog_build_directory(os.getenv("OUT")) + os.mkdir(cmplog_build_directory) + new_env["OUT"] = cmplog_build_directory + fuzz_target = os.getenv("FUZZ_TARGET") + if fuzz_target: + new_env["FUZZ_TARGET"] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print("Re-building benchmark for CmpLog fuzzing target") + with utils.restore_directory(src), utils.restore_directory(work): + utils.build_benchmark(env=new_env) + + # Write a flag file to signal that fox processing failed + with open(os.path.join(os.getenv("OUT"), "is_vanilla"), + "w", + encoding="utf-8") as file_desc: + file_desc.write("is_vanilla") + + print("[post_build] Copying afl-fuzz to $OUT directory") + # Copy out the afl-fuzz binary as a build artifact. + shutil.copy("/fox/afl-fuzz", + os.path.join(os.environ["OUT"], "fox_4.09c_hybrid_start")) + shutil.copy("/fox/ensemble_runner.py", os.environ["OUT"]) + shutil.copy("/fox_cmplog/afl-fuzz", + os.path.join(os.environ["OUT"], "cmplog_4.09c_hybrid_start")) + shutil.copy("/afl_vanilla/afl-fuzz", + os.path.join(os.environ["OUT"], "afl-fuzz-vanilla")) + + +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" + + #XXX: Added from aflplusplus + os.environ["AFL_FAST_CAL"] = "1" + os.environ["AFL_DISABLE_TRIM"] = "1" + os.environ["AFL_CMPLOG_ONLY_NEW"] = "1" + + # Allows resuming from an already fuzzed outdir (needed for fox hybrid mode) + os.environ["AFL_AUTORESUME"] = "1" + + # AFL needs at least one non-empty seed to start. + utils.create_seed_file_for_empty_corpus(input_corpus) + + +def run_afl_fuzz(input_corpus, output_corpus, target_binary, hide_output=False): + """Run afl-fuzz.""" + # Spawn the afl fuzzing process. + is_vanilla = False + dictionary_path = utils.get_dictionary_path(target_binary) + print("[run_afl_fuzz] Running target with afl-fuzz") + # Check if the fuzzer is to be run in fallback mode or not + if os.path.exists(os.path.join(os.getenv("OUT"), "is_vanilla")): + is_vanilla = True + if not is_vanilla: + cmplog_target_binary_directory_main = os.path.join( + os.path.dirname(target_binary), "cmplog_hybrid_main") + cmplog_target_binary_main = os.path.join( + cmplog_target_binary_directory_main, + os.path.basename(target_binary)) + + cmplog_target_binary_directory_support = os.path.join( + os.path.dirname(target_binary), "cmplog_hybrid_support") + cmplog_target_binary_support = os.path.join( + cmplog_target_binary_directory_support, + os.path.basename(target_binary)) + if dictionary_path: + command = [ + "python", "ensemble_runner.py", "-i", input_corpus, "-o", + output_corpus, "-b", cmplog_target_binary_main, + "--fox_target_binary", target_binary, "-x", "/out/keyval.dict", + dictionary_path, "--cmplog_target_binary", + cmplog_target_binary_support + ] + else: + command = [ + "python", "ensemble_runner.py", "-i", input_corpus, "-o", + output_corpus, "-b", cmplog_target_binary_main, + "--fox_target_binary", target_binary, "-x", "/out/keyval.dict", + "--cmplog_target_binary", cmplog_target_binary_support + ] + else: + # Calculate vanilla binary path from the instrumented target binary. + # Calculate CmpLog binary path from the instrumented target binary. + cmplog_target_binary_directory = (get_cmplog_build_directory( + os.path.dirname(target_binary))) + vanilla_target_binary = os.path.join( + get_vanilla_build_directory(os.path.dirname(target_binary)), + os.path.basename(target_binary)) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + os.path.basename(target_binary)) + if dictionary_path: + command = [ + "./afl-fuzz-vanilla", "-i", input_corpus, "-o", output_corpus, + "-t", "1000+", "-s", "0", "-m", "none", "-c", cmplog_target_binary, "-x", + "/out/keyval.dict", "-x", dictionary_path, "--", + vanilla_target_binary + ] + else: + command = [ + "./afl-fuzz-vanilla", "-i", input_corpus, "-o", output_corpus, + "-t", "1000+", "-s", "0", "-m", "none", "-c", cmplog_target_binary, "-x", + "/out/keyval.dict", "--", vanilla_target_binary + ] + 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/fox/runner.Dockerfile b/fuzzers/fox/runner.Dockerfile new file mode 100644 index 000000000..f0a87f43e --- /dev/null +++ b/fuzzers/fox/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 install -y unzip git gdb joe diff --git a/fuzzers/honggfuzz_um_prioritize_75/builder.Dockerfile b/fuzzers/honggfuzz_t0/builder.Dockerfile similarity index 85% rename from fuzzers/honggfuzz_um_prioritize_75/builder.Dockerfile rename to fuzzers/honggfuzz_t0/builder.Dockerfile index d5c2c5dca..11a483288 100644 --- a/fuzzers/honggfuzz_um_prioritize_75/builder.Dockerfile +++ b/fuzzers/honggfuzz_t0/builder.Dockerfile @@ -15,10 +15,6 @@ ARG parent_image FROM $parent_image -RUN apt-get update && apt-get install -y python3 -RUN pip3 install --upgrade --force pip -RUN pip install universalmutator - # honggfuzz requires libfd and libunwid. RUN apt-get update -y && \ apt-get install -y \ @@ -34,7 +30,7 @@ RUN apt-get update -y && \ # honggfuzz doesn't need this when hfuzz-clang(++) is used). RUN git clone https://github.com/google/honggfuzz.git /honggfuzz && \ cd /honggfuzz && \ - git checkout 0b4cd5b1c4cf26b7e022dc1deb931d9318c054cb && \ + git checkout oss-fuzz && \ CFLAGS="-O3 -funroll-loops" make && \ touch empty_lib.c && \ - cc -c -o empty_lib.o empty_lib.c + cc -c -o empty_lib.o empty_lib.c \ No newline at end of file diff --git a/fuzzers/honggfuzz_t0/fuzzer.py b/fuzzers/honggfuzz_t0/fuzzer.py new file mode 100644 index 000000000..7a75a17fd --- /dev/null +++ b/fuzzers/honggfuzz_t0/fuzzer.py @@ -0,0 +1,69 @@ +# 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 Honggfuzz fuzzer.""" + +import os +import shutil +import subprocess + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # honggfuzz doesn't need additional libraries when code is compiled + # with hfuzz-clang(++) + os.environ['CC'] = '/honggfuzz/hfuzz_cc/hfuzz-clang' + os.environ['CXX'] = '/honggfuzz/hfuzz_cc/hfuzz-clang++' + os.environ['FUZZER_LIB'] = '/honggfuzz/empty_lib.o' + + utils.build_benchmark() + + print('[post_build] Copying honggfuzz to $OUT directory') + # Copy over honggfuzz's main fuzzing binary. + shutil.copy('/honggfuzz/honggfuzz', os.environ['OUT']) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + print('[fuzz] Running target with honggfuzz') + command = [ + './honggfuzz', + '--persistent', + '--rlimit_rss', + '2048', + '--sanitizers_del_report=true', + '--input', + input_corpus, + '--output', + output_corpus, + + # Store crashes along with corpus for bug based benchmarking. + '--crashdir', + crashes_dir, + ] + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + command.extend(['--dict', dictionary_path]) + command.extend(['--', target_binary]) + + print('[fuzz] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/honggfuzz_um_parallel/runner.Dockerfile b/fuzzers/honggfuzz_t0/runner.Dockerfile similarity index 100% rename from fuzzers/honggfuzz_um_parallel/runner.Dockerfile rename to fuzzers/honggfuzz_t0/runner.Dockerfile diff --git a/fuzzers/honggfuzz_um_parallel/builder.Dockerfile b/fuzzers/honggfuzz_t1/builder.Dockerfile similarity index 85% rename from fuzzers/honggfuzz_um_parallel/builder.Dockerfile rename to fuzzers/honggfuzz_t1/builder.Dockerfile index d5c2c5dca..11a483288 100644 --- a/fuzzers/honggfuzz_um_parallel/builder.Dockerfile +++ b/fuzzers/honggfuzz_t1/builder.Dockerfile @@ -15,10 +15,6 @@ ARG parent_image FROM $parent_image -RUN apt-get update && apt-get install -y python3 -RUN pip3 install --upgrade --force pip -RUN pip install universalmutator - # honggfuzz requires libfd and libunwid. RUN apt-get update -y && \ apt-get install -y \ @@ -34,7 +30,7 @@ RUN apt-get update -y && \ # honggfuzz doesn't need this when hfuzz-clang(++) is used). RUN git clone https://github.com/google/honggfuzz.git /honggfuzz && \ cd /honggfuzz && \ - git checkout 0b4cd5b1c4cf26b7e022dc1deb931d9318c054cb && \ + git checkout oss-fuzz && \ CFLAGS="-O3 -funroll-loops" make && \ touch empty_lib.c && \ - cc -c -o empty_lib.o empty_lib.c + cc -c -o empty_lib.o empty_lib.c \ No newline at end of file diff --git a/fuzzers/honggfuzz_t1/fuzzer.py b/fuzzers/honggfuzz_t1/fuzzer.py new file mode 100644 index 000000000..7a75a17fd --- /dev/null +++ b/fuzzers/honggfuzz_t1/fuzzer.py @@ -0,0 +1,69 @@ +# 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 Honggfuzz fuzzer.""" + +import os +import shutil +import subprocess + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # honggfuzz doesn't need additional libraries when code is compiled + # with hfuzz-clang(++) + os.environ['CC'] = '/honggfuzz/hfuzz_cc/hfuzz-clang' + os.environ['CXX'] = '/honggfuzz/hfuzz_cc/hfuzz-clang++' + os.environ['FUZZER_LIB'] = '/honggfuzz/empty_lib.o' + + utils.build_benchmark() + + print('[post_build] Copying honggfuzz to $OUT directory') + # Copy over honggfuzz's main fuzzing binary. + shutil.copy('/honggfuzz/honggfuzz', os.environ['OUT']) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + print('[fuzz] Running target with honggfuzz') + command = [ + './honggfuzz', + '--persistent', + '--rlimit_rss', + '2048', + '--sanitizers_del_report=true', + '--input', + input_corpus, + '--output', + output_corpus, + + # Store crashes along with corpus for bug based benchmarking. + '--crashdir', + crashes_dir, + ] + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + command.extend(['--dict', dictionary_path]) + command.extend(['--', target_binary]) + + print('[fuzz] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/honggfuzz_um_prioritize/runner.Dockerfile b/fuzzers/honggfuzz_t1/runner.Dockerfile similarity index 100% rename from fuzzers/honggfuzz_um_prioritize/runner.Dockerfile rename to fuzzers/honggfuzz_t1/runner.Dockerfile diff --git a/fuzzers/honggfuzz_um_random/builder.Dockerfile b/fuzzers/honggfuzz_t2/builder.Dockerfile similarity index 85% rename from fuzzers/honggfuzz_um_random/builder.Dockerfile rename to fuzzers/honggfuzz_t2/builder.Dockerfile index d5c2c5dca..11a483288 100644 --- a/fuzzers/honggfuzz_um_random/builder.Dockerfile +++ b/fuzzers/honggfuzz_t2/builder.Dockerfile @@ -15,10 +15,6 @@ ARG parent_image FROM $parent_image -RUN apt-get update && apt-get install -y python3 -RUN pip3 install --upgrade --force pip -RUN pip install universalmutator - # honggfuzz requires libfd and libunwid. RUN apt-get update -y && \ apt-get install -y \ @@ -34,7 +30,7 @@ RUN apt-get update -y && \ # honggfuzz doesn't need this when hfuzz-clang(++) is used). RUN git clone https://github.com/google/honggfuzz.git /honggfuzz && \ cd /honggfuzz && \ - git checkout 0b4cd5b1c4cf26b7e022dc1deb931d9318c054cb && \ + git checkout oss-fuzz && \ CFLAGS="-O3 -funroll-loops" make && \ touch empty_lib.c && \ - cc -c -o empty_lib.o empty_lib.c + cc -c -o empty_lib.o empty_lib.c \ No newline at end of file diff --git a/fuzzers/honggfuzz_t2/fuzzer.py b/fuzzers/honggfuzz_t2/fuzzer.py new file mode 100644 index 000000000..7a75a17fd --- /dev/null +++ b/fuzzers/honggfuzz_t2/fuzzer.py @@ -0,0 +1,69 @@ +# 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 Honggfuzz fuzzer.""" + +import os +import shutil +import subprocess + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # honggfuzz doesn't need additional libraries when code is compiled + # with hfuzz-clang(++) + os.environ['CC'] = '/honggfuzz/hfuzz_cc/hfuzz-clang' + os.environ['CXX'] = '/honggfuzz/hfuzz_cc/hfuzz-clang++' + os.environ['FUZZER_LIB'] = '/honggfuzz/empty_lib.o' + + utils.build_benchmark() + + print('[post_build] Copying honggfuzz to $OUT directory') + # Copy over honggfuzz's main fuzzing binary. + shutil.copy('/honggfuzz/honggfuzz', os.environ['OUT']) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + print('[fuzz] Running target with honggfuzz') + command = [ + './honggfuzz', + '--persistent', + '--rlimit_rss', + '2048', + '--sanitizers_del_report=true', + '--input', + input_corpus, + '--output', + output_corpus, + + # Store crashes along with corpus for bug based benchmarking. + '--crashdir', + crashes_dir, + ] + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + command.extend(['--dict', dictionary_path]) + command.extend(['--', target_binary]) + + print('[fuzz] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/honggfuzz_um_prioritize_75/runner.Dockerfile b/fuzzers/honggfuzz_t2/runner.Dockerfile similarity index 100% rename from fuzzers/honggfuzz_um_prioritize_75/runner.Dockerfile rename to fuzzers/honggfuzz_t2/runner.Dockerfile diff --git a/fuzzers/honggfuzz_um_prioritize/builder.Dockerfile b/fuzzers/honggfuzz_t3/builder.Dockerfile similarity index 85% rename from fuzzers/honggfuzz_um_prioritize/builder.Dockerfile rename to fuzzers/honggfuzz_t3/builder.Dockerfile index d5c2c5dca..11a483288 100644 --- a/fuzzers/honggfuzz_um_prioritize/builder.Dockerfile +++ b/fuzzers/honggfuzz_t3/builder.Dockerfile @@ -15,10 +15,6 @@ ARG parent_image FROM $parent_image -RUN apt-get update && apt-get install -y python3 -RUN pip3 install --upgrade --force pip -RUN pip install universalmutator - # honggfuzz requires libfd and libunwid. RUN apt-get update -y && \ apt-get install -y \ @@ -34,7 +30,7 @@ RUN apt-get update -y && \ # honggfuzz doesn't need this when hfuzz-clang(++) is used). RUN git clone https://github.com/google/honggfuzz.git /honggfuzz && \ cd /honggfuzz && \ - git checkout 0b4cd5b1c4cf26b7e022dc1deb931d9318c054cb && \ + git checkout oss-fuzz && \ CFLAGS="-O3 -funroll-loops" make && \ touch empty_lib.c && \ - cc -c -o empty_lib.o empty_lib.c + cc -c -o empty_lib.o empty_lib.c \ No newline at end of file diff --git a/fuzzers/honggfuzz_t3/fuzzer.py b/fuzzers/honggfuzz_t3/fuzzer.py new file mode 100644 index 000000000..7a75a17fd --- /dev/null +++ b/fuzzers/honggfuzz_t3/fuzzer.py @@ -0,0 +1,69 @@ +# 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 Honggfuzz fuzzer.""" + +import os +import shutil +import subprocess + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # honggfuzz doesn't need additional libraries when code is compiled + # with hfuzz-clang(++) + os.environ['CC'] = '/honggfuzz/hfuzz_cc/hfuzz-clang' + os.environ['CXX'] = '/honggfuzz/hfuzz_cc/hfuzz-clang++' + os.environ['FUZZER_LIB'] = '/honggfuzz/empty_lib.o' + + utils.build_benchmark() + + print('[post_build] Copying honggfuzz to $OUT directory') + # Copy over honggfuzz's main fuzzing binary. + shutil.copy('/honggfuzz/honggfuzz', os.environ['OUT']) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + print('[fuzz] Running target with honggfuzz') + command = [ + './honggfuzz', + '--persistent', + '--rlimit_rss', + '2048', + '--sanitizers_del_report=true', + '--input', + input_corpus, + '--output', + output_corpus, + + # Store crashes along with corpus for bug based benchmarking. + '--crashdir', + crashes_dir, + ] + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + command.extend(['--dict', dictionary_path]) + command.extend(['--', target_binary]) + + print('[fuzz] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/honggfuzz_um_random/runner.Dockerfile b/fuzzers/honggfuzz_t3/runner.Dockerfile similarity index 100% rename from fuzzers/honggfuzz_um_random/runner.Dockerfile rename to fuzzers/honggfuzz_t3/runner.Dockerfile diff --git a/fuzzers/honggfuzz_t4/builder.Dockerfile b/fuzzers/honggfuzz_t4/builder.Dockerfile new file mode 100644 index 000000000..11a483288 --- /dev/null +++ b/fuzzers/honggfuzz_t4/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_t4/fuzzer.py b/fuzzers/honggfuzz_t4/fuzzer.py new file mode 100644 index 000000000..7a75a17fd --- /dev/null +++ b/fuzzers/honggfuzz_t4/fuzzer.py @@ -0,0 +1,69 @@ +# 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 Honggfuzz fuzzer.""" + +import os +import shutil +import subprocess + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # honggfuzz doesn't need additional libraries when code is compiled + # with hfuzz-clang(++) + os.environ['CC'] = '/honggfuzz/hfuzz_cc/hfuzz-clang' + os.environ['CXX'] = '/honggfuzz/hfuzz_cc/hfuzz-clang++' + os.environ['FUZZER_LIB'] = '/honggfuzz/empty_lib.o' + + utils.build_benchmark() + + print('[post_build] Copying honggfuzz to $OUT directory') + # Copy over honggfuzz's main fuzzing binary. + shutil.copy('/honggfuzz/honggfuzz', os.environ['OUT']) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + print('[fuzz] Running target with honggfuzz') + command = [ + './honggfuzz', + '--persistent', + '--rlimit_rss', + '2048', + '--sanitizers_del_report=true', + '--input', + input_corpus, + '--output', + output_corpus, + + # Store crashes along with corpus for bug based benchmarking. + '--crashdir', + crashes_dir, + ] + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + command.extend(['--dict', dictionary_path]) + command.extend(['--', target_binary]) + + print('[fuzz] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/honggfuzz_um_random_75/runner.Dockerfile b/fuzzers/honggfuzz_t4/runner.Dockerfile similarity index 100% rename from fuzzers/honggfuzz_um_random_75/runner.Dockerfile rename to fuzzers/honggfuzz_t4/runner.Dockerfile diff --git a/fuzzers/honggfuzz_um_parallel/description.md b/fuzzers/honggfuzz_um_parallel/description.md deleted file mode 100644 index 9163c5cb6..000000000 --- a/fuzzers/honggfuzz_um_parallel/description.md +++ /dev/null @@ -1,9 +0,0 @@ -# aflplusplus UM (parallel) - -Run aflplusplus over mutated code in parallel. - -NOTE: This only works with C or C++ benchmarks. - -[builder.Dockerfile](builder.Dockerfile) -[fuzzer.py](fuzzer.py) -[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/honggfuzz_um_parallel/fuzzer.py b/fuzzers/honggfuzz_um_parallel/fuzzer.py deleted file mode 100644 index c17fc8ce8..000000000 --- a/fuzzers/honggfuzz_um_parallel/fuzzer.py +++ /dev/null @@ -1,205 +0,0 @@ -# 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 honggfuzz fuzzer.""" - -import glob -import os -from pathlib import Path -import random -import shutil -import filecmp -from subprocess import CalledProcessError -import time -import signal -import math -from contextlib import contextmanager - -from fuzzers.honggfuzz import fuzzer as honggfuzz_fuzzer -from fuzzers import utils - - -class TimeoutException(Exception): - """"Exception thrown when timeouts occur""" - - -TOTAL_FUZZING_TIME_DEFAULT = 82800 # 23 hours -TOTAL_BUILD_TIME = 43200 # 12 hours -FUZZ_PROP = 0.5 -DEFAULT_MUTANT_TIMEOUT = 300 -GRACE_TIME = 3600 # 1 hour in seconds -MAX_MUTANTS = 200000 - - -@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 build(): # pylint: disable=too-many-locals,too-many-statements - """Build benchmark.""" - start_time = time.time() - - out = os.getenv("OUT") - src = os.getenv("SRC") - work = os.getenv("WORK") - storage_dir = "/storage" - os.mkdir(storage_dir) - mutate_dir = f"{storage_dir}/mutant_files" - os.mkdir(mutate_dir) - mutate_bins = f"{storage_dir}/mutant_bins" - os.mkdir(mutate_bins) - mutate_scripts = f"{storage_dir}/mutant_scripts" - os.mkdir(mutate_scripts) - orig_out = f"{storage_dir}/orig_out" - os.mkdir(orig_out) - - orig_fuzz_target = os.getenv("FUZZ_TARGET") - with utils.restore_directory(src), utils.restore_directory(work): - honggfuzz_fuzzer.build() - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{orig_fuzz_target}") - os.system(f"cp -r {out}/* {orig_out}/") - benchmark = os.getenv("BENCHMARK") - - source_extensions = [".c", ".cc", ".cpp"] - # Use heuristic to try to find benchmark directory, - # otherwise look for all files in the current directory. - subdirs = [ - name for name in os.listdir(src) - if os.path.isdir(os.path.join(src, name)) - ] - benchmark_src_dir = src - for directory in subdirs: - if directory in benchmark: - benchmark_src_dir = os.path.join(src, directory) - break - - source_files = [] - for extension in source_extensions: - source_files += glob.glob(f"{benchmark_src_dir}/**/*{extension}", - recursive=True) - random.shuffle(source_files) - - mutants = [] - for source_file in source_files: - source_dir = os.path.dirname(source_file).split(src, 1)[1] - Path(f"{mutate_dir}/{source_dir}").mkdir(parents=True, exist_ok=True) - os.system(f"mutate {source_file} --mutantDir \ - {mutate_dir}/{source_dir} --noCheck > /dev/null") - source_base = os.path.basename(source_file).split(".")[0] - mutants_glob = glob.glob( - f"{mutate_dir}/{source_dir}/{source_base}.mutant.*") - mutants += [ - f"{source_dir}/{mutant.split('/')[-1]}"[1:] - for mutant in mutants_glob - ] - - if len(mutants) > MAX_MUTANTS: - break - - random.shuffle(mutants) - with open(f"{mutate_dir}/mutants.txt", "w", encoding="utf-8") as f_name: - f_name.writelines(f"{l}\n" for l in mutants) - - curr_time = time.time() - - # Add grace time for final build at end - remaining_time = int(TOTAL_BUILD_TIME - (start_time - curr_time) - - GRACE_TIME) - try: - with time_limit(remaining_time): - num_non_buggy = 1 - ind = 0 - while ind < len(mutants): - with utils.restore_directory(src), utils.restore_directory( - work): - mutant = mutants[ind] - suffix = "." + mutant.split(".")[-1] - mpart = ".mutant." + mutant.split(".mutant.")[1] - source_file = f"{src}/{mutant.replace(mpart, suffix)}" - print(source_file) - print(f"{mutate_dir}/{mutant}") - os.system(f"cp {source_file} {mutate_dir}/orig") - os.system(f"cp {mutate_dir}/{mutant} {source_file}") - - try: - new_fuzz_target = f"{os.getenv('FUZZ_TARGET')}"\ - f".{num_non_buggy}" - - os.system(f"rm -rf {out}/*") - honggfuzz_fuzzer.build() - if not filecmp.cmp(f'{mutate_bins}/{orig_fuzz_target}', - f'{out}/{orig_fuzz_target}', - shallow=False): - print(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - num_non_buggy += 1 - else: - print("EQUAL") - except RuntimeError: - pass - except CalledProcessError: - pass - os.system(f"cp {mutate_dir}/orig {source_file}") - ind += 1 - except TimeoutException: - pass - - os.system(f"rm -rf {out}/*") - os.system(f"cp -r {orig_out}/* {out}/") - os.system(f"cp {mutate_bins}/* {out}/") - - -def fuzz(input_corpus, output_corpus, target_binary): - """Run fuzzer.""" - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - total_mutant_time = int(FUZZ_PROP * total_fuzzing_time) - - mutants = glob.glob(f"{target_binary}.*") - random.shuffle(mutants) - timeout = max(DEFAULT_MUTANT_TIMEOUT, - int(total_mutant_time / max(len(mutants), 1))) - num_mutants = min(math.ceil(total_mutant_time / timeout), len(mutants)) - - input_corpus_dir = "/storage/input_corpus" - os.makedirs(input_corpus_dir, exist_ok=True) - os.environ['AFL_SKIP_CRASHES'] = "1" - - for mutant in mutants[:num_mutants]: - with utils.restore_directory(input_corpus), utils.restore_directory( - output_corpus): - try: - with time_limit(timeout): - honggfuzz_fuzzer.fuzz(input_corpus, output_corpus, mutant) - except TimeoutException: - pass - except CalledProcessError: - pass - os.system(f"cp -r {output_corpus}/* {input_corpus_dir}/*") - - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - honggfuzz_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/honggfuzz_um_prioritize/description.md b/fuzzers/honggfuzz_um_prioritize/description.md deleted file mode 100644 index ca04efdba..000000000 --- a/fuzzers/honggfuzz_um_prioritize/description.md +++ /dev/null @@ -1,9 +0,0 @@ -# honggfuzz UM (prioritize) - -Run honggfuzz over mutated code with UM prioritization - -NOTE: This only works with C or C++ benchmarks. - -[builder.Dockerfile](builder.Dockerfile) -[fuzzer.py](fuzzer.py) -[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/honggfuzz_um_prioritize/fuzzer.py b/fuzzers/honggfuzz_um_prioritize/fuzzer.py deleted file mode 100755 index 59f86d3a7..000000000 --- a/fuzzers/honggfuzz_um_prioritize/fuzzer.py +++ /dev/null @@ -1,243 +0,0 @@ -# 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 honggfuzz fuzzer.""" - -import glob -import os -from pathlib import Path -import random -import shutil -import filecmp -from subprocess import CalledProcessError -import time -import math -import signal -from contextlib import contextmanager - -from fuzzers.honggfuzz import fuzzer as honggfuzz_fuzzer -from fuzzers import utils - - -class TimeoutException(Exception): - """"Exception thrown when timeouts occur""" - - -TOTAL_FUZZING_TIME_DEFAULT = 82800 # 23 hours -TOTAL_BUILD_TIME = 43200 # 12 hours -FUZZ_PROP = 0.5 -DEFAULT_MUTANT_TIMEOUT = 300 -PRIORITIZE_MULTIPLIER = 5 -GRACE_TIME = 3600 # 1 hour in seconds -MAX_MUTANTS = 200000 -MAX_PRIORITIZE = 30 - - -@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 build(): # pylint: disable=too-many-locals,too-many-statements,too-many-branches - """Build benchmark.""" - start_time = time.time() - - out = os.getenv("OUT") - src = os.getenv("SRC") - work = os.getenv("WORK") - storage_dir = "/storage" - os.mkdir(storage_dir) - mutate_dir = f"{storage_dir}/mutant_files" - os.mkdir(mutate_dir) - mutate_bins = f"{storage_dir}/mutant_bins" - os.mkdir(mutate_bins) - mutate_scripts = f"{storage_dir}/mutant_scripts" - os.mkdir(mutate_scripts) - orig_out = f"{storage_dir}/orig_out" - os.mkdir(orig_out) - - orig_fuzz_target = os.getenv("FUZZ_TARGET") - with utils.restore_directory(src), utils.restore_directory(work): - honggfuzz_fuzzer.build() - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{orig_fuzz_target}") - os.system(f"cp -r {out}/* {orig_out}/") - benchmark = os.getenv("BENCHMARK") - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - - source_extensions = [".c", ".cc", ".cpp"] - num_mutants = math.ceil( - (total_fuzzing_time * FUZZ_PROP) / DEFAULT_MUTANT_TIMEOUT) - # Use heuristic to try to find benchmark directory, otherwise look for all - # files in the current directory. - subdirs = [ - name for name in os.listdir(src) - if os.path.isdir(os.path.join(src, name)) - ] - benchmark_src_dir = src - for directory in subdirs: - if directory in benchmark: - benchmark_src_dir = os.path.join(src, directory) - break - - source_files = [] - for extension in source_extensions: - source_files += glob.glob(f"{benchmark_src_dir}/**/*{extension}", - recursive=True) - random.shuffle(source_files) - - mutants_map = {} - num_mutants = 0 - for source_file in source_files: - source_dir = os.path.dirname(source_file).split(src, 1)[1] - Path(f"{mutate_dir}/{source_dir}").mkdir(parents=True, exist_ok=True) - os.system(f"mutate {source_file} --mutantDir \ - {mutate_dir}/{source_dir} --noCheck > /dev/null") - source_base = os.path.basename(source_file).split(".")[0] - mutants_glob = glob.glob( - f"{mutate_dir}/{source_dir}/{source_base}.mutant.*") - mutants = [ - f"{source_dir}/{mutant.split('/')[-1]}"[1:] - for mutant in mutants_glob - ] - num_mutants += len(mutants) - mutants_map[source_file] = mutants - if num_mutants > MAX_MUTANTS: - break - - prioritize_map = {} - num_prioritized = min( - math.ceil((num_mutants * PRIORITIZE_MULTIPLIER) / len(mutants_map)), - MAX_PRIORITIZE) - for source_file in mutants_map: - mutants = mutants_map[source_file] - with open(f"{mutate_dir}/mutants.txt", "w", encoding="utf_8") as f_name: - f_name.writelines(f"{l}\n" for l in mutants) - os.system(f"prioritize_mutants {mutate_dir}/mutants.txt \ - {mutate_dir}/prioritize_mutants_sorted.txt {num_prioritized}\ - --noSDPriority --sourceDir {src} --mutantDir {mutate_dir}") - prioritized_list = [] - with open(f"{mutate_dir}/prioritize_mutants_sorted.txt", - "r", - encoding="utf_8") as f_name: - prioritized_list = f_name.read().splitlines() - prioritize_map[source_file] = prioritized_list - - prioritized_keys = list(prioritize_map.keys()) - random.shuffle(prioritized_keys) - order = [] - ind = 0 - finished = False - - while not finished: - finished = True - for key in prioritized_keys: - if ind < len(prioritize_map[key]): - finished = False - order.append((key, ind)) - ind += 1 - curr_time = time.time() - - # Add grace time for final build at end - remaining_time = int(TOTAL_BUILD_TIME - (start_time - curr_time) - - GRACE_TIME) - try: - with time_limit(remaining_time): - num_non_buggy = 1 - ind = 0 - while ind < len(order): - with utils.restore_directory(src), utils.restore_directory( - work): - key, line = order[ind] - mutant = prioritize_map[key][line] - print(mutant) - suffix = "." + mutant.split(".")[-1] - mpart = ".mutant." + mutant.split(".mutant.")[1] - source_file = f"{src}/{mutant.replace(mpart, suffix)}" - print(source_file) - print(f"{mutate_dir}/{mutant}") - os.system(f"cp {source_file} {mutate_dir}/orig") - os.system(f"cp {mutate_dir}/{mutant} {source_file}") - try: - new_fuzz_target = f"{os.getenv('FUZZ_TARGET')}"\ - f".{num_non_buggy}" - - os.system(f"rm -rf {out}/*") - honggfuzz_fuzzer.build() - if not filecmp.cmp(f'{mutate_bins}/{orig_fuzz_target}', - f'{out}/{orig_fuzz_target}', - shallow=False): - print(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - num_non_buggy += 1 - print(f"FOUND NOT EQUAL {num_non_buggy}, \ - ind: {ind}") - else: - print(f"EQUAL {num_non_buggy}, ind: {ind}") - except RuntimeError: - pass - except CalledProcessError: - pass - os.system(f"cp {mutate_dir}/orig {source_file}") - ind += 1 - except TimeoutException: - pass - - os.system(f"rm -rf {out}/*") - os.system(f"cp -r {orig_out}/* {out}/") - os.system(f"cp {mutate_bins}/* {out}/") - - -def fuzz(input_corpus, output_corpus, target_binary): - """Run fuzzer.""" - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - total_mutant_time = int(FUZZ_PROP * total_fuzzing_time) - - mutants = glob.glob(f"{target_binary}.*") - random.shuffle(mutants) - timeout = max(DEFAULT_MUTANT_TIMEOUT, - int(total_mutant_time / max(len(mutants), 1))) - num_mutants = min(math.ceil(total_mutant_time / timeout), len(mutants)) - - input_corpus_dir = "/storage/input_corpus" - os.makedirs(input_corpus_dir, exist_ok=True) - - for mutant in mutants[:num_mutants]: - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - with utils.restore_directory(input_corpus), utils.restore_directory( - output_corpus): - try: - with time_limit(timeout): - honggfuzz_fuzzer.fuzz(input_corpus, output_corpus, mutant) - except TimeoutException: - pass - except CalledProcessError: - pass - os.system(f"cp -r {output_corpus}/* {input_corpus_dir}/*") - - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - honggfuzz_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/honggfuzz_um_prioritize_75/description.md b/fuzzers/honggfuzz_um_prioritize_75/description.md deleted file mode 100644 index ca04efdba..000000000 --- a/fuzzers/honggfuzz_um_prioritize_75/description.md +++ /dev/null @@ -1,9 +0,0 @@ -# honggfuzz UM (prioritize) - -Run honggfuzz over mutated code with UM prioritization - -NOTE: This only works with C or C++ benchmarks. - -[builder.Dockerfile](builder.Dockerfile) -[fuzzer.py](fuzzer.py) -[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/honggfuzz_um_prioritize_75/fuzzer.py b/fuzzers/honggfuzz_um_prioritize_75/fuzzer.py deleted file mode 100755 index a6c9ea22f..000000000 --- a/fuzzers/honggfuzz_um_prioritize_75/fuzzer.py +++ /dev/null @@ -1,243 +0,0 @@ -# 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 honggfuzz fuzzer.""" - -import glob -import os -from pathlib import Path -import random -import shutil -import filecmp -from subprocess import CalledProcessError -import time -import math -import signal -from contextlib import contextmanager - -from fuzzers.honggfuzz import fuzzer as honggfuzz_fuzzer -from fuzzers import utils - - -class TimeoutException(Exception): - """"Exception thrown when timeouts occur""" - - -TOTAL_FUZZING_TIME_DEFAULT = 82800 # 23 hours -TOTAL_BUILD_TIME = 43200 # 12 hours -FUZZ_PROP = 0.75 -DEFAULT_MUTANT_TIMEOUT = 300 -PRIORITIZE_MULTIPLIER = 5 -GRACE_TIME = 3600 # 1 hour in seconds -MAX_MUTANTS = 200000 -MAX_PRIORITIZE = 30 - - -@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 build(): # pylint: disable=too-many-locals,too-many-statements,too-many-branches - """Build benchmark.""" - start_time = time.time() - - out = os.getenv("OUT") - src = os.getenv("SRC") - work = os.getenv("WORK") - storage_dir = "/storage" - os.mkdir(storage_dir) - mutate_dir = f"{storage_dir}/mutant_files" - os.mkdir(mutate_dir) - mutate_bins = f"{storage_dir}/mutant_bins" - os.mkdir(mutate_bins) - mutate_scripts = f"{storage_dir}/mutant_scripts" - os.mkdir(mutate_scripts) - orig_out = f"{storage_dir}/orig_out" - os.mkdir(orig_out) - - orig_fuzz_target = os.getenv("FUZZ_TARGET") - with utils.restore_directory(src), utils.restore_directory(work): - honggfuzz_fuzzer.build() - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{orig_fuzz_target}") - os.system(f"cp -r {out}/* {orig_out}/") - benchmark = os.getenv("BENCHMARK") - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - - source_extensions = [".c", ".cc", ".cpp"] - num_mutants = math.ceil( - (total_fuzzing_time * FUZZ_PROP) / DEFAULT_MUTANT_TIMEOUT) - # Use heuristic to try to find benchmark directory, otherwise look for all - # files in the current directory. - subdirs = [ - name for name in os.listdir(src) - if os.path.isdir(os.path.join(src, name)) - ] - benchmark_src_dir = src - for directory in subdirs: - if directory in benchmark: - benchmark_src_dir = os.path.join(src, directory) - break - - source_files = [] - for extension in source_extensions: - source_files += glob.glob(f"{benchmark_src_dir}/**/*{extension}", - recursive=True) - random.shuffle(source_files) - - mutants_map = {} - num_mutants = 0 - for source_file in source_files: - source_dir = os.path.dirname(source_file).split(src, 1)[1] - Path(f"{mutate_dir}/{source_dir}").mkdir(parents=True, exist_ok=True) - os.system(f"mutate {source_file} --mutantDir \ - {mutate_dir}/{source_dir} --noCheck > /dev/null") - source_base = os.path.basename(source_file).split(".")[0] - mutants_glob = glob.glob( - f"{mutate_dir}/{source_dir}/{source_base}.mutant.*") - mutants = [ - f"{source_dir}/{mutant.split('/')[-1]}"[1:] - for mutant in mutants_glob - ] - num_mutants += len(mutants) - mutants_map[source_file] = mutants - if num_mutants > MAX_MUTANTS: - break - - prioritize_map = {} - num_prioritized = min( - math.ceil((num_mutants * PRIORITIZE_MULTIPLIER) / len(mutants_map)), - MAX_PRIORITIZE) - for source_file in mutants_map: - mutants = mutants_map[source_file] - with open(f"{mutate_dir}/mutants.txt", "w", encoding="utf_8") as f_name: - f_name.writelines(f"{l}\n" for l in mutants) - os.system(f"prioritize_mutants {mutate_dir}/mutants.txt \ - {mutate_dir}/prioritize_mutants_sorted.txt {num_prioritized}\ - --noSDPriority --sourceDir {src} --mutantDir {mutate_dir}") - prioritized_list = [] - with open(f"{mutate_dir}/prioritize_mutants_sorted.txt", - "r", - encoding="utf_8") as f_name: - prioritized_list = f_name.read().splitlines() - prioritize_map[source_file] = prioritized_list - - prioritized_keys = list(prioritize_map.keys()) - random.shuffle(prioritized_keys) - order = [] - ind = 0 - finished = False - - while not finished: - finished = True - for key in prioritized_keys: - if ind < len(prioritize_map[key]): - finished = False - order.append((key, ind)) - ind += 1 - curr_time = time.time() - - # Add grace time for final build at end - remaining_time = int(TOTAL_BUILD_TIME - (start_time - curr_time) - - GRACE_TIME) - try: - with time_limit(remaining_time): - num_non_buggy = 1 - ind = 0 - while ind < len(order): - with utils.restore_directory(src), utils.restore_directory( - work): - key, line = order[ind] - mutant = prioritize_map[key][line] - print(mutant) - suffix = "." + mutant.split(".")[-1] - mpart = ".mutant." + mutant.split(".mutant.")[1] - source_file = f"{src}/{mutant.replace(mpart, suffix)}" - print(source_file) - print(f"{mutate_dir}/{mutant}") - os.system(f"cp {source_file} {mutate_dir}/orig") - os.system(f"cp {mutate_dir}/{mutant} {source_file}") - try: - new_fuzz_target = f"{os.getenv('FUZZ_TARGET')}"\ - f".{num_non_buggy}" - - os.system(f"rm -rf {out}/*") - honggfuzz_fuzzer.build() - if not filecmp.cmp(f'{mutate_bins}/{orig_fuzz_target}', - f'{out}/{orig_fuzz_target}', - shallow=False): - print(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - num_non_buggy += 1 - print(f"FOUND NOT EQUAL {num_non_buggy}, \ - ind: {ind}") - else: - print(f"EQUAL {num_non_buggy}, ind: {ind}") - except RuntimeError: - pass - except CalledProcessError: - pass - os.system(f"cp {mutate_dir}/orig {source_file}") - ind += 1 - except TimeoutException: - pass - - os.system(f"rm -rf {out}/*") - os.system(f"cp -r {orig_out}/* {out}/") - os.system(f"cp {mutate_bins}/* {out}/") - - -def fuzz(input_corpus, output_corpus, target_binary): - """Run fuzzer.""" - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - total_mutant_time = int(FUZZ_PROP * total_fuzzing_time) - - mutants = glob.glob(f"{target_binary}.*") - random.shuffle(mutants) - timeout = max(DEFAULT_MUTANT_TIMEOUT, - int(total_mutant_time / max(len(mutants), 1))) - num_mutants = min(math.ceil(total_mutant_time / timeout), len(mutants)) - - input_corpus_dir = "/storage/input_corpus" - os.makedirs(input_corpus_dir, exist_ok=True) - - for mutant in mutants[:num_mutants]: - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - with utils.restore_directory(input_corpus), utils.restore_directory( - output_corpus): - try: - with time_limit(timeout): - honggfuzz_fuzzer.fuzz(input_corpus, output_corpus, mutant) - except TimeoutException: - pass - except CalledProcessError: - pass - os.system(f"cp -r {output_corpus}/* {input_corpus_dir}/*") - - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - honggfuzz_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/honggfuzz_um_random/description.md b/fuzzers/honggfuzz_um_random/description.md deleted file mode 100644 index 686a166cb..000000000 --- a/fuzzers/honggfuzz_um_random/description.md +++ /dev/null @@ -1,10 +0,0 @@ -# aflplusplus UM (random) - -Run aflplusplus over mutated code without UM prioritization. Randomly sample -list of generated mutants. - -NOTE: This only works with C or C++ benchmarks. - -[builder.Dockerfile](builder.Dockerfile) -[fuzzer.py](fuzzer.py) -[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/honggfuzz_um_random/fuzzer.py b/fuzzers/honggfuzz_um_random/fuzzer.py deleted file mode 100644 index 01b87c96c..000000000 --- a/fuzzers/honggfuzz_um_random/fuzzer.py +++ /dev/null @@ -1,206 +0,0 @@ -# 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 honggfuzz fuzzer.""" - -import glob -import os -from pathlib import Path -import random -import shutil -import filecmp -from subprocess import CalledProcessError -import time -import signal -import math -from contextlib import contextmanager - -from fuzzers.honggfuzz import fuzzer as honggfuzz_fuzzer -from fuzzers import utils - - -class TimeoutException(Exception): - """"Exception thrown when timeouts occur""" - - -TOTAL_FUZZING_TIME_DEFAULT = 82800 # 23 hours -TOTAL_BUILD_TIME = 43200 # 12 hours -FUZZ_PROP = 0.5 -DEFAULT_MUTANT_TIMEOUT = 300 -GRACE_TIME = 3600 # 1 hour in seconds -MAX_MUTANTS = 200000 - - -@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 build(): # pylint: disable=too-many-locals,too-many-statements - """Build benchmark.""" - start_time = time.time() - - out = os.getenv("OUT") - src = os.getenv("SRC") - work = os.getenv("WORK") - storage_dir = "/storage" - os.mkdir(storage_dir) - mutate_dir = f"{storage_dir}/mutant_files" - os.mkdir(mutate_dir) - mutate_bins = f"{storage_dir}/mutant_bins" - os.mkdir(mutate_bins) - mutate_scripts = f"{storage_dir}/mutant_scripts" - os.mkdir(mutate_scripts) - orig_out = f"{storage_dir}/orig_out" - os.mkdir(orig_out) - - orig_fuzz_target = os.getenv("FUZZ_TARGET") - with utils.restore_directory(src), utils.restore_directory(work): - honggfuzz_fuzzer.build() - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{orig_fuzz_target}") - os.system(f"cp -r {out}/* {orig_out}/") - benchmark = os.getenv("BENCHMARK") - - source_extensions = [".c", ".cc", ".cpp"] - # Use heuristic to try to find benchmark directory, - # otherwise look for all files in the current directory. - subdirs = [ - name for name in os.listdir(src) - if os.path.isdir(os.path.join(src, name)) - ] - benchmark_src_dir = src - for directory in subdirs: - if directory in benchmark: - benchmark_src_dir = os.path.join(src, directory) - break - - source_files = [] - for extension in source_extensions: - source_files += glob.glob(f"{benchmark_src_dir}/**/*{extension}", - recursive=True) - random.shuffle(source_files) - - mutants = [] - for source_file in source_files: - source_dir = os.path.dirname(source_file).split(src, 1)[1] - Path(f"{mutate_dir}/{source_dir}").mkdir(parents=True, exist_ok=True) - os.system(f"mutate {source_file} --mutantDir \ - {mutate_dir}/{source_dir} --noCheck > /dev/null") - source_base = os.path.basename(source_file).split(".")[0] - mutants_glob = glob.glob( - f"{mutate_dir}/{source_dir}/{source_base}.mutant.*") - mutants += [ - f"{source_dir}/{mutant.split('/')[-1]}"[1:] - for mutant in mutants_glob - ] - - if len(mutants) > MAX_MUTANTS: - break - - random.shuffle(mutants) - with open(f"{mutate_dir}/mutants.txt", "w", encoding="utf-8") as f_name: - f_name.writelines(f"{l}\n" for l in mutants) - - curr_time = time.time() - - # Add grace time for final build at end - remaining_time = int(TOTAL_BUILD_TIME - (start_time - curr_time) - - GRACE_TIME) - try: - with time_limit(remaining_time): - num_non_buggy = 1 - ind = 0 - while ind < len(mutants): - with utils.restore_directory(src), utils.restore_directory( - work): - mutant = mutants[ind] - suffix = "." + mutant.split(".")[-1] - mpart = ".mutant." + mutant.split(".mutant.")[1] - source_file = f"{src}/{mutant.replace(mpart, suffix)}" - print(source_file) - print(f"{mutate_dir}/{mutant}") - os.system(f"cp {source_file} {mutate_dir}/orig") - os.system(f"cp {mutate_dir}/{mutant} {source_file}") - - try: - new_fuzz_target = f"{os.getenv('FUZZ_TARGET')}"\ - f".{num_non_buggy}" - - os.system(f"rm -rf {out}/*") - honggfuzz_fuzzer.build() - if not filecmp.cmp(f'{mutate_bins}/{orig_fuzz_target}', - f'{out}/{orig_fuzz_target}', - shallow=False): - print(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - num_non_buggy += 1 - else: - print("EQUAL") - except RuntimeError: - pass - except CalledProcessError: - pass - os.system(f"cp {mutate_dir}/orig {source_file}") - ind += 1 - except TimeoutException: - pass - - os.system(f"rm -rf {out}/*") - os.system(f"cp -r {orig_out}/* {out}/") - os.system(f"cp {mutate_bins}/* {out}/") - - -def fuzz(input_corpus, output_corpus, target_binary): - """Run fuzzer.""" - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - total_mutant_time = int(FUZZ_PROP * total_fuzzing_time) - - mutants = glob.glob(f"{target_binary}.*") - random.shuffle(mutants) - timeout = max(DEFAULT_MUTANT_TIMEOUT, - int(total_mutant_time / max(len(mutants), 1))) - num_mutants = min(math.ceil(total_mutant_time / timeout), len(mutants)) - - input_corpus_dir = "/storage/input_corpus" - os.makedirs(input_corpus_dir, exist_ok=True) - os.environ['AFL_SKIP_CRASHES'] = "1" - - for mutant in mutants[:num_mutants]: - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - with utils.restore_directory(input_corpus), utils.restore_directory( - output_corpus): - try: - with time_limit(timeout): - honggfuzz_fuzzer.fuzz(input_corpus, output_corpus, mutant) - except TimeoutException: - pass - except CalledProcessError: - pass - os.system(f"cp -r {output_corpus}/* {input_corpus_dir}/*") - - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - honggfuzz_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/honggfuzz_um_random_75/builder.Dockerfile b/fuzzers/honggfuzz_um_random_75/builder.Dockerfile deleted file mode 100644 index d5c2c5dca..000000000 --- a/fuzzers/honggfuzz_um_random_75/builder.Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -# 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 apt-get update && apt-get install -y python3 -RUN pip3 install --upgrade --force pip -RUN pip install universalmutator - -# 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 0b4cd5b1c4cf26b7e022dc1deb931d9318c054cb && \ - CFLAGS="-O3 -funroll-loops" make && \ - touch empty_lib.c && \ - cc -c -o empty_lib.o empty_lib.c diff --git a/fuzzers/honggfuzz_um_random_75/description.md b/fuzzers/honggfuzz_um_random_75/description.md deleted file mode 100644 index 686a166cb..000000000 --- a/fuzzers/honggfuzz_um_random_75/description.md +++ /dev/null @@ -1,10 +0,0 @@ -# aflplusplus UM (random) - -Run aflplusplus over mutated code without UM prioritization. Randomly sample -list of generated mutants. - -NOTE: This only works with C or C++ benchmarks. - -[builder.Dockerfile](builder.Dockerfile) -[fuzzer.py](fuzzer.py) -[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/honggfuzz_um_random_75/fuzzer.py b/fuzzers/honggfuzz_um_random_75/fuzzer.py deleted file mode 100644 index ad9bf91e0..000000000 --- a/fuzzers/honggfuzz_um_random_75/fuzzer.py +++ /dev/null @@ -1,206 +0,0 @@ -# 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 honggfuzz fuzzer.""" - -import glob -import os -from pathlib import Path -import random -import shutil -import filecmp -from subprocess import CalledProcessError -import time -import signal -import math -from contextlib import contextmanager - -from fuzzers.honggfuzz import fuzzer as honggfuzz_fuzzer -from fuzzers import utils - - -class TimeoutException(Exception): - """"Exception thrown when timeouts occur""" - - -TOTAL_FUZZING_TIME_DEFAULT = 82800 # 23 hours -TOTAL_BUILD_TIME = 43200 # 12 hours -FUZZ_PROP = 0.75 -DEFAULT_MUTANT_TIMEOUT = 300 -GRACE_TIME = 3600 # 1 hour in seconds -MAX_MUTANTS = 200000 - - -@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 build(): # pylint: disable=too-many-locals,too-many-statements - """Build benchmark.""" - start_time = time.time() - - out = os.getenv("OUT") - src = os.getenv("SRC") - work = os.getenv("WORK") - storage_dir = "/storage" - os.mkdir(storage_dir) - mutate_dir = f"{storage_dir}/mutant_files" - os.mkdir(mutate_dir) - mutate_bins = f"{storage_dir}/mutant_bins" - os.mkdir(mutate_bins) - mutate_scripts = f"{storage_dir}/mutant_scripts" - os.mkdir(mutate_scripts) - orig_out = f"{storage_dir}/orig_out" - os.mkdir(orig_out) - - orig_fuzz_target = os.getenv("FUZZ_TARGET") - with utils.restore_directory(src), utils.restore_directory(work): - honggfuzz_fuzzer.build() - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{orig_fuzz_target}") - os.system(f"cp -r {out}/* {orig_out}/") - benchmark = os.getenv("BENCHMARK") - - source_extensions = [".c", ".cc", ".cpp"] - # Use heuristic to try to find benchmark directory, - # otherwise look for all files in the current directory. - subdirs = [ - name for name in os.listdir(src) - if os.path.isdir(os.path.join(src, name)) - ] - benchmark_src_dir = src - for directory in subdirs: - if directory in benchmark: - benchmark_src_dir = os.path.join(src, directory) - break - - source_files = [] - for extension in source_extensions: - source_files += glob.glob(f"{benchmark_src_dir}/**/*{extension}", - recursive=True) - random.shuffle(source_files) - - mutants = [] - for source_file in source_files: - source_dir = os.path.dirname(source_file).split(src, 1)[1] - Path(f"{mutate_dir}/{source_dir}").mkdir(parents=True, exist_ok=True) - os.system(f"mutate {source_file} --mutantDir \ - {mutate_dir}/{source_dir} --noCheck > /dev/null") - source_base = os.path.basename(source_file).split(".")[0] - mutants_glob = glob.glob( - f"{mutate_dir}/{source_dir}/{source_base}.mutant.*") - mutants += [ - f"{source_dir}/{mutant.split('/')[-1]}"[1:] - for mutant in mutants_glob - ] - - if len(mutants) > MAX_MUTANTS: - break - - random.shuffle(mutants) - with open(f"{mutate_dir}/mutants.txt", "w", encoding="utf-8") as f_name: - f_name.writelines(f"{l}\n" for l in mutants) - - curr_time = time.time() - - # Add grace time for final build at end - remaining_time = int(TOTAL_BUILD_TIME - (start_time - curr_time) - - GRACE_TIME) - try: - with time_limit(remaining_time): - num_non_buggy = 1 - ind = 0 - while ind < len(mutants): - with utils.restore_directory(src), utils.restore_directory( - work): - mutant = mutants[ind] - suffix = "." + mutant.split(".")[-1] - mpart = ".mutant." + mutant.split(".mutant.")[1] - source_file = f"{src}/{mutant.replace(mpart, suffix)}" - print(source_file) - print(f"{mutate_dir}/{mutant}") - os.system(f"cp {source_file} {mutate_dir}/orig") - os.system(f"cp {mutate_dir}/{mutant} {source_file}") - - try: - new_fuzz_target = f"{os.getenv('FUZZ_TARGET')}"\ - f".{num_non_buggy}" - - os.system(f"rm -rf {out}/*") - honggfuzz_fuzzer.build() - if not filecmp.cmp(f'{mutate_bins}/{orig_fuzz_target}', - f'{out}/{orig_fuzz_target}', - shallow=False): - print(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - shutil.copy(f"{out}/{orig_fuzz_target}", - f"{mutate_bins}/{new_fuzz_target}") - num_non_buggy += 1 - else: - print("EQUAL") - except RuntimeError: - pass - except CalledProcessError: - pass - os.system(f"cp {mutate_dir}/orig {source_file}") - ind += 1 - except TimeoutException: - pass - - os.system(f"rm -rf {out}/*") - os.system(f"cp -r {orig_out}/* {out}/") - os.system(f"cp {mutate_bins}/* {out}/") - - -def fuzz(input_corpus, output_corpus, target_binary): - """Run fuzzer.""" - total_fuzzing_time = int( - os.getenv('MAX_TOTAL_TIME', str(TOTAL_FUZZING_TIME_DEFAULT))) - total_mutant_time = int(FUZZ_PROP * total_fuzzing_time) - - mutants = glob.glob(f"{target_binary}.*") - random.shuffle(mutants) - timeout = max(DEFAULT_MUTANT_TIMEOUT, - int(total_mutant_time / max(len(mutants), 1))) - num_mutants = min(math.ceil(total_mutant_time / timeout), len(mutants)) - - input_corpus_dir = "/storage/input_corpus" - os.makedirs(input_corpus_dir, exist_ok=True) - os.environ['AFL_SKIP_CRASHES'] = "1" - - for mutant in mutants[:num_mutants]: - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - with utils.restore_directory(input_corpus), utils.restore_directory( - output_corpus): - try: - with time_limit(timeout): - honggfuzz_fuzzer.fuzz(input_corpus, output_corpus, mutant) - except TimeoutException: - pass - except CalledProcessError: - pass - os.system(f"cp -r {output_corpus}/* {input_corpus_dir}/*") - - os.system(f"cp -r {input_corpus_dir}/* {input_corpus}/*") - honggfuzz_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/aflpp_random_default/builder.Dockerfile b/fuzzers/kfuzz1/builder.Dockerfile similarity index 50% rename from fuzzers/aflpp_random_default/builder.Dockerfile rename to fuzzers/kfuzz1/builder.Dockerfile index 52bc270f5..0dd7fb843 100644 --- a/fuzzers/aflpp_random_default/builder.Dockerfile +++ b/fuzzers/kfuzz1/builder.Dockerfile @@ -15,21 +15,33 @@ 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/jiradeto/AFLplusplus.git /afl && \ +# Download afl++. +RUN git clone https://github.com/KFuzzing/KFuzz /afl && \ cd /afl && \ - git checkout 773baf9391ff5f1793deb7968366819e7fa07adc + git checkout 24128042eab2824d2e8761d994595637a0a8f7d1 # 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 / diff --git a/fuzzers/kfuzz1/description.md b/fuzzers/kfuzz1/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/kfuzz1/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/kfuzz1/fuzzer.py b/fuzzers/kfuzz1/fuzzer.py new file mode 100755 index 000000000..901769d18 --- /dev/null +++ b/fuzzers/kfuzz1/fuzzer.py @@ -0,0 +1,285 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + flags += ['-k'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/kfuzz1/runner.Dockerfile b/fuzzers/kfuzz1/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/kfuzz1/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/aflpp_random_no_favs/builder.Dockerfile b/fuzzers/kfuzz2/builder.Dockerfile similarity index 50% rename from fuzzers/aflpp_random_no_favs/builder.Dockerfile rename to fuzzers/kfuzz2/builder.Dockerfile index c4066c277..51ad2fdd5 100644 --- a/fuzzers/aflpp_random_no_favs/builder.Dockerfile +++ b/fuzzers/kfuzz2/builder.Dockerfile @@ -15,21 +15,33 @@ 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/jiradeto/AFLplusplus /afl && \ +# Download afl++. +RUN git clone https://github.com/KFuzzing/AFLplusplus /afl && \ cd /afl && \ - git checkout port_random_fuzzing_to_afl++ + git checkout 9c57ed88fb9daaf163f0a799439fe8aaf9796b71 # 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 / diff --git a/fuzzers/kfuzz2/description.md b/fuzzers/kfuzz2/description.md new file mode 100644 index 000000000..f7eb407ad --- /dev/null +++ b/fuzzers/kfuzz2/description.md @@ -0,0 +1,14 @@ +# aflplusplus + +AFL++ fuzzer instance that has the following config active for all benchmarks: + - PCGUARD instrumentation + - cmplog feature + - dict2file feature + - "fast" power schedule + - persistent mode + shared memory test cases + +Repository: [https://github.com/AFLplusplus/AFLplusplus/](https://github.com/AFLplusplus/AFLplusplus/) + +[builder.Dockerfile](builder.Dockerfile) +[fuzzer.py](fuzzer.py) +[runner.Dockerfile](runner.Dockerfile) diff --git a/fuzzers/kfuzz2/fuzzer.py b/fuzzers/kfuzz2/fuzzer.py new file mode 100755 index 000000000..da1b2ff71 --- /dev/null +++ b/fuzzers/kfuzz2/fuzzer.py @@ -0,0 +1,286 @@ +# 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.""" + +import os +import shutil + +from fuzzers.afl import fuzzer as afl_fuzzer +from fuzzers import utils + + +def get_cmplog_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'cmplog') + + +def get_uninstrumented_build_directory(target_directory): + """Return path to CmpLog target directory.""" + return os.path.join(target_directory, 'uninstrumented') + + +def build(*args): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide + # a default configuration. + + build_modes = list(args) + if 'BUILD_MODES' in os.environ: + build_modes = os.environ['BUILD_MODES'].split(',') + + # Placeholder comment. + build_directory = os.environ['OUT'] + + # If nothing was set this is the default: + if not build_modes: + build_modes = ['tracepc', 'cmplog', 'dict2file'] + + # For bug type benchmarks we have to instrument via native clang pcguard :( + build_flags = os.environ['CFLAGS'] + + if build_flags.find( + 'array-bounds' + ) != -1 and 'qemu' not in build_modes and 'classic' not in build_modes: + if 'gcc' not in build_modes: + build_modes[0] = 'native' + + # Instrumentation coverage modes: + if 'lto' in build_modes: + os.environ['CC'] = '/afl/afl-clang-lto' + os.environ['CXX'] = '/afl/afl-clang-lto++' + edge_file = build_directory + '/aflpp_edges.txt' + os.environ['AFL_LLVM_DOCUMENT_IDS'] = edge_file + if os.path.isfile('/usr/local/bin/llvm-ranlib-13'): + os.environ['RANLIB'] = 'llvm-ranlib-13' + os.environ['AR'] = 'llvm-ar-13' + os.environ['AS'] = 'llvm-as-13' + elif os.path.isfile('/usr/local/bin/llvm-ranlib-12'): + os.environ['RANLIB'] = 'llvm-ranlib-12' + os.environ['AR'] = 'llvm-ar-12' + os.environ['AS'] = 'llvm-as-12' + else: + os.environ['RANLIB'] = 'llvm-ranlib' + os.environ['AR'] = 'llvm-ar' + os.environ['AS'] = 'llvm-as' + elif 'qemu' in build_modes: + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + elif 'gcc' in build_modes: + os.environ['CC'] = 'afl-gcc-fast' + os.environ['CXX'] = 'afl-g++-fast' + if build_flags.find('array-bounds') != -1: + os.environ['CFLAGS'] = '-fsanitize=address -O1' + os.environ['CXXFLAGS'] = '-fsanitize=address -O1' + else: + os.environ['CFLAGS'] = '' + os.environ['CXXFLAGS'] = '' + os.environ['CPPFLAGS'] = '' + else: + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + + print('AFL++ build: ') + print(build_modes) + + if 'qemu' in build_modes or 'symcc' in build_modes: + os.environ['CFLAGS'] = ' '.join(utils.NO_SANITIZER_COMPAT_CFLAGS) + cxxflags = [utils.LIBCPLUSPLUS_FLAG] + utils.NO_SANITIZER_COMPAT_CFLAGS + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + + if 'tracepc' in build_modes or 'pcguard' in build_modes: + os.environ['AFL_LLVM_USE_TRACE_PC'] = '1' + elif 'classic' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'CLASSIC' + elif 'native' in build_modes: + os.environ['AFL_LLVM_INSTRUMENT'] = 'LLVMNATIVE' + + # Instrumentation coverage options: + # Do not use a fixed map location (LTO only) + if 'dynamic' in build_modes: + os.environ['AFL_LLVM_MAP_DYNAMIC'] = '1' + # Use a fixed map location (LTO only) + if 'fixed' in build_modes: + os.environ['AFL_LLVM_MAP_ADDR'] = '0x10000' + # Generate an extra dictionary. + if 'dict2file' in build_modes or 'native' in build_modes: + os.environ['AFL_LLVM_DICT2FILE'] = build_directory + '/afl++.dict' + os.environ['AFL_LLVM_DICT2FILE_NO_MAIN'] = '1' + # Enable context sentitivity for LLVM mode (non LTO only) + if 'ctx' in build_modes: + os.environ['AFL_LLVM_CTX'] = '1' + # Enable N-gram coverage for LLVM mode (non LTO only) + if 'ngram2' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '2' + elif 'ngram3' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '3' + elif 'ngram4' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '4' + elif 'ngram5' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '5' + elif 'ngram6' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '6' + elif 'ngram7' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '7' + elif 'ngram8' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '8' + elif 'ngram16' in build_modes: + os.environ['AFL_LLVM_NGRAM_SIZE'] = '16' + if 'ctx1' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '1' + elif 'ctx2' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '2' + elif 'ctx3' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '3' + elif 'ctx4' in build_modes: + os.environ['AFL_LLVM_CTX_K'] = '4' + + # Only one of the following OR cmplog + # enable laf-intel compare splitting + if 'laf' in build_modes: + os.environ['AFL_LLVM_LAF_SPLIT_SWITCHES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_LLVM_LAF_SPLIT_FLOATS'] = '1' + if 'autodict' not in build_modes: + os.environ['AFL_LLVM_LAF_TRANSFORM_COMPARES'] = '1' + + if 'eclipser' in build_modes: + os.environ['FUZZER_LIB'] = '/libStandaloneFuzzTarget.a' + else: + os.environ['FUZZER_LIB'] = '/libAFLDriver.a' + + # Some benchmarks like lcms. (see: + # https://github.com/mm2/Little-CMS/commit/ab1093539b4287c233aca6a3cf53b234faceb792#diff-f0e6d05e72548974e852e8e55dffc4ccR212) + # fail to compile if the compiler outputs things to stderr in unexpected + # cases. Prevent these failures by using AFL_QUIET to stop afl-clang-fast + # from writing AFL specific messages to stderr. + os.environ['AFL_QUIET'] = '1' + os.environ['AFL_MAP_SIZE'] = '2621440' + + src = os.getenv('SRC') + work = os.getenv('WORK') + + with utils.restore_directory(src), utils.restore_directory(work): + # Restore SRC to its initial state so we can build again without any + # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run + # twice in the same directory without this. + utils.build_benchmark() + + if 'cmplog' in build_modes and 'qemu' not in build_modes: + + # CmpLog requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['AFL_LLVM_CMPLOG'] = '1' + + # For CmpLog build, set the OUT and FUZZ_TARGET environment + # variable to point to the new CmpLog build directory. + cmplog_build_directory = get_cmplog_build_directory(build_directory) + os.mkdir(cmplog_build_directory) + new_env['OUT'] = cmplog_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(cmplog_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for CmpLog fuzzing target') + utils.build_benchmark(env=new_env) + + if 'symcc' in build_modes: + + symcc_build_directory = get_uninstrumented_build_directory( + build_directory) + os.mkdir(symcc_build_directory) + + # symcc requires an build with different instrumentation. + new_env = os.environ.copy() + new_env['CC'] = '/symcc/build/symcc' + new_env['CXX'] = '/symcc/build/sym++' + new_env['SYMCC_OUTPUT_DIR'] = '/tmp' + new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') + new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' + new_env['OUT'] = symcc_build_directory + new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' + new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' + new_env['SYMCC_SILENT'] = '1' + + # For symcc build, set the OUT and FUZZ_TARGET environment + # variable to point to the new symcc build directory. + new_env['OUT'] = symcc_build_directory + fuzz_target = os.getenv('FUZZ_TARGET') + if fuzz_target: + new_env['FUZZ_TARGET'] = os.path.join(symcc_build_directory, + os.path.basename(fuzz_target)) + + print('Re-building benchmark for symcc fuzzing target') + utils.build_benchmark(env=new_env) + + shutil.copy('/afl/afl-fuzz', build_directory) + if os.path.exists('/afl/afl-qemu-trace'): + shutil.copy('/afl/afl-qemu-trace', build_directory) + if os.path.exists('/aflpp_qemu_driver_hook.so'): + shutil.copy('/aflpp_qemu_driver_hook.so', build_directory) + if os.path.exists('/get_frida_entry.sh'): + shutil.copy('/afl/afl-frida-trace.so', build_directory) + shutil.copy('/get_frida_entry.sh', build_directory) + + +# pylint: disable=too-many-arguments +def fuzz(input_corpus, + output_corpus, + target_binary, + flags=tuple(), + skip=False, + no_cmplog=False): # pylint: disable=too-many-arguments + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = ( + get_cmplog_build_directory(target_binary_directory)) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + afl_fuzzer.prepare_fuzz_environment(input_corpus) + # decomment this to enable libdislocator. + # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t + # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' + + flags = list(flags) + + if os.path.exists('./afl++.dict'): + flags += ['-x', './afl++.dict'] + + flags += ['-k'] + flags += ['-H'] + + # Move the following to skip for upcoming _double tests: + if os.path.exists(cmplog_target_binary) and no_cmplog is False: + flags += ['-c', cmplog_target_binary] + + #os.environ['AFL_IGNORE_TIMEOUTS'] = '1' + os.environ['AFL_IGNORE_UNKNOWN_ENVS'] = '1' + os.environ['AFL_FAST_CAL'] = '1' + os.environ['AFL_NO_WARN_INSTABILITY'] = '1' + os.environ['AFL_NO_SYNC'] = '1' + + if not skip: + os.environ['AFL_DISABLE_TRIM'] = '1' + os.environ['AFL_CMPLOG_ONLY_NEW'] = '1' + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + + afl_fuzzer.run_afl_fuzz(input_corpus, + output_corpus, + target_binary, + additional_flags=flags) diff --git a/fuzzers/kfuzz2/runner.Dockerfile b/fuzzers/kfuzz2/runner.Dockerfile new file mode 100644 index 000000000..5640d5b24 --- /dev/null +++ b/fuzzers/kfuzz2/runner.Dockerfile @@ -0,0 +1,24 @@ +# 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 upgrade && apt install -y unzip git gdb joe diff --git a/fuzzers/lafintel_t0/builder.Dockerfile b/fuzzers/lafintel_t0/builder.Dockerfile new file mode 100644 index 000000000..f71a9e3e6 --- /dev/null +++ b/fuzzers/lafintel_t0/builder.Dockerfile @@ -0,0 +1,64 @@ +# 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 + +# Need Clang/LLVM 3.8. +RUN apt-get update -y && \ + apt-get -y install llvm-3.8 \ + clang-3.8 \ + libstdc++-5-dev \ + wget + +# Download AFL and compile using default compiler. +# We need afl-2.26b +# Use a copy of +# https://lcamtuf.coredump.cx/afl/releases/afl-2.26b.tgz +# to avoid network flakiness. +RUN wget https://storage.googleapis.com/fuzzbench-files/afl-2.26b.tgz -O /afl-2.26b.tgz && \ + tar xvzf /afl-2.26b.tgz -C / && \ + mv /afl-2.26b /afl && \ + cd /afl && \ + git clone https://github.com/google/AFL.git /afl/recent_afl && \ + cd /afl/recent_afl && \ + git checkout 8da80951dd7eeeb3e3b5a3bcd36c485045f40274 && \ + cd /afl/ && \ + cp /afl/recent_afl/*.c /afl/ && \ + cp /afl/recent_afl/*.h /afl/ && \ + AFL_NO_X86=1 make + +# Set the env variables for LLVM passes and test units. +ENV CC=clang-3.8 +ENV CXX=clang++-3.8 +ENV LLVM_CONFIG=llvm-config-3.8 + +# Build the LLVM passes with the LAF-INTEL patches, using Clang 3.8. +# We force linking by setting maybe_linking = 1, see https://github.com/google/AFL/commit/3ef34c16697715d64fecfaed46c0e31e86fa9f01#diff-49b21a9ca7039117ef774ba1adfa2962 +RUN cd /afl/llvm_mode && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/afl.patch && \ + patch -p0 < afl.patch && \ + sed -i 's/maybe_linking = 0/maybe_linking = 1/g' afl-clang-fast.c && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/compare-transform-pass.so.cc && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/split-compares-pass.so.cc && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/split-switches-pass.so.cc && \ + sed -i 's/errs()/outs()/g' split-switches-pass.so.cc && \ + sed -i 's/errs()/outs()/g' split-compares-pass.so.cc && \ + sed -i 's/errs()/outs()/g' compare-transform-pass.so.cc && \ + CXXFLAGS= CFLAGS= make + +# 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 && \ + $CXX -I/usr/local/include/c++/v1/ -stdlib=libc++ -std=c++11 -O2 -c /afl/afl_driver.cpp && \ + ar r /libAFL.a *.o diff --git a/fuzzers/lafintel_t0/fuzzer.py b/fuzzers/lafintel_t0/fuzzer.py new file mode 100644 index 000000000..3cfc082c9 --- /dev/null +++ b/fuzzers/lafintel_t0/fuzzer.py @@ -0,0 +1,77 @@ +# 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 shutil +import os + +from fuzzers import utils + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def prepare_build_environment(): + """Set environment variables used to build benchmark.""" + + # LLVm 3.8 doesn't support -fsanitize=builtin + def remove_builtin(flag): + split = flag.split('=') + if split[0].startswith('-fsanitize') or split[0].startswith( + '-fno-sanitize'): + options = split[1].split(',') + options = filter(lambda x: x != 'builtin', options) + return split[0] + '=' + ','.join(options) + return flag + + cflags = map(remove_builtin, os.environ['CFLAGS'].split()) + cxxflags = map(remove_builtin, os.environ['CXXFLAGS'].split()) + os.environ['CFLAGS'] = ' '.join(cflags) + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + # In php benchmark, there is a call to __builtin_cpu_supports("ssse3") + # (see https://github.com/php/php-src/blob/master/Zend/zend_cpuinfo.h). + # It is not supported by clang-3.8, so we define the MACRO below + # to replace any __builtin_cpu_supports() with 0, i.e., not supported + cflags = ['-fPIC'] + if 'php' in os.environ['BENCHMARK']: + cflags += ['-D__builtin_cpu_supports\\(x\\)=0'] + cppflags = cflags + ['-I/usr/local/include/c++/v1/', '-std=c++11'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cppflags) + + # Enable LAF-INTEL changes + os.environ['LAF_SPLIT_SWITCHES'] = '1' + os.environ['LAF_TRANSFORM_COMPARES'] = '1' + os.environ['LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_CC'] = 'clang-3.8' + os.environ['AFL_CXX'] = 'clang++-3.8' + + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + 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 fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/lafintel_t0/runner.Dockerfile b/fuzzers/lafintel_t0/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/lafintel_t0/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 diff --git a/fuzzers/lafintel_t1/builder.Dockerfile b/fuzzers/lafintel_t1/builder.Dockerfile new file mode 100644 index 000000000..f71a9e3e6 --- /dev/null +++ b/fuzzers/lafintel_t1/builder.Dockerfile @@ -0,0 +1,64 @@ +# 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 + +# Need Clang/LLVM 3.8. +RUN apt-get update -y && \ + apt-get -y install llvm-3.8 \ + clang-3.8 \ + libstdc++-5-dev \ + wget + +# Download AFL and compile using default compiler. +# We need afl-2.26b +# Use a copy of +# https://lcamtuf.coredump.cx/afl/releases/afl-2.26b.tgz +# to avoid network flakiness. +RUN wget https://storage.googleapis.com/fuzzbench-files/afl-2.26b.tgz -O /afl-2.26b.tgz && \ + tar xvzf /afl-2.26b.tgz -C / && \ + mv /afl-2.26b /afl && \ + cd /afl && \ + git clone https://github.com/google/AFL.git /afl/recent_afl && \ + cd /afl/recent_afl && \ + git checkout 8da80951dd7eeeb3e3b5a3bcd36c485045f40274 && \ + cd /afl/ && \ + cp /afl/recent_afl/*.c /afl/ && \ + cp /afl/recent_afl/*.h /afl/ && \ + AFL_NO_X86=1 make + +# Set the env variables for LLVM passes and test units. +ENV CC=clang-3.8 +ENV CXX=clang++-3.8 +ENV LLVM_CONFIG=llvm-config-3.8 + +# Build the LLVM passes with the LAF-INTEL patches, using Clang 3.8. +# We force linking by setting maybe_linking = 1, see https://github.com/google/AFL/commit/3ef34c16697715d64fecfaed46c0e31e86fa9f01#diff-49b21a9ca7039117ef774ba1adfa2962 +RUN cd /afl/llvm_mode && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/afl.patch && \ + patch -p0 < afl.patch && \ + sed -i 's/maybe_linking = 0/maybe_linking = 1/g' afl-clang-fast.c && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/compare-transform-pass.so.cc && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/split-compares-pass.so.cc && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/split-switches-pass.so.cc && \ + sed -i 's/errs()/outs()/g' split-switches-pass.so.cc && \ + sed -i 's/errs()/outs()/g' split-compares-pass.so.cc && \ + sed -i 's/errs()/outs()/g' compare-transform-pass.so.cc && \ + CXXFLAGS= CFLAGS= make + +# 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 && \ + $CXX -I/usr/local/include/c++/v1/ -stdlib=libc++ -std=c++11 -O2 -c /afl/afl_driver.cpp && \ + ar r /libAFL.a *.o diff --git a/fuzzers/lafintel_t1/fuzzer.py b/fuzzers/lafintel_t1/fuzzer.py new file mode 100644 index 000000000..3cfc082c9 --- /dev/null +++ b/fuzzers/lafintel_t1/fuzzer.py @@ -0,0 +1,77 @@ +# 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 shutil +import os + +from fuzzers import utils + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def prepare_build_environment(): + """Set environment variables used to build benchmark.""" + + # LLVm 3.8 doesn't support -fsanitize=builtin + def remove_builtin(flag): + split = flag.split('=') + if split[0].startswith('-fsanitize') or split[0].startswith( + '-fno-sanitize'): + options = split[1].split(',') + options = filter(lambda x: x != 'builtin', options) + return split[0] + '=' + ','.join(options) + return flag + + cflags = map(remove_builtin, os.environ['CFLAGS'].split()) + cxxflags = map(remove_builtin, os.environ['CXXFLAGS'].split()) + os.environ['CFLAGS'] = ' '.join(cflags) + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + # In php benchmark, there is a call to __builtin_cpu_supports("ssse3") + # (see https://github.com/php/php-src/blob/master/Zend/zend_cpuinfo.h). + # It is not supported by clang-3.8, so we define the MACRO below + # to replace any __builtin_cpu_supports() with 0, i.e., not supported + cflags = ['-fPIC'] + if 'php' in os.environ['BENCHMARK']: + cflags += ['-D__builtin_cpu_supports\\(x\\)=0'] + cppflags = cflags + ['-I/usr/local/include/c++/v1/', '-std=c++11'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cppflags) + + # Enable LAF-INTEL changes + os.environ['LAF_SPLIT_SWITCHES'] = '1' + os.environ['LAF_TRANSFORM_COMPARES'] = '1' + os.environ['LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_CC'] = 'clang-3.8' + os.environ['AFL_CXX'] = 'clang++-3.8' + + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + 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 fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/lafintel_t1/runner.Dockerfile b/fuzzers/lafintel_t1/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/lafintel_t1/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 diff --git a/fuzzers/lafintel_t2/builder.Dockerfile b/fuzzers/lafintel_t2/builder.Dockerfile new file mode 100644 index 000000000..f71a9e3e6 --- /dev/null +++ b/fuzzers/lafintel_t2/builder.Dockerfile @@ -0,0 +1,64 @@ +# 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 + +# Need Clang/LLVM 3.8. +RUN apt-get update -y && \ + apt-get -y install llvm-3.8 \ + clang-3.8 \ + libstdc++-5-dev \ + wget + +# Download AFL and compile using default compiler. +# We need afl-2.26b +# Use a copy of +# https://lcamtuf.coredump.cx/afl/releases/afl-2.26b.tgz +# to avoid network flakiness. +RUN wget https://storage.googleapis.com/fuzzbench-files/afl-2.26b.tgz -O /afl-2.26b.tgz && \ + tar xvzf /afl-2.26b.tgz -C / && \ + mv /afl-2.26b /afl && \ + cd /afl && \ + git clone https://github.com/google/AFL.git /afl/recent_afl && \ + cd /afl/recent_afl && \ + git checkout 8da80951dd7eeeb3e3b5a3bcd36c485045f40274 && \ + cd /afl/ && \ + cp /afl/recent_afl/*.c /afl/ && \ + cp /afl/recent_afl/*.h /afl/ && \ + AFL_NO_X86=1 make + +# Set the env variables for LLVM passes and test units. +ENV CC=clang-3.8 +ENV CXX=clang++-3.8 +ENV LLVM_CONFIG=llvm-config-3.8 + +# Build the LLVM passes with the LAF-INTEL patches, using Clang 3.8. +# We force linking by setting maybe_linking = 1, see https://github.com/google/AFL/commit/3ef34c16697715d64fecfaed46c0e31e86fa9f01#diff-49b21a9ca7039117ef774ba1adfa2962 +RUN cd /afl/llvm_mode && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/afl.patch && \ + patch -p0 < afl.patch && \ + sed -i 's/maybe_linking = 0/maybe_linking = 1/g' afl-clang-fast.c && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/compare-transform-pass.so.cc && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/split-compares-pass.so.cc && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/split-switches-pass.so.cc && \ + sed -i 's/errs()/outs()/g' split-switches-pass.so.cc && \ + sed -i 's/errs()/outs()/g' split-compares-pass.so.cc && \ + sed -i 's/errs()/outs()/g' compare-transform-pass.so.cc && \ + CXXFLAGS= CFLAGS= make + +# 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 && \ + $CXX -I/usr/local/include/c++/v1/ -stdlib=libc++ -std=c++11 -O2 -c /afl/afl_driver.cpp && \ + ar r /libAFL.a *.o diff --git a/fuzzers/lafintel_t2/fuzzer.py b/fuzzers/lafintel_t2/fuzzer.py new file mode 100644 index 000000000..3cfc082c9 --- /dev/null +++ b/fuzzers/lafintel_t2/fuzzer.py @@ -0,0 +1,77 @@ +# 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 shutil +import os + +from fuzzers import utils + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def prepare_build_environment(): + """Set environment variables used to build benchmark.""" + + # LLVm 3.8 doesn't support -fsanitize=builtin + def remove_builtin(flag): + split = flag.split('=') + if split[0].startswith('-fsanitize') or split[0].startswith( + '-fno-sanitize'): + options = split[1].split(',') + options = filter(lambda x: x != 'builtin', options) + return split[0] + '=' + ','.join(options) + return flag + + cflags = map(remove_builtin, os.environ['CFLAGS'].split()) + cxxflags = map(remove_builtin, os.environ['CXXFLAGS'].split()) + os.environ['CFLAGS'] = ' '.join(cflags) + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + # In php benchmark, there is a call to __builtin_cpu_supports("ssse3") + # (see https://github.com/php/php-src/blob/master/Zend/zend_cpuinfo.h). + # It is not supported by clang-3.8, so we define the MACRO below + # to replace any __builtin_cpu_supports() with 0, i.e., not supported + cflags = ['-fPIC'] + if 'php' in os.environ['BENCHMARK']: + cflags += ['-D__builtin_cpu_supports\\(x\\)=0'] + cppflags = cflags + ['-I/usr/local/include/c++/v1/', '-std=c++11'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cppflags) + + # Enable LAF-INTEL changes + os.environ['LAF_SPLIT_SWITCHES'] = '1' + os.environ['LAF_TRANSFORM_COMPARES'] = '1' + os.environ['LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_CC'] = 'clang-3.8' + os.environ['AFL_CXX'] = 'clang++-3.8' + + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + 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 fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/lafintel_t2/runner.Dockerfile b/fuzzers/lafintel_t2/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/lafintel_t2/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 diff --git a/fuzzers/lafintel_t3/builder.Dockerfile b/fuzzers/lafintel_t3/builder.Dockerfile new file mode 100644 index 000000000..f71a9e3e6 --- /dev/null +++ b/fuzzers/lafintel_t3/builder.Dockerfile @@ -0,0 +1,64 @@ +# 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 + +# Need Clang/LLVM 3.8. +RUN apt-get update -y && \ + apt-get -y install llvm-3.8 \ + clang-3.8 \ + libstdc++-5-dev \ + wget + +# Download AFL and compile using default compiler. +# We need afl-2.26b +# Use a copy of +# https://lcamtuf.coredump.cx/afl/releases/afl-2.26b.tgz +# to avoid network flakiness. +RUN wget https://storage.googleapis.com/fuzzbench-files/afl-2.26b.tgz -O /afl-2.26b.tgz && \ + tar xvzf /afl-2.26b.tgz -C / && \ + mv /afl-2.26b /afl && \ + cd /afl && \ + git clone https://github.com/google/AFL.git /afl/recent_afl && \ + cd /afl/recent_afl && \ + git checkout 8da80951dd7eeeb3e3b5a3bcd36c485045f40274 && \ + cd /afl/ && \ + cp /afl/recent_afl/*.c /afl/ && \ + cp /afl/recent_afl/*.h /afl/ && \ + AFL_NO_X86=1 make + +# Set the env variables for LLVM passes and test units. +ENV CC=clang-3.8 +ENV CXX=clang++-3.8 +ENV LLVM_CONFIG=llvm-config-3.8 + +# Build the LLVM passes with the LAF-INTEL patches, using Clang 3.8. +# We force linking by setting maybe_linking = 1, see https://github.com/google/AFL/commit/3ef34c16697715d64fecfaed46c0e31e86fa9f01#diff-49b21a9ca7039117ef774ba1adfa2962 +RUN cd /afl/llvm_mode && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/afl.patch && \ + patch -p0 < afl.patch && \ + sed -i 's/maybe_linking = 0/maybe_linking = 1/g' afl-clang-fast.c && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/compare-transform-pass.so.cc && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/split-compares-pass.so.cc && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/split-switches-pass.so.cc && \ + sed -i 's/errs()/outs()/g' split-switches-pass.so.cc && \ + sed -i 's/errs()/outs()/g' split-compares-pass.so.cc && \ + sed -i 's/errs()/outs()/g' compare-transform-pass.so.cc && \ + CXXFLAGS= CFLAGS= make + +# 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 && \ + $CXX -I/usr/local/include/c++/v1/ -stdlib=libc++ -std=c++11 -O2 -c /afl/afl_driver.cpp && \ + ar r /libAFL.a *.o diff --git a/fuzzers/lafintel_t3/fuzzer.py b/fuzzers/lafintel_t3/fuzzer.py new file mode 100644 index 000000000..3cfc082c9 --- /dev/null +++ b/fuzzers/lafintel_t3/fuzzer.py @@ -0,0 +1,77 @@ +# 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 shutil +import os + +from fuzzers import utils + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def prepare_build_environment(): + """Set environment variables used to build benchmark.""" + + # LLVm 3.8 doesn't support -fsanitize=builtin + def remove_builtin(flag): + split = flag.split('=') + if split[0].startswith('-fsanitize') or split[0].startswith( + '-fno-sanitize'): + options = split[1].split(',') + options = filter(lambda x: x != 'builtin', options) + return split[0] + '=' + ','.join(options) + return flag + + cflags = map(remove_builtin, os.environ['CFLAGS'].split()) + cxxflags = map(remove_builtin, os.environ['CXXFLAGS'].split()) + os.environ['CFLAGS'] = ' '.join(cflags) + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + # In php benchmark, there is a call to __builtin_cpu_supports("ssse3") + # (see https://github.com/php/php-src/blob/master/Zend/zend_cpuinfo.h). + # It is not supported by clang-3.8, so we define the MACRO below + # to replace any __builtin_cpu_supports() with 0, i.e., not supported + cflags = ['-fPIC'] + if 'php' in os.environ['BENCHMARK']: + cflags += ['-D__builtin_cpu_supports\\(x\\)=0'] + cppflags = cflags + ['-I/usr/local/include/c++/v1/', '-std=c++11'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cppflags) + + # Enable LAF-INTEL changes + os.environ['LAF_SPLIT_SWITCHES'] = '1' + os.environ['LAF_TRANSFORM_COMPARES'] = '1' + os.environ['LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_CC'] = 'clang-3.8' + os.environ['AFL_CXX'] = 'clang++-3.8' + + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + 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 fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/lafintel_t3/runner.Dockerfile b/fuzzers/lafintel_t3/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/lafintel_t3/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 diff --git a/fuzzers/lafintel_t4/builder.Dockerfile b/fuzzers/lafintel_t4/builder.Dockerfile new file mode 100644 index 000000000..f71a9e3e6 --- /dev/null +++ b/fuzzers/lafintel_t4/builder.Dockerfile @@ -0,0 +1,64 @@ +# 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 + +# Need Clang/LLVM 3.8. +RUN apt-get update -y && \ + apt-get -y install llvm-3.8 \ + clang-3.8 \ + libstdc++-5-dev \ + wget + +# Download AFL and compile using default compiler. +# We need afl-2.26b +# Use a copy of +# https://lcamtuf.coredump.cx/afl/releases/afl-2.26b.tgz +# to avoid network flakiness. +RUN wget https://storage.googleapis.com/fuzzbench-files/afl-2.26b.tgz -O /afl-2.26b.tgz && \ + tar xvzf /afl-2.26b.tgz -C / && \ + mv /afl-2.26b /afl && \ + cd /afl && \ + git clone https://github.com/google/AFL.git /afl/recent_afl && \ + cd /afl/recent_afl && \ + git checkout 8da80951dd7eeeb3e3b5a3bcd36c485045f40274 && \ + cd /afl/ && \ + cp /afl/recent_afl/*.c /afl/ && \ + cp /afl/recent_afl/*.h /afl/ && \ + AFL_NO_X86=1 make + +# Set the env variables for LLVM passes and test units. +ENV CC=clang-3.8 +ENV CXX=clang++-3.8 +ENV LLVM_CONFIG=llvm-config-3.8 + +# Build the LLVM passes with the LAF-INTEL patches, using Clang 3.8. +# We force linking by setting maybe_linking = 1, see https://github.com/google/AFL/commit/3ef34c16697715d64fecfaed46c0e31e86fa9f01#diff-49b21a9ca7039117ef774ba1adfa2962 +RUN cd /afl/llvm_mode && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/afl.patch && \ + patch -p0 < afl.patch && \ + sed -i 's/maybe_linking = 0/maybe_linking = 1/g' afl-clang-fast.c && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/compare-transform-pass.so.cc && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/split-compares-pass.so.cc && \ + wget https://gitlab.com/laf-intel/laf-llvm-pass/raw/master/src/split-switches-pass.so.cc && \ + sed -i 's/errs()/outs()/g' split-switches-pass.so.cc && \ + sed -i 's/errs()/outs()/g' split-compares-pass.so.cc && \ + sed -i 's/errs()/outs()/g' compare-transform-pass.so.cc && \ + CXXFLAGS= CFLAGS= make + +# 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 && \ + $CXX -I/usr/local/include/c++/v1/ -stdlib=libc++ -std=c++11 -O2 -c /afl/afl_driver.cpp && \ + ar r /libAFL.a *.o diff --git a/fuzzers/lafintel_t4/fuzzer.py b/fuzzers/lafintel_t4/fuzzer.py new file mode 100644 index 000000000..3cfc082c9 --- /dev/null +++ b/fuzzers/lafintel_t4/fuzzer.py @@ -0,0 +1,77 @@ +# 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 shutil +import os + +from fuzzers import utils + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def prepare_build_environment(): + """Set environment variables used to build benchmark.""" + + # LLVm 3.8 doesn't support -fsanitize=builtin + def remove_builtin(flag): + split = flag.split('=') + if split[0].startswith('-fsanitize') or split[0].startswith( + '-fno-sanitize'): + options = split[1].split(',') + options = filter(lambda x: x != 'builtin', options) + return split[0] + '=' + ','.join(options) + return flag + + cflags = map(remove_builtin, os.environ['CFLAGS'].split()) + cxxflags = map(remove_builtin, os.environ['CXXFLAGS'].split()) + os.environ['CFLAGS'] = ' '.join(cflags) + os.environ['CXXFLAGS'] = ' '.join(cxxflags) + # In php benchmark, there is a call to __builtin_cpu_supports("ssse3") + # (see https://github.com/php/php-src/blob/master/Zend/zend_cpuinfo.h). + # It is not supported by clang-3.8, so we define the MACRO below + # to replace any __builtin_cpu_supports() with 0, i.e., not supported + cflags = ['-fPIC'] + if 'php' in os.environ['BENCHMARK']: + cflags += ['-D__builtin_cpu_supports\\(x\\)=0'] + cppflags = cflags + ['-I/usr/local/include/c++/v1/', '-std=c++11'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cppflags) + + # Enable LAF-INTEL changes + os.environ['LAF_SPLIT_SWITCHES'] = '1' + os.environ['LAF_TRANSFORM_COMPARES'] = '1' + os.environ['LAF_SPLIT_COMPARES'] = '1' + os.environ['AFL_CC'] = 'clang-3.8' + os.environ['AFL_CXX'] = 'clang++-3.8' + + os.environ['CC'] = '/afl/afl-clang-fast' + os.environ['CXX'] = '/afl/afl-clang-fast++' + 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 fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/lafintel_t4/runner.Dockerfile b/fuzzers/lafintel_t4/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/lafintel_t4/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 diff --git a/fuzzers/libafl/builder.Dockerfile b/fuzzers/libafl/builder.Dockerfile index f0136ff46..c505f9f0a 100644 --- a/fuzzers/libafl/builder.Dockerfile +++ b/fuzzers/libafl/builder.Dockerfile @@ -38,17 +38,17 @@ RUN wget https://gist.githubusercontent.com/tokatoka/26f4ba95991c6e3313999997633 RUN git clone https://github.com/AFLplusplus/LibAFL /libafl # Checkout a current commit -RUN cd /libafl && git pull && git checkout f856092f3d393056b010fcae3b086769377cba18 || true +RUN cd /libafl && git pull && git checkout 71ed5c722720d081f206dfd0f549dc988742068e || 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/fuzzbench && \ + cd ./fuzzers/inprocess/fuzzbench && \ PATH="/root/.cargo/bin/:$PATH" cargo build --profile release-fuzzbench --features no_link_main # Auxiliary weak references. -RUN cd /libafl/fuzzers/fuzzbench/fuzzbench && \ +RUN cd /libafl/fuzzers/inprocess/fuzzbench && \ clang -c stub_rt.c && \ ar r /stub_rt.a stub_rt.o diff --git a/fuzzers/libafl_fixseed0/builder.Dockerfile b/fuzzers/libafl_fixseed0/builder.Dockerfile new file mode 100644 index 000000000..4e0c56dd6 --- /dev/null +++ b/fuzzers/libafl_fixseed0/builder.Dockerfile @@ -0,0 +1,54 @@ +# 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-2025-04-01 -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 + +# Download libafl. +RUN git clone https://github.com/AFLplusplus/LibAFL /libafl + +# Checkout a current commit +RUN cd /libafl && git pull && git checkout a541fc27d2579bb9c24c533b2ca35dcacc647c90 || 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/inprocess/fuzzbench && \ + PATH="/root/.cargo/bin/:$PATH" cargo build --profile release-fuzzbench --features no_link_main + +# Auxiliary weak references. +RUN cd /libafl/fuzzers/inprocess/fuzzbench && \ + clang -c stub_rt.c && \ + ar r /stub_rt.a stub_rt.o diff --git a/fuzzers/libafl_fixseed0/description.md b/fuzzers/libafl_fixseed0/description.md new file mode 100644 index 000000000..ea9b947d6 --- /dev/null +++ b/fuzzers/libafl_fixseed0/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/libafl_fixseed0/fuzzer.py b/fuzzers/libafl_fixseed0/fuzzer.py new file mode 100755 index 000000000..fbe55aa5e --- /dev/null +++ b/fuzzers/libafl_fixseed0/fuzzer.py @@ -0,0 +1,72 @@ +# 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 a LibAFL-based fuzzer.""" + +import os +import subprocess + +from fuzzers import utils + + +def prepare_fuzz_environment(input_corpus): + """Prepare to fuzz with a LibAFL-based fuzzer.""" + os.environ['ASAN_OPTIONS'] = 'abort_on_error=1:detect_leaks=0:'\ + 'malloc_context_size=0:symbolize=0:'\ + 'allocator_may_return_null=1:'\ + 'detect_odr_violation=0:handle_segv=0:'\ + 'handle_sigbus=0:handle_abort=0:'\ + 'handle_sigfpe=0:handle_sigill=0' + os.environ['UBSAN_OPTIONS'] = 'abort_on_error=1:'\ + 'allocator_release_to_os_interval_ms=500:'\ + 'handle_abort=0:handle_segv=0:'\ + 'handle_sigbus=0:handle_sigfpe=0:'\ + 'handle_sigill=0:print_stacktrace=0:'\ + 'symbolize=0:symbolize_inline_frames=0' + # Create at least one non-empty seed to start. + utils.create_seed_file_for_empty_corpus(input_corpus) + + +def build(): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + os.environ['CC'] = ('/libafl/fuzzers/inprocess/fuzzbench' + '/target/release-fuzzbench/libafl_cc') + os.environ['CXX'] = ('/libafl/fuzzers/inprocess/fuzzbench' + '/target/release-fuzzbench/libafl_cxx') + + os.environ['ASAN_OPTIONS'] = 'abort_on_error=0:allocator_may_return_null=1' + os.environ['UBSAN_OPTIONS'] = 'abort_on_error=0' + + cflags = ['--libafl'] + cxxflags = ['--libafl', '--std=c++14'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cxxflags) + utils.append_flags('LDFLAGS', cflags) + + os.environ['FUZZER_LIB'] = '/stub_rt.a' + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + prepare_fuzz_environment(input_corpus) + dictionary_path = utils.get_dictionary_path(target_binary) + command = [target_binary] + if dictionary_path: + command += (['-x', dictionary_path]) + command += (['-o', output_corpus, '-i', input_corpus]) + fuzzer_env = os.environ.copy() + fuzzer_env['LD_PRELOAD'] = '/usr/lib/x86_64-linux-gnu/libjemalloc.so.2' + print(command) + subprocess.check_call(command, cwd=os.environ['OUT'], env=fuzzer_env) diff --git a/fuzzers/aflplusplus_um_prioritize_75/runner.Dockerfile b/fuzzers/libafl_fixseed0/runner.Dockerfile similarity index 96% rename from fuzzers/aflplusplus_um_prioritize_75/runner.Dockerfile rename to fuzzers/libafl_fixseed0/runner.Dockerfile index 7aa1da8e4..f0c5eb6cc 100644 --- a/fuzzers/aflplusplus_um_prioritize_75/runner.Dockerfile +++ b/fuzzers/libafl_fixseed0/runner.Dockerfile @@ -14,6 +14,8 @@ 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 diff --git a/fuzzers/libafl_fixseed1/builder.Dockerfile b/fuzzers/libafl_fixseed1/builder.Dockerfile new file mode 100644 index 000000000..4e0c56dd6 --- /dev/null +++ b/fuzzers/libafl_fixseed1/builder.Dockerfile @@ -0,0 +1,54 @@ +# 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-2025-04-01 -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 + +# Download libafl. +RUN git clone https://github.com/AFLplusplus/LibAFL /libafl + +# Checkout a current commit +RUN cd /libafl && git pull && git checkout a541fc27d2579bb9c24c533b2ca35dcacc647c90 || 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/inprocess/fuzzbench && \ + PATH="/root/.cargo/bin/:$PATH" cargo build --profile release-fuzzbench --features no_link_main + +# Auxiliary weak references. +RUN cd /libafl/fuzzers/inprocess/fuzzbench && \ + clang -c stub_rt.c && \ + ar r /stub_rt.a stub_rt.o diff --git a/fuzzers/libafl_fixseed1/description.md b/fuzzers/libafl_fixseed1/description.md new file mode 100644 index 000000000..ea9b947d6 --- /dev/null +++ b/fuzzers/libafl_fixseed1/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/libafl_fixseed1/fuzzer.py b/fuzzers/libafl_fixseed1/fuzzer.py new file mode 100755 index 000000000..fbe55aa5e --- /dev/null +++ b/fuzzers/libafl_fixseed1/fuzzer.py @@ -0,0 +1,72 @@ +# 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 a LibAFL-based fuzzer.""" + +import os +import subprocess + +from fuzzers import utils + + +def prepare_fuzz_environment(input_corpus): + """Prepare to fuzz with a LibAFL-based fuzzer.""" + os.environ['ASAN_OPTIONS'] = 'abort_on_error=1:detect_leaks=0:'\ + 'malloc_context_size=0:symbolize=0:'\ + 'allocator_may_return_null=1:'\ + 'detect_odr_violation=0:handle_segv=0:'\ + 'handle_sigbus=0:handle_abort=0:'\ + 'handle_sigfpe=0:handle_sigill=0' + os.environ['UBSAN_OPTIONS'] = 'abort_on_error=1:'\ + 'allocator_release_to_os_interval_ms=500:'\ + 'handle_abort=0:handle_segv=0:'\ + 'handle_sigbus=0:handle_sigfpe=0:'\ + 'handle_sigill=0:print_stacktrace=0:'\ + 'symbolize=0:symbolize_inline_frames=0' + # Create at least one non-empty seed to start. + utils.create_seed_file_for_empty_corpus(input_corpus) + + +def build(): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + os.environ['CC'] = ('/libafl/fuzzers/inprocess/fuzzbench' + '/target/release-fuzzbench/libafl_cc') + os.environ['CXX'] = ('/libafl/fuzzers/inprocess/fuzzbench' + '/target/release-fuzzbench/libafl_cxx') + + os.environ['ASAN_OPTIONS'] = 'abort_on_error=0:allocator_may_return_null=1' + os.environ['UBSAN_OPTIONS'] = 'abort_on_error=0' + + cflags = ['--libafl'] + cxxflags = ['--libafl', '--std=c++14'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cxxflags) + utils.append_flags('LDFLAGS', cflags) + + os.environ['FUZZER_LIB'] = '/stub_rt.a' + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + prepare_fuzz_environment(input_corpus) + dictionary_path = utils.get_dictionary_path(target_binary) + command = [target_binary] + if dictionary_path: + command += (['-x', dictionary_path]) + command += (['-o', output_corpus, '-i', input_corpus]) + fuzzer_env = os.environ.copy() + fuzzer_env['LD_PRELOAD'] = '/usr/lib/x86_64-linux-gnu/libjemalloc.so.2' + print(command) + subprocess.check_call(command, cwd=os.environ['OUT'], env=fuzzer_env) diff --git a/fuzzers/aflplusplus_um_prioritize/runner.Dockerfile b/fuzzers/libafl_fixseed1/runner.Dockerfile similarity index 96% rename from fuzzers/aflplusplus_um_prioritize/runner.Dockerfile rename to fuzzers/libafl_fixseed1/runner.Dockerfile index 7aa1da8e4..f0c5eb6cc 100644 --- a/fuzzers/aflplusplus_um_prioritize/runner.Dockerfile +++ b/fuzzers/libafl_fixseed1/runner.Dockerfile @@ -14,6 +14,8 @@ 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 diff --git a/fuzzers/libafl_fixseed2/builder.Dockerfile b/fuzzers/libafl_fixseed2/builder.Dockerfile new file mode 100644 index 000000000..4e0c56dd6 --- /dev/null +++ b/fuzzers/libafl_fixseed2/builder.Dockerfile @@ -0,0 +1,54 @@ +# 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-2025-04-01 -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 + +# Download libafl. +RUN git clone https://github.com/AFLplusplus/LibAFL /libafl + +# Checkout a current commit +RUN cd /libafl && git pull && git checkout a541fc27d2579bb9c24c533b2ca35dcacc647c90 || 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/inprocess/fuzzbench && \ + PATH="/root/.cargo/bin/:$PATH" cargo build --profile release-fuzzbench --features no_link_main + +# Auxiliary weak references. +RUN cd /libafl/fuzzers/inprocess/fuzzbench && \ + clang -c stub_rt.c && \ + ar r /stub_rt.a stub_rt.o diff --git a/fuzzers/libafl_fixseed2/description.md b/fuzzers/libafl_fixseed2/description.md new file mode 100644 index 000000000..ea9b947d6 --- /dev/null +++ b/fuzzers/libafl_fixseed2/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/libafl_fixseed2/fuzzer.py b/fuzzers/libafl_fixseed2/fuzzer.py new file mode 100755 index 000000000..fbe55aa5e --- /dev/null +++ b/fuzzers/libafl_fixseed2/fuzzer.py @@ -0,0 +1,72 @@ +# 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 a LibAFL-based fuzzer.""" + +import os +import subprocess + +from fuzzers import utils + + +def prepare_fuzz_environment(input_corpus): + """Prepare to fuzz with a LibAFL-based fuzzer.""" + os.environ['ASAN_OPTIONS'] = 'abort_on_error=1:detect_leaks=0:'\ + 'malloc_context_size=0:symbolize=0:'\ + 'allocator_may_return_null=1:'\ + 'detect_odr_violation=0:handle_segv=0:'\ + 'handle_sigbus=0:handle_abort=0:'\ + 'handle_sigfpe=0:handle_sigill=0' + os.environ['UBSAN_OPTIONS'] = 'abort_on_error=1:'\ + 'allocator_release_to_os_interval_ms=500:'\ + 'handle_abort=0:handle_segv=0:'\ + 'handle_sigbus=0:handle_sigfpe=0:'\ + 'handle_sigill=0:print_stacktrace=0:'\ + 'symbolize=0:symbolize_inline_frames=0' + # Create at least one non-empty seed to start. + utils.create_seed_file_for_empty_corpus(input_corpus) + + +def build(): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + os.environ['CC'] = ('/libafl/fuzzers/inprocess/fuzzbench' + '/target/release-fuzzbench/libafl_cc') + os.environ['CXX'] = ('/libafl/fuzzers/inprocess/fuzzbench' + '/target/release-fuzzbench/libafl_cxx') + + os.environ['ASAN_OPTIONS'] = 'abort_on_error=0:allocator_may_return_null=1' + os.environ['UBSAN_OPTIONS'] = 'abort_on_error=0' + + cflags = ['--libafl'] + cxxflags = ['--libafl', '--std=c++14'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cxxflags) + utils.append_flags('LDFLAGS', cflags) + + os.environ['FUZZER_LIB'] = '/stub_rt.a' + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + prepare_fuzz_environment(input_corpus) + dictionary_path = utils.get_dictionary_path(target_binary) + command = [target_binary] + if dictionary_path: + command += (['-x', dictionary_path]) + command += (['-o', output_corpus, '-i', input_corpus]) + fuzzer_env = os.environ.copy() + fuzzer_env['LD_PRELOAD'] = '/usr/lib/x86_64-linux-gnu/libjemalloc.so.2' + print(command) + subprocess.check_call(command, cwd=os.environ['OUT'], env=fuzzer_env) diff --git a/fuzzers/aflplusplus_um_random/runner.Dockerfile b/fuzzers/libafl_fixseed2/runner.Dockerfile similarity index 96% rename from fuzzers/aflplusplus_um_random/runner.Dockerfile rename to fuzzers/libafl_fixseed2/runner.Dockerfile index 7aa1da8e4..f0c5eb6cc 100644 --- a/fuzzers/aflplusplus_um_random/runner.Dockerfile +++ b/fuzzers/libafl_fixseed2/runner.Dockerfile @@ -14,6 +14,8 @@ 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 diff --git a/fuzzers/libafl_fixseed3/builder.Dockerfile b/fuzzers/libafl_fixseed3/builder.Dockerfile new file mode 100644 index 000000000..4e0c56dd6 --- /dev/null +++ b/fuzzers/libafl_fixseed3/builder.Dockerfile @@ -0,0 +1,54 @@ +# 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-2025-04-01 -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 + +# Download libafl. +RUN git clone https://github.com/AFLplusplus/LibAFL /libafl + +# Checkout a current commit +RUN cd /libafl && git pull && git checkout a541fc27d2579bb9c24c533b2ca35dcacc647c90 || 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/inprocess/fuzzbench && \ + PATH="/root/.cargo/bin/:$PATH" cargo build --profile release-fuzzbench --features no_link_main + +# Auxiliary weak references. +RUN cd /libafl/fuzzers/inprocess/fuzzbench && \ + clang -c stub_rt.c && \ + ar r /stub_rt.a stub_rt.o diff --git a/fuzzers/libafl_fixseed3/description.md b/fuzzers/libafl_fixseed3/description.md new file mode 100644 index 000000000..ea9b947d6 --- /dev/null +++ b/fuzzers/libafl_fixseed3/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/libafl_fixseed3/fuzzer.py b/fuzzers/libafl_fixseed3/fuzzer.py new file mode 100755 index 000000000..fbe55aa5e --- /dev/null +++ b/fuzzers/libafl_fixseed3/fuzzer.py @@ -0,0 +1,72 @@ +# 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 a LibAFL-based fuzzer.""" + +import os +import subprocess + +from fuzzers import utils + + +def prepare_fuzz_environment(input_corpus): + """Prepare to fuzz with a LibAFL-based fuzzer.""" + os.environ['ASAN_OPTIONS'] = 'abort_on_error=1:detect_leaks=0:'\ + 'malloc_context_size=0:symbolize=0:'\ + 'allocator_may_return_null=1:'\ + 'detect_odr_violation=0:handle_segv=0:'\ + 'handle_sigbus=0:handle_abort=0:'\ + 'handle_sigfpe=0:handle_sigill=0' + os.environ['UBSAN_OPTIONS'] = 'abort_on_error=1:'\ + 'allocator_release_to_os_interval_ms=500:'\ + 'handle_abort=0:handle_segv=0:'\ + 'handle_sigbus=0:handle_sigfpe=0:'\ + 'handle_sigill=0:print_stacktrace=0:'\ + 'symbolize=0:symbolize_inline_frames=0' + # Create at least one non-empty seed to start. + utils.create_seed_file_for_empty_corpus(input_corpus) + + +def build(): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + os.environ['CC'] = ('/libafl/fuzzers/inprocess/fuzzbench' + '/target/release-fuzzbench/libafl_cc') + os.environ['CXX'] = ('/libafl/fuzzers/inprocess/fuzzbench' + '/target/release-fuzzbench/libafl_cxx') + + os.environ['ASAN_OPTIONS'] = 'abort_on_error=0:allocator_may_return_null=1' + os.environ['UBSAN_OPTIONS'] = 'abort_on_error=0' + + cflags = ['--libafl'] + cxxflags = ['--libafl', '--std=c++14'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cxxflags) + utils.append_flags('LDFLAGS', cflags) + + os.environ['FUZZER_LIB'] = '/stub_rt.a' + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + prepare_fuzz_environment(input_corpus) + dictionary_path = utils.get_dictionary_path(target_binary) + command = [target_binary] + if dictionary_path: + command += (['-x', dictionary_path]) + command += (['-o', output_corpus, '-i', input_corpus]) + fuzzer_env = os.environ.copy() + fuzzer_env['LD_PRELOAD'] = '/usr/lib/x86_64-linux-gnu/libjemalloc.so.2' + print(command) + subprocess.check_call(command, cwd=os.environ['OUT'], env=fuzzer_env) diff --git a/fuzzers/aflplusplus_um_parallel/runner.Dockerfile b/fuzzers/libafl_fixseed3/runner.Dockerfile similarity index 96% rename from fuzzers/aflplusplus_um_parallel/runner.Dockerfile rename to fuzzers/libafl_fixseed3/runner.Dockerfile index 7aa1da8e4..f0c5eb6cc 100644 --- a/fuzzers/aflplusplus_um_parallel/runner.Dockerfile +++ b/fuzzers/libafl_fixseed3/runner.Dockerfile @@ -14,6 +14,8 @@ 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 diff --git a/fuzzers/libafl_fixseed4/builder.Dockerfile b/fuzzers/libafl_fixseed4/builder.Dockerfile new file mode 100644 index 000000000..4e0c56dd6 --- /dev/null +++ b/fuzzers/libafl_fixseed4/builder.Dockerfile @@ -0,0 +1,54 @@ +# 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-2025-04-01 -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 + +# Download libafl. +RUN git clone https://github.com/AFLplusplus/LibAFL /libafl + +# Checkout a current commit +RUN cd /libafl && git pull && git checkout a541fc27d2579bb9c24c533b2ca35dcacc647c90 || 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/inprocess/fuzzbench && \ + PATH="/root/.cargo/bin/:$PATH" cargo build --profile release-fuzzbench --features no_link_main + +# Auxiliary weak references. +RUN cd /libafl/fuzzers/inprocess/fuzzbench && \ + clang -c stub_rt.c && \ + ar r /stub_rt.a stub_rt.o diff --git a/fuzzers/libafl_fixseed4/description.md b/fuzzers/libafl_fixseed4/description.md new file mode 100644 index 000000000..ea9b947d6 --- /dev/null +++ b/fuzzers/libafl_fixseed4/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/libafl_fixseed4/fuzzer.py b/fuzzers/libafl_fixseed4/fuzzer.py new file mode 100755 index 000000000..fbe55aa5e --- /dev/null +++ b/fuzzers/libafl_fixseed4/fuzzer.py @@ -0,0 +1,72 @@ +# 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 a LibAFL-based fuzzer.""" + +import os +import subprocess + +from fuzzers import utils + + +def prepare_fuzz_environment(input_corpus): + """Prepare to fuzz with a LibAFL-based fuzzer.""" + os.environ['ASAN_OPTIONS'] = 'abort_on_error=1:detect_leaks=0:'\ + 'malloc_context_size=0:symbolize=0:'\ + 'allocator_may_return_null=1:'\ + 'detect_odr_violation=0:handle_segv=0:'\ + 'handle_sigbus=0:handle_abort=0:'\ + 'handle_sigfpe=0:handle_sigill=0' + os.environ['UBSAN_OPTIONS'] = 'abort_on_error=1:'\ + 'allocator_release_to_os_interval_ms=500:'\ + 'handle_abort=0:handle_segv=0:'\ + 'handle_sigbus=0:handle_sigfpe=0:'\ + 'handle_sigill=0:print_stacktrace=0:'\ + 'symbolize=0:symbolize_inline_frames=0' + # Create at least one non-empty seed to start. + utils.create_seed_file_for_empty_corpus(input_corpus) + + +def build(): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + os.environ['CC'] = ('/libafl/fuzzers/inprocess/fuzzbench' + '/target/release-fuzzbench/libafl_cc') + os.environ['CXX'] = ('/libafl/fuzzers/inprocess/fuzzbench' + '/target/release-fuzzbench/libafl_cxx') + + os.environ['ASAN_OPTIONS'] = 'abort_on_error=0:allocator_may_return_null=1' + os.environ['UBSAN_OPTIONS'] = 'abort_on_error=0' + + cflags = ['--libafl'] + cxxflags = ['--libafl', '--std=c++14'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cxxflags) + utils.append_flags('LDFLAGS', cflags) + + os.environ['FUZZER_LIB'] = '/stub_rt.a' + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + prepare_fuzz_environment(input_corpus) + dictionary_path = utils.get_dictionary_path(target_binary) + command = [target_binary] + if dictionary_path: + command += (['-x', dictionary_path]) + command += (['-o', output_corpus, '-i', input_corpus]) + fuzzer_env = os.environ.copy() + fuzzer_env['LD_PRELOAD'] = '/usr/lib/x86_64-linux-gnu/libjemalloc.so.2' + print(command) + subprocess.check_call(command, cwd=os.environ['OUT'], env=fuzzer_env) diff --git a/fuzzers/libafl_fixseed4/runner.Dockerfile b/fuzzers/libafl_fixseed4/runner.Dockerfile new file mode 100644 index 000000000..f0c5eb6cc --- /dev/null +++ b/fuzzers/libafl_fixseed4/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/libafl_fuzz/builder.Dockerfile b/fuzzers/libafl_fuzz/builder.Dockerfile new file mode 100644 index 000000000..1f87ca5f2 --- /dev/null +++ b/fuzzers/libafl_fuzz/builder.Dockerfile @@ -0,0 +1,56 @@ +# 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 dependencies. +RUN apt-get update && \ + apt-get install -y build-essential libstdc++5 libtool-bin automake flex \ + bison libglib2.0-dev python3-setuptools unzip python3-dev joe curl \ + cmake git apt-utils apt-transport-https ca-certificates libdbus-1-dev + +# 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-11-25 -y && \ + rm /rustup.sh + +# Download afl++. +RUN git clone https://github.com/AFLplusplus/AFLplusplus /afl + +# Checkout a current commit +RUN cd /afl && git pull && git checkout 5777ceaf23f48ae4ceae60e4f3a79263802633c6 + +# Build without Python support as we don't need it. +# Set AFL_NO_X86 to skip flaky tests. +RUN cd /afl && \ + unset CFLAGS CXXFLAGS && \ + export CC=clang AFL_NO_X86=1 AFL_PATH=/afl && \ + PYTHON_INCLUDE=/ make && \ + make install && \ + cp utils/aflpp_driver/libAFLDriver.a / + +# Download libafl. +RUN git clone https://github.com/AFLplusplus/LibAFL /libafl + +# Checkout a current commit +RUN cd /libafl && git pull + +# Compile libafl. +RUN cd /libafl && \ + unset CFLAGS CXXFLAGS && \ + cd ./fuzzers/forkserver/libafl-fuzz && \ + PATH="/root/.cargo/bin/:$PATH" cargo build --profile release --features fuzzbench + diff --git a/fuzzers/libafl_fuzz/fuzzer.py b/fuzzers/libafl_fuzz/fuzzer.py new file mode 100644 index 000000000..46e31124e --- /dev/null +++ b/fuzzers/libafl_fuzz/fuzzer.py @@ -0,0 +1,73 @@ +# 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 libafl-fuzz; Dervied from AFLRustRust""" + +import os +import shutil +import subprocess + +from fuzzers import utils +from fuzzers.aflplusplus import fuzzer as aflplusplus_fuzzer +from fuzzers.libafl import fuzzer as libafl_fuzzer + + +def build(): + """Build benchmark.""" + # Build the target with AFL++ + aflplusplus_fuzzer.build('tracepc', 'cmplog', 'dict2file') + + # Copy to fuzzer to OUT + build_directory = os.environ['OUT'] + fuzzer = '/libafl/fuzzers/forkserver/libafl-fuzz/target/release/libafl-fuzz' + shutil.copy(fuzzer, build_directory) + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + # Calculate CmpLog binary path from the instrumented target binary. + target_binary_directory = os.path.dirname(target_binary) + cmplog_target_binary_directory = \ + aflplusplus_fuzzer.get_cmplog_build_directory(target_binary_directory) + target_binary_name = os.path.basename(target_binary) + cmplog_target_binary = os.path.join(cmplog_target_binary_directory, + target_binary_name) + + # Setup env vars + libafl_fuzzer.prepare_fuzz_environment(input_corpus) + + # Merge dictionaries + dictionary_path = utils.get_dictionary_path(target_binary) + if os.path.exists('./afl++.dict'): + if dictionary_path: + with open('./afl++.dict', encoding='utf-8') as dictfile: + autodict = dictfile.read() + with open(dictionary_path, 'a', encoding='utf-8') as dictfile: + dictfile.write(autodict) + else: + dictionary_path = './afl++.dict' + + # Run the fuzzer + command = ['./libafl-fuzz', '-c', cmplog_target_binary] + if dictionary_path: + command += (['-x', dictionary_path]) + command += (['-o', output_corpus, '-i', input_corpus, target_binary]) + command += (['-t', '1000']) + print(command) + env = { + 'AFL_CORES': '0', + 'AFL_IGNORE_TIMEOUT': '1', + 'AFL_MAP_SIZE': '2621440', + 'AFL_CMPLOG_ONLY_NEW': '1' + } + subprocess.check_call(command, cwd=os.environ['OUT'], env=env) diff --git a/fuzzers/libafl_fuzz/runner.Dockerfile b/fuzzers/libafl_fuzz/runner.Dockerfile new file mode 100644 index 000000000..6ffb9eb24 --- /dev/null +++ b/fuzzers/libafl_fuzz/runner.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. + +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 upgrade && apt install -y unzip git gdb joe +RUN apt install libjemalloc2 + diff --git a/fuzzers/libafl_grimoire/builder.Dockerfile b/fuzzers/libafl_grimoire/builder.Dockerfile new file mode 100644 index 000000000..2db39faf5 --- /dev/null +++ b/fuzzers/libafl_grimoire/builder.Dockerfile @@ -0,0 +1,53 @@ +# 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-2024-08-12 -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 + + +# Download libafl +RUN git clone https://github.com/AFLplusplus/libafl_fuzzbench /libafl_fuzzbench && \ + cd /libafl_fuzzbench && \ + git checkout 876f383339a78415b402ddba0829bf2448be202a && \ + git submodule update --init + +# Compile libafl +RUN cd /libafl_fuzzbench/ && unset CFLAGS && unset CXXFLAGS && \ + export CC=clang && export CXX=clang++ && \ + export LIBAFL_EDGES_MAP_SIZE=65536 && \ + PATH="/root/.cargo/bin/:$PATH" cargo build --release --features no_link_main + +# Auxiliary weak references. +RUN cd /libafl_fuzzbench && \ + clang -c stub_rt.c && \ + ar r /stub_rt.a stub_rt.o diff --git a/fuzzers/libafl_grimoire/description.md b/fuzzers/libafl_grimoire/description.md new file mode 100644 index 000000000..ea9b947d6 --- /dev/null +++ b/fuzzers/libafl_grimoire/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/libafl_grimoire/fuzzer.py b/fuzzers/libafl_grimoire/fuzzer.py new file mode 100755 index 000000000..5199af27a --- /dev/null +++ b/fuzzers/libafl_grimoire/fuzzer.py @@ -0,0 +1,70 @@ +# 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 a LibAFL-based fuzzer.""" + +import os +import subprocess + +from fuzzers import utils + + +def prepare_fuzz_environment(input_corpus): + """Prepare to fuzz with a LibAFL-based fuzzer.""" + os.environ['ASAN_OPTIONS'] = 'abort_on_error=1:detect_leaks=0:'\ + 'malloc_context_size=0:symbolize=0:'\ + 'allocator_may_return_null=1:'\ + 'detect_odr_violation=0:handle_segv=0:'\ + 'handle_sigbus=0:handle_abort=0:'\ + 'handle_sigfpe=0:handle_sigill=0' + os.environ['UBSAN_OPTIONS'] = 'abort_on_error=1:'\ + 'allocator_release_to_os_interval_ms=500:'\ + 'handle_abort=0:handle_segv=0:'\ + 'handle_sigbus=0:handle_sigfpe=0:'\ + 'handle_sigill=0:print_stacktrace=0:'\ + 'symbolize=0:symbolize_inline_frames=0' + # Create at least one non-empty seed to start. + utils.create_seed_file_for_empty_corpus(input_corpus) + + +def build(): # pylint: disable=too-many-branches,too-many-statements + """Build benchmark.""" + os.environ['CC'] = '/libafl_fuzzbench/target/release/grimoire_cc' + os.environ['CXX'] = '/libafl_fuzzbench/target/release/grimoire_cxx' + + os.environ['ASAN_OPTIONS'] = 'abort_on_error=0:allocator_may_return_null=1' + os.environ['UBSAN_OPTIONS'] = 'abort_on_error=0' + + cflags = ['--libafl'] + cxxflags = ['--libafl', '--std=c++14'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cxxflags) + utils.append_flags('LDFLAGS', cflags) + + os.environ['FUZZER_LIB'] = '/stub_rt.a' + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + prepare_fuzz_environment(input_corpus) + dictionary_path = utils.get_dictionary_path(target_binary) + command = [target_binary] + if dictionary_path: + command += (['-x', dictionary_path]) + command += (['-o', output_corpus, '-i', input_corpus]) + fuzzer_env = os.environ.copy() + fuzzer_env['LD_PRELOAD'] = '/usr/lib/x86_64-linux-gnu/libjemalloc.so.2' + print(command) + subprocess.check_call(command, cwd=os.environ['OUT'], env=fuzzer_env) diff --git a/fuzzers/libafl_grimoire/runner.Dockerfile b/fuzzers/libafl_grimoire/runner.Dockerfile new file mode 100644 index 000000000..f0c5eb6cc --- /dev/null +++ b/fuzzers/libafl_grimoire/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_fixseed0/builder.Dockerfile b/fuzzers/libfuzzer_fixseed0/builder.Dockerfile new file mode 100644 index 000000000..7fe80447e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed0/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_fixseed0/fuzzer.py b/fuzzers/libfuzzer_fixseed0/fuzzer.py new file mode 100755 index 000000000..573eaf42c --- /dev/null +++ b/fuzzers/libfuzzer_fixseed0/fuzzer.py @@ -0,0 +1,103 @@ +# 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 libFuzzer fuzzer.""" + +import subprocess +import os + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # With LibFuzzer we use -fsanitize=fuzzer-no-link for build CFLAGS and then + # /usr/lib/libFuzzer.a as the FUZZER_LIB for the main fuzzing binary. This + # allows us to link against a version of LibFuzzer that we specify. + cflags = ['-fsanitize=fuzzer-no-link'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cflags) + + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + os.environ['FUZZER_LIB'] = '/usr/lib/libFuzzer.a' + + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer. Wrapper that uses the defaults when calling + run_fuzzer.""" + run_fuzzer(input_corpus, output_corpus, target_binary) + + +def run_fuzzer(input_corpus, output_corpus, target_binary, extra_flags=None): + """Run fuzzer.""" + if extra_flags is None: + extra_flags = [] + + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + # Enable symbolization if needed. + # Note: if the flags are like `symbolize=0:..:symbolize=1` then + # only symbolize=1 is respected. + for flag in extra_flags: + if flag.startswith('-focus_function'): + if 'ASAN_OPTIONS' in os.environ: + os.environ['ASAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['ASAN_OPTIONS'] = 'symbolize=1' + if 'UBSAN_OPTIONS' in os.environ: + os.environ['UBSAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['UBSAN_OPTIONS'] = 'symbolize=1' + break + + flags = [ + '-print_final_stats=1', + # `close_fd_mask` to prevent too much logging output from the target. + '-close_fd_mask=3', + '-seed=1', + # Run in fork mode to allow ignoring ooms, timeouts, crashes and + # continue fuzzing indefinitely. + '-fork=1', + '-ignore_ooms=1', + '-ignore_timeouts=1', + '-ignore_crashes=1', + '-entropic=1', + '-keep_seed=1', + '-cross_over_uniform_dist=1', + '-entropic_scale_per_exec_time=1', + + # Don't use LSAN's leak detection. Other fuzzers won't be using it and + # using it will cause libFuzzer to find "crashes" no one cares about. + '-detect_leaks=0', + + # Store crashes along with corpus for bug based benchmarking. + f'-artifact_prefix={crashes_dir}/', + ] + flags += extra_flags + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + flags.append('-dict=' + dictionary_path) + + command = [target_binary] + flags + [output_corpus, input_corpus] + print('[run_fuzzer] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/libfuzzer_fixseed0/patch.diff b/fuzzers/libfuzzer_fixseed0/patch.diff new file mode 100644 index 000000000..a31cc301e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed0/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_fixseed0/runner.Dockerfile b/fuzzers/libfuzzer_fixseed0/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed0/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 diff --git a/fuzzers/libfuzzer_fixseed1/builder.Dockerfile b/fuzzers/libfuzzer_fixseed1/builder.Dockerfile new file mode 100644 index 000000000..7fe80447e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed1/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_fixseed1/fuzzer.py b/fuzzers/libfuzzer_fixseed1/fuzzer.py new file mode 100755 index 000000000..573eaf42c --- /dev/null +++ b/fuzzers/libfuzzer_fixseed1/fuzzer.py @@ -0,0 +1,103 @@ +# 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 libFuzzer fuzzer.""" + +import subprocess +import os + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # With LibFuzzer we use -fsanitize=fuzzer-no-link for build CFLAGS and then + # /usr/lib/libFuzzer.a as the FUZZER_LIB for the main fuzzing binary. This + # allows us to link against a version of LibFuzzer that we specify. + cflags = ['-fsanitize=fuzzer-no-link'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cflags) + + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + os.environ['FUZZER_LIB'] = '/usr/lib/libFuzzer.a' + + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer. Wrapper that uses the defaults when calling + run_fuzzer.""" + run_fuzzer(input_corpus, output_corpus, target_binary) + + +def run_fuzzer(input_corpus, output_corpus, target_binary, extra_flags=None): + """Run fuzzer.""" + if extra_flags is None: + extra_flags = [] + + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + # Enable symbolization if needed. + # Note: if the flags are like `symbolize=0:..:symbolize=1` then + # only symbolize=1 is respected. + for flag in extra_flags: + if flag.startswith('-focus_function'): + if 'ASAN_OPTIONS' in os.environ: + os.environ['ASAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['ASAN_OPTIONS'] = 'symbolize=1' + if 'UBSAN_OPTIONS' in os.environ: + os.environ['UBSAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['UBSAN_OPTIONS'] = 'symbolize=1' + break + + flags = [ + '-print_final_stats=1', + # `close_fd_mask` to prevent too much logging output from the target. + '-close_fd_mask=3', + '-seed=1', + # Run in fork mode to allow ignoring ooms, timeouts, crashes and + # continue fuzzing indefinitely. + '-fork=1', + '-ignore_ooms=1', + '-ignore_timeouts=1', + '-ignore_crashes=1', + '-entropic=1', + '-keep_seed=1', + '-cross_over_uniform_dist=1', + '-entropic_scale_per_exec_time=1', + + # Don't use LSAN's leak detection. Other fuzzers won't be using it and + # using it will cause libFuzzer to find "crashes" no one cares about. + '-detect_leaks=0', + + # Store crashes along with corpus for bug based benchmarking. + f'-artifact_prefix={crashes_dir}/', + ] + flags += extra_flags + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + flags.append('-dict=' + dictionary_path) + + command = [target_binary] + flags + [output_corpus, input_corpus] + print('[run_fuzzer] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/libfuzzer_fixseed1/patch.diff b/fuzzers/libfuzzer_fixseed1/patch.diff new file mode 100644 index 000000000..a31cc301e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed1/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_fixseed1/runner.Dockerfile b/fuzzers/libfuzzer_fixseed1/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed1/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 diff --git a/fuzzers/libfuzzer_fixseed2/builder.Dockerfile b/fuzzers/libfuzzer_fixseed2/builder.Dockerfile new file mode 100644 index 000000000..7fe80447e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed2/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_fixseed2/fuzzer.py b/fuzzers/libfuzzer_fixseed2/fuzzer.py new file mode 100755 index 000000000..573eaf42c --- /dev/null +++ b/fuzzers/libfuzzer_fixseed2/fuzzer.py @@ -0,0 +1,103 @@ +# 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 libFuzzer fuzzer.""" + +import subprocess +import os + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # With LibFuzzer we use -fsanitize=fuzzer-no-link for build CFLAGS and then + # /usr/lib/libFuzzer.a as the FUZZER_LIB for the main fuzzing binary. This + # allows us to link against a version of LibFuzzer that we specify. + cflags = ['-fsanitize=fuzzer-no-link'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cflags) + + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + os.environ['FUZZER_LIB'] = '/usr/lib/libFuzzer.a' + + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer. Wrapper that uses the defaults when calling + run_fuzzer.""" + run_fuzzer(input_corpus, output_corpus, target_binary) + + +def run_fuzzer(input_corpus, output_corpus, target_binary, extra_flags=None): + """Run fuzzer.""" + if extra_flags is None: + extra_flags = [] + + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + # Enable symbolization if needed. + # Note: if the flags are like `symbolize=0:..:symbolize=1` then + # only symbolize=1 is respected. + for flag in extra_flags: + if flag.startswith('-focus_function'): + if 'ASAN_OPTIONS' in os.environ: + os.environ['ASAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['ASAN_OPTIONS'] = 'symbolize=1' + if 'UBSAN_OPTIONS' in os.environ: + os.environ['UBSAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['UBSAN_OPTIONS'] = 'symbolize=1' + break + + flags = [ + '-print_final_stats=1', + # `close_fd_mask` to prevent too much logging output from the target. + '-close_fd_mask=3', + '-seed=1', + # Run in fork mode to allow ignoring ooms, timeouts, crashes and + # continue fuzzing indefinitely. + '-fork=1', + '-ignore_ooms=1', + '-ignore_timeouts=1', + '-ignore_crashes=1', + '-entropic=1', + '-keep_seed=1', + '-cross_over_uniform_dist=1', + '-entropic_scale_per_exec_time=1', + + # Don't use LSAN's leak detection. Other fuzzers won't be using it and + # using it will cause libFuzzer to find "crashes" no one cares about. + '-detect_leaks=0', + + # Store crashes along with corpus for bug based benchmarking. + f'-artifact_prefix={crashes_dir}/', + ] + flags += extra_flags + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + flags.append('-dict=' + dictionary_path) + + command = [target_binary] + flags + [output_corpus, input_corpus] + print('[run_fuzzer] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/libfuzzer_fixseed2/patch.diff b/fuzzers/libfuzzer_fixseed2/patch.diff new file mode 100644 index 000000000..a31cc301e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed2/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_fixseed2/runner.Dockerfile b/fuzzers/libfuzzer_fixseed2/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed2/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 diff --git a/fuzzers/libfuzzer_fixseed3/builder.Dockerfile b/fuzzers/libfuzzer_fixseed3/builder.Dockerfile new file mode 100644 index 000000000..7fe80447e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed3/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_fixseed3/fuzzer.py b/fuzzers/libfuzzer_fixseed3/fuzzer.py new file mode 100755 index 000000000..573eaf42c --- /dev/null +++ b/fuzzers/libfuzzer_fixseed3/fuzzer.py @@ -0,0 +1,103 @@ +# 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 libFuzzer fuzzer.""" + +import subprocess +import os + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # With LibFuzzer we use -fsanitize=fuzzer-no-link for build CFLAGS and then + # /usr/lib/libFuzzer.a as the FUZZER_LIB for the main fuzzing binary. This + # allows us to link against a version of LibFuzzer that we specify. + cflags = ['-fsanitize=fuzzer-no-link'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cflags) + + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + os.environ['FUZZER_LIB'] = '/usr/lib/libFuzzer.a' + + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer. Wrapper that uses the defaults when calling + run_fuzzer.""" + run_fuzzer(input_corpus, output_corpus, target_binary) + + +def run_fuzzer(input_corpus, output_corpus, target_binary, extra_flags=None): + """Run fuzzer.""" + if extra_flags is None: + extra_flags = [] + + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + # Enable symbolization if needed. + # Note: if the flags are like `symbolize=0:..:symbolize=1` then + # only symbolize=1 is respected. + for flag in extra_flags: + if flag.startswith('-focus_function'): + if 'ASAN_OPTIONS' in os.environ: + os.environ['ASAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['ASAN_OPTIONS'] = 'symbolize=1' + if 'UBSAN_OPTIONS' in os.environ: + os.environ['UBSAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['UBSAN_OPTIONS'] = 'symbolize=1' + break + + flags = [ + '-print_final_stats=1', + # `close_fd_mask` to prevent too much logging output from the target. + '-close_fd_mask=3', + '-seed=1', + # Run in fork mode to allow ignoring ooms, timeouts, crashes and + # continue fuzzing indefinitely. + '-fork=1', + '-ignore_ooms=1', + '-ignore_timeouts=1', + '-ignore_crashes=1', + '-entropic=1', + '-keep_seed=1', + '-cross_over_uniform_dist=1', + '-entropic_scale_per_exec_time=1', + + # Don't use LSAN's leak detection. Other fuzzers won't be using it and + # using it will cause libFuzzer to find "crashes" no one cares about. + '-detect_leaks=0', + + # Store crashes along with corpus for bug based benchmarking. + f'-artifact_prefix={crashes_dir}/', + ] + flags += extra_flags + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + flags.append('-dict=' + dictionary_path) + + command = [target_binary] + flags + [output_corpus, input_corpus] + print('[run_fuzzer] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/libfuzzer_fixseed3/patch.diff b/fuzzers/libfuzzer_fixseed3/patch.diff new file mode 100644 index 000000000..a31cc301e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed3/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_fixseed3/runner.Dockerfile b/fuzzers/libfuzzer_fixseed3/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed3/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 diff --git a/fuzzers/libfuzzer_fixseed4/builder.Dockerfile b/fuzzers/libfuzzer_fixseed4/builder.Dockerfile new file mode 100644 index 000000000..7fe80447e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed4/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_fixseed4/fuzzer.py b/fuzzers/libfuzzer_fixseed4/fuzzer.py new file mode 100755 index 000000000..573eaf42c --- /dev/null +++ b/fuzzers/libfuzzer_fixseed4/fuzzer.py @@ -0,0 +1,103 @@ +# 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 libFuzzer fuzzer.""" + +import subprocess +import os + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # With LibFuzzer we use -fsanitize=fuzzer-no-link for build CFLAGS and then + # /usr/lib/libFuzzer.a as the FUZZER_LIB for the main fuzzing binary. This + # allows us to link against a version of LibFuzzer that we specify. + cflags = ['-fsanitize=fuzzer-no-link'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cflags) + + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + os.environ['FUZZER_LIB'] = '/usr/lib/libFuzzer.a' + + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer. Wrapper that uses the defaults when calling + run_fuzzer.""" + run_fuzzer(input_corpus, output_corpus, target_binary) + + +def run_fuzzer(input_corpus, output_corpus, target_binary, extra_flags=None): + """Run fuzzer.""" + if extra_flags is None: + extra_flags = [] + + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + # Enable symbolization if needed. + # Note: if the flags are like `symbolize=0:..:symbolize=1` then + # only symbolize=1 is respected. + for flag in extra_flags: + if flag.startswith('-focus_function'): + if 'ASAN_OPTIONS' in os.environ: + os.environ['ASAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['ASAN_OPTIONS'] = 'symbolize=1' + if 'UBSAN_OPTIONS' in os.environ: + os.environ['UBSAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['UBSAN_OPTIONS'] = 'symbolize=1' + break + + flags = [ + '-print_final_stats=1', + # `close_fd_mask` to prevent too much logging output from the target. + '-close_fd_mask=3', + '-seed=1', + # Run in fork mode to allow ignoring ooms, timeouts, crashes and + # continue fuzzing indefinitely. + '-fork=1', + '-ignore_ooms=1', + '-ignore_timeouts=1', + '-ignore_crashes=1', + '-entropic=1', + '-keep_seed=1', + '-cross_over_uniform_dist=1', + '-entropic_scale_per_exec_time=1', + + # Don't use LSAN's leak detection. Other fuzzers won't be using it and + # using it will cause libFuzzer to find "crashes" no one cares about. + '-detect_leaks=0', + + # Store crashes along with corpus for bug based benchmarking. + f'-artifact_prefix={crashes_dir}/', + ] + flags += extra_flags + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + flags.append('-dict=' + dictionary_path) + + command = [target_binary] + flags + [output_corpus, input_corpus] + print('[run_fuzzer] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/libfuzzer_fixseed4/patch.diff b/fuzzers/libfuzzer_fixseed4/patch.diff new file mode 100644 index 000000000..a31cc301e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed4/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_fixseed4/runner.Dockerfile b/fuzzers/libfuzzer_fixseed4/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/libfuzzer_fixseed4/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 diff --git a/fuzzers/libfuzzer_t0/builder.Dockerfile b/fuzzers/libfuzzer_t0/builder.Dockerfile new file mode 100644 index 000000000..7fe80447e --- /dev/null +++ b/fuzzers/libfuzzer_t0/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_t0/fuzzer.py b/fuzzers/libfuzzer_t0/fuzzer.py new file mode 100755 index 000000000..78a1e2f8f --- /dev/null +++ b/fuzzers/libfuzzer_t0/fuzzer.py @@ -0,0 +1,102 @@ +# 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 libFuzzer fuzzer.""" + +import subprocess +import os + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # With LibFuzzer we use -fsanitize=fuzzer-no-link for build CFLAGS and then + # /usr/lib/libFuzzer.a as the FUZZER_LIB for the main fuzzing binary. This + # allows us to link against a version of LibFuzzer that we specify. + cflags = ['-fsanitize=fuzzer-no-link'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cflags) + + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + os.environ['FUZZER_LIB'] = '/usr/lib/libFuzzer.a' + + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer. Wrapper that uses the defaults when calling + run_fuzzer.""" + run_fuzzer(input_corpus, output_corpus, target_binary) + + +def run_fuzzer(input_corpus, output_corpus, target_binary, extra_flags=None): + """Run fuzzer.""" + if extra_flags is None: + extra_flags = [] + + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + # Enable symbolization if needed. + # Note: if the flags are like `symbolize=0:..:symbolize=1` then + # only symbolize=1 is respected. + for flag in extra_flags: + if flag.startswith('-focus_function'): + if 'ASAN_OPTIONS' in os.environ: + os.environ['ASAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['ASAN_OPTIONS'] = 'symbolize=1' + if 'UBSAN_OPTIONS' in os.environ: + os.environ['UBSAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['UBSAN_OPTIONS'] = 'symbolize=1' + break + + flags = [ + '-print_final_stats=1', + # `close_fd_mask` to prevent too much logging output from the target. + '-close_fd_mask=3', + # Run in fork mode to allow ignoring ooms, timeouts, crashes and + # continue fuzzing indefinitely. + '-fork=1', + '-ignore_ooms=1', + '-ignore_timeouts=1', + '-ignore_crashes=1', + '-entropic=1', + '-keep_seed=1', + '-cross_over_uniform_dist=1', + '-entropic_scale_per_exec_time=1', + + # Don't use LSAN's leak detection. Other fuzzers won't be using it and + # using it will cause libFuzzer to find "crashes" no one cares about. + '-detect_leaks=0', + + # Store crashes along with corpus for bug based benchmarking. + f'-artifact_prefix={crashes_dir}/', + ] + flags += extra_flags + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + flags.append('-dict=' + dictionary_path) + + command = [target_binary] + flags + [output_corpus, input_corpus] + print('[run_fuzzer] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/libfuzzer_t0/patch.diff b/fuzzers/libfuzzer_t0/patch.diff new file mode 100644 index 000000000..a31cc301e --- /dev/null +++ b/fuzzers/libfuzzer_t0/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_t0/runner.Dockerfile b/fuzzers/libfuzzer_t0/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/libfuzzer_t0/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 diff --git a/fuzzers/libfuzzer_t1/builder.Dockerfile b/fuzzers/libfuzzer_t1/builder.Dockerfile new file mode 100644 index 000000000..7fe80447e --- /dev/null +++ b/fuzzers/libfuzzer_t1/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_t1/fuzzer.py b/fuzzers/libfuzzer_t1/fuzzer.py new file mode 100755 index 000000000..78a1e2f8f --- /dev/null +++ b/fuzzers/libfuzzer_t1/fuzzer.py @@ -0,0 +1,102 @@ +# 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 libFuzzer fuzzer.""" + +import subprocess +import os + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # With LibFuzzer we use -fsanitize=fuzzer-no-link for build CFLAGS and then + # /usr/lib/libFuzzer.a as the FUZZER_LIB for the main fuzzing binary. This + # allows us to link against a version of LibFuzzer that we specify. + cflags = ['-fsanitize=fuzzer-no-link'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cflags) + + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + os.environ['FUZZER_LIB'] = '/usr/lib/libFuzzer.a' + + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer. Wrapper that uses the defaults when calling + run_fuzzer.""" + run_fuzzer(input_corpus, output_corpus, target_binary) + + +def run_fuzzer(input_corpus, output_corpus, target_binary, extra_flags=None): + """Run fuzzer.""" + if extra_flags is None: + extra_flags = [] + + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + # Enable symbolization if needed. + # Note: if the flags are like `symbolize=0:..:symbolize=1` then + # only symbolize=1 is respected. + for flag in extra_flags: + if flag.startswith('-focus_function'): + if 'ASAN_OPTIONS' in os.environ: + os.environ['ASAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['ASAN_OPTIONS'] = 'symbolize=1' + if 'UBSAN_OPTIONS' in os.environ: + os.environ['UBSAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['UBSAN_OPTIONS'] = 'symbolize=1' + break + + flags = [ + '-print_final_stats=1', + # `close_fd_mask` to prevent too much logging output from the target. + '-close_fd_mask=3', + # Run in fork mode to allow ignoring ooms, timeouts, crashes and + # continue fuzzing indefinitely. + '-fork=1', + '-ignore_ooms=1', + '-ignore_timeouts=1', + '-ignore_crashes=1', + '-entropic=1', + '-keep_seed=1', + '-cross_over_uniform_dist=1', + '-entropic_scale_per_exec_time=1', + + # Don't use LSAN's leak detection. Other fuzzers won't be using it and + # using it will cause libFuzzer to find "crashes" no one cares about. + '-detect_leaks=0', + + # Store crashes along with corpus for bug based benchmarking. + f'-artifact_prefix={crashes_dir}/', + ] + flags += extra_flags + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + flags.append('-dict=' + dictionary_path) + + command = [target_binary] + flags + [output_corpus, input_corpus] + print('[run_fuzzer] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/libfuzzer_t1/patch.diff b/fuzzers/libfuzzer_t1/patch.diff new file mode 100644 index 000000000..a31cc301e --- /dev/null +++ b/fuzzers/libfuzzer_t1/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_t1/runner.Dockerfile b/fuzzers/libfuzzer_t1/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/libfuzzer_t1/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 diff --git a/fuzzers/libfuzzer_t2/builder.Dockerfile b/fuzzers/libfuzzer_t2/builder.Dockerfile new file mode 100644 index 000000000..7fe80447e --- /dev/null +++ b/fuzzers/libfuzzer_t2/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_t2/fuzzer.py b/fuzzers/libfuzzer_t2/fuzzer.py new file mode 100755 index 000000000..78a1e2f8f --- /dev/null +++ b/fuzzers/libfuzzer_t2/fuzzer.py @@ -0,0 +1,102 @@ +# 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 libFuzzer fuzzer.""" + +import subprocess +import os + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # With LibFuzzer we use -fsanitize=fuzzer-no-link for build CFLAGS and then + # /usr/lib/libFuzzer.a as the FUZZER_LIB for the main fuzzing binary. This + # allows us to link against a version of LibFuzzer that we specify. + cflags = ['-fsanitize=fuzzer-no-link'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cflags) + + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + os.environ['FUZZER_LIB'] = '/usr/lib/libFuzzer.a' + + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer. Wrapper that uses the defaults when calling + run_fuzzer.""" + run_fuzzer(input_corpus, output_corpus, target_binary) + + +def run_fuzzer(input_corpus, output_corpus, target_binary, extra_flags=None): + """Run fuzzer.""" + if extra_flags is None: + extra_flags = [] + + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + # Enable symbolization if needed. + # Note: if the flags are like `symbolize=0:..:symbolize=1` then + # only symbolize=1 is respected. + for flag in extra_flags: + if flag.startswith('-focus_function'): + if 'ASAN_OPTIONS' in os.environ: + os.environ['ASAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['ASAN_OPTIONS'] = 'symbolize=1' + if 'UBSAN_OPTIONS' in os.environ: + os.environ['UBSAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['UBSAN_OPTIONS'] = 'symbolize=1' + break + + flags = [ + '-print_final_stats=1', + # `close_fd_mask` to prevent too much logging output from the target. + '-close_fd_mask=3', + # Run in fork mode to allow ignoring ooms, timeouts, crashes and + # continue fuzzing indefinitely. + '-fork=1', + '-ignore_ooms=1', + '-ignore_timeouts=1', + '-ignore_crashes=1', + '-entropic=1', + '-keep_seed=1', + '-cross_over_uniform_dist=1', + '-entropic_scale_per_exec_time=1', + + # Don't use LSAN's leak detection. Other fuzzers won't be using it and + # using it will cause libFuzzer to find "crashes" no one cares about. + '-detect_leaks=0', + + # Store crashes along with corpus for bug based benchmarking. + f'-artifact_prefix={crashes_dir}/', + ] + flags += extra_flags + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + flags.append('-dict=' + dictionary_path) + + command = [target_binary] + flags + [output_corpus, input_corpus] + print('[run_fuzzer] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/libfuzzer_t2/patch.diff b/fuzzers/libfuzzer_t2/patch.diff new file mode 100644 index 000000000..a31cc301e --- /dev/null +++ b/fuzzers/libfuzzer_t2/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_t2/runner.Dockerfile b/fuzzers/libfuzzer_t2/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/libfuzzer_t2/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 diff --git a/fuzzers/libfuzzer_t3/builder.Dockerfile b/fuzzers/libfuzzer_t3/builder.Dockerfile new file mode 100644 index 000000000..7fe80447e --- /dev/null +++ b/fuzzers/libfuzzer_t3/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_t3/fuzzer.py b/fuzzers/libfuzzer_t3/fuzzer.py new file mode 100755 index 000000000..78a1e2f8f --- /dev/null +++ b/fuzzers/libfuzzer_t3/fuzzer.py @@ -0,0 +1,102 @@ +# 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 libFuzzer fuzzer.""" + +import subprocess +import os + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # With LibFuzzer we use -fsanitize=fuzzer-no-link for build CFLAGS and then + # /usr/lib/libFuzzer.a as the FUZZER_LIB for the main fuzzing binary. This + # allows us to link against a version of LibFuzzer that we specify. + cflags = ['-fsanitize=fuzzer-no-link'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cflags) + + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + os.environ['FUZZER_LIB'] = '/usr/lib/libFuzzer.a' + + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer. Wrapper that uses the defaults when calling + run_fuzzer.""" + run_fuzzer(input_corpus, output_corpus, target_binary) + + +def run_fuzzer(input_corpus, output_corpus, target_binary, extra_flags=None): + """Run fuzzer.""" + if extra_flags is None: + extra_flags = [] + + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + # Enable symbolization if needed. + # Note: if the flags are like `symbolize=0:..:symbolize=1` then + # only symbolize=1 is respected. + for flag in extra_flags: + if flag.startswith('-focus_function'): + if 'ASAN_OPTIONS' in os.environ: + os.environ['ASAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['ASAN_OPTIONS'] = 'symbolize=1' + if 'UBSAN_OPTIONS' in os.environ: + os.environ['UBSAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['UBSAN_OPTIONS'] = 'symbolize=1' + break + + flags = [ + '-print_final_stats=1', + # `close_fd_mask` to prevent too much logging output from the target. + '-close_fd_mask=3', + # Run in fork mode to allow ignoring ooms, timeouts, crashes and + # continue fuzzing indefinitely. + '-fork=1', + '-ignore_ooms=1', + '-ignore_timeouts=1', + '-ignore_crashes=1', + '-entropic=1', + '-keep_seed=1', + '-cross_over_uniform_dist=1', + '-entropic_scale_per_exec_time=1', + + # Don't use LSAN's leak detection. Other fuzzers won't be using it and + # using it will cause libFuzzer to find "crashes" no one cares about. + '-detect_leaks=0', + + # Store crashes along with corpus for bug based benchmarking. + f'-artifact_prefix={crashes_dir}/', + ] + flags += extra_flags + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + flags.append('-dict=' + dictionary_path) + + command = [target_binary] + flags + [output_corpus, input_corpus] + print('[run_fuzzer] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/libfuzzer_t3/patch.diff b/fuzzers/libfuzzer_t3/patch.diff new file mode 100644 index 000000000..a31cc301e --- /dev/null +++ b/fuzzers/libfuzzer_t3/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_t3/runner.Dockerfile b/fuzzers/libfuzzer_t3/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/libfuzzer_t3/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 diff --git a/fuzzers/libfuzzer_t4/builder.Dockerfile b/fuzzers/libfuzzer_t4/builder.Dockerfile new file mode 100644 index 000000000..7fe80447e --- /dev/null +++ b/fuzzers/libfuzzer_t4/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_t4/fuzzer.py b/fuzzers/libfuzzer_t4/fuzzer.py new file mode 100755 index 000000000..78a1e2f8f --- /dev/null +++ b/fuzzers/libfuzzer_t4/fuzzer.py @@ -0,0 +1,102 @@ +# 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 libFuzzer fuzzer.""" + +import subprocess +import os + +from fuzzers import utils + + +def build(): + """Build benchmark.""" + # With LibFuzzer we use -fsanitize=fuzzer-no-link for build CFLAGS and then + # /usr/lib/libFuzzer.a as the FUZZER_LIB for the main fuzzing binary. This + # allows us to link against a version of LibFuzzer that we specify. + cflags = ['-fsanitize=fuzzer-no-link'] + utils.append_flags('CFLAGS', cflags) + utils.append_flags('CXXFLAGS', cflags) + + os.environ['CC'] = 'clang' + os.environ['CXX'] = 'clang++' + os.environ['FUZZER_LIB'] = '/usr/lib/libFuzzer.a' + + utils.build_benchmark() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer. Wrapper that uses the defaults when calling + run_fuzzer.""" + run_fuzzer(input_corpus, output_corpus, target_binary) + + +def run_fuzzer(input_corpus, output_corpus, target_binary, extra_flags=None): + """Run fuzzer.""" + if extra_flags is None: + extra_flags = [] + + # Seperate out corpus and crash directories as sub-directories of + # |output_corpus| to avoid conflicts when corpus directory is reloaded. + crashes_dir = os.path.join(output_corpus, 'crashes') + output_corpus = os.path.join(output_corpus, 'corpus') + os.makedirs(crashes_dir) + os.makedirs(output_corpus) + + # Enable symbolization if needed. + # Note: if the flags are like `symbolize=0:..:symbolize=1` then + # only symbolize=1 is respected. + for flag in extra_flags: + if flag.startswith('-focus_function'): + if 'ASAN_OPTIONS' in os.environ: + os.environ['ASAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['ASAN_OPTIONS'] = 'symbolize=1' + if 'UBSAN_OPTIONS' in os.environ: + os.environ['UBSAN_OPTIONS'] += ':symbolize=1' + else: + os.environ['UBSAN_OPTIONS'] = 'symbolize=1' + break + + flags = [ + '-print_final_stats=1', + # `close_fd_mask` to prevent too much logging output from the target. + '-close_fd_mask=3', + # Run in fork mode to allow ignoring ooms, timeouts, crashes and + # continue fuzzing indefinitely. + '-fork=1', + '-ignore_ooms=1', + '-ignore_timeouts=1', + '-ignore_crashes=1', + '-entropic=1', + '-keep_seed=1', + '-cross_over_uniform_dist=1', + '-entropic_scale_per_exec_time=1', + + # Don't use LSAN's leak detection. Other fuzzers won't be using it and + # using it will cause libFuzzer to find "crashes" no one cares about. + '-detect_leaks=0', + + # Store crashes along with corpus for bug based benchmarking. + f'-artifact_prefix={crashes_dir}/', + ] + flags += extra_flags + if 'ADDITIONAL_ARGS' in os.environ: + flags += os.environ['ADDITIONAL_ARGS'].split(' ') + dictionary_path = utils.get_dictionary_path(target_binary) + if dictionary_path: + flags.append('-dict=' + dictionary_path) + + command = [target_binary] + flags + [output_corpus, input_corpus] + print('[run_fuzzer] Running command: ' + ' '.join(command)) + subprocess.check_call(command) diff --git a/fuzzers/libfuzzer_t4/patch.diff b/fuzzers/libfuzzer_t4/patch.diff new file mode 100644 index 000000000..a31cc301e --- /dev/null +++ b/fuzzers/libfuzzer_t4/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_t4/runner.Dockerfile b/fuzzers/libfuzzer_t4/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/libfuzzer_t4/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 diff --git a/fuzzers/mopt/builder.Dockerfile b/fuzzers/mopt/builder.Dockerfile index afd22521e..d3a094752 100644 --- a/fuzzers/mopt/builder.Dockerfile +++ b/fuzzers/mopt/builder.Dockerfile @@ -18,7 +18,7 @@ FROM $parent_image # Set AFL_NO_X86 to skip flaky tests. RUN git clone https://github.com/puppet-meteor/MOpt-AFL /afl && \ cd /afl && \ - git checkout 45b9f38d2d8b699fd571cfde1bf974974339a21e && \ + git checkout a9a5dc5c0c291c1cdb09b2b7b27d7cbf1db7ce7b && \ cd MOpt && AFL_NO_X86=1 make && \ cp afl-fuzz .. diff --git a/fuzzers/mopt2/builder.Dockerfile b/fuzzers/mopt2/builder.Dockerfile new file mode 100644 index 000000000..7e5511235 --- /dev/null +++ b/fuzzers/mopt2/builder.Dockerfile @@ -0,0 +1,31 @@ +# 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 + +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/vanhauser-THC/MOpt /afl && \ + cd /afl && \ + git checkout a2e23d151bed60e1912e74670f71dec695c988c7 && \ + cd MOpt && AFL_NO_X86=1 make && \ + cp afl-fuzz .. + +# Use afl_driver.cpp from LLVM as our fuzzing library. +RUN apt-get update && \ + apt-get install wget -y && cd /afl/MOpt && \ + wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/afl/afl_driver.cpp -O /afl/MOpt/afl_driver.cpp && \ + clang -Wno-pointer-sign -c -o /afl/MOpt/afl-llvm-rt.o /afl/MOpt/llvm_mode/afl-llvm-rt.o.c -I/afl/MOpt && \ + clang++ -stdlib=libc++ -std=c++11 -O2 -c -o /afl/MOpt/afl_driver.o /afl/MOpt/afl_driver.cpp && \ + ar r /libAFL.a *.o diff --git a/fuzzers/symcc_afl_single/fuzzer.py b/fuzzers/mopt2/fuzzer.py old mode 100644 new mode 100755 similarity index 52% rename from fuzzers/symcc_afl_single/fuzzer.py rename to fuzzers/mopt2/fuzzer.py index b37e13bb3..150d1992a --- a/fuzzers/symcc_afl_single/fuzzer.py +++ b/fuzzers/mopt2/fuzzer.py @@ -1,4 +1,4 @@ -# Copyright 2021 Google LLC +# 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. @@ -11,17 +11,27 @@ # 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. -''' Uses the SymCC-AFL hybrid from SymCC, although this only - launches a single AFL instance rather than two. ''' +"""Integration code for MOpt fuzzer.""" -from fuzzers.symcc_afl import fuzzer as symcc_afl_fuzzer +from fuzzers.afl import fuzzer as afl_fuzzer def build(): - """ Build an AFL version and SymCC version of the benchmark """ - symcc_afl_fuzzer.build() + """Build benchmark.""" + afl_fuzzer.build() def fuzz(input_corpus, output_corpus, target_binary): - """ Launch a SymCC with a single AFL instance. """ - symcc_afl_fuzzer.fuzz(input_corpus, output_corpus, target_binary, True) + """Run fuzzer.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + + afl_fuzzer.run_afl_fuzz( + input_corpus, + output_corpus, + target_binary, + additional_flags=[ + # Enable Mopt mutator with pacemaker fuzzing mode at first. This + # is also recommended in a short-time scale evaluation. + '-L', + '0', + ]) diff --git a/fuzzers/mopt2/runner.Dockerfile b/fuzzers/mopt2/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/mopt2/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 diff --git a/fuzzers/mopt_t0/builder.Dockerfile b/fuzzers/mopt_t0/builder.Dockerfile new file mode 100644 index 000000000..d3a094752 --- /dev/null +++ b/fuzzers/mopt_t0/builder.Dockerfile @@ -0,0 +1,31 @@ +# 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 + +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/puppet-meteor/MOpt-AFL /afl && \ + cd /afl && \ + git checkout a9a5dc5c0c291c1cdb09b2b7b27d7cbf1db7ce7b && \ + cd MOpt && AFL_NO_X86=1 make && \ + cp afl-fuzz .. + +# Use afl_driver.cpp from LLVM as our fuzzing library. +RUN apt-get update && \ + apt-get install wget -y && cd /afl/MOpt && \ + wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/afl/afl_driver.cpp -O /afl/MOpt/afl_driver.cpp && \ + clang -Wno-pointer-sign -c -o /afl/MOpt/afl-llvm-rt.o /afl/MOpt/llvm_mode/afl-llvm-rt.o.c -I/afl/MOpt && \ + clang++ -stdlib=libc++ -std=c++11 -O2 -c -o /afl/MOpt/afl_driver.o /afl/MOpt/afl_driver.cpp && \ + ar r /libAFL.a *.o diff --git a/fuzzers/mopt_t0/fuzzer.py b/fuzzers/mopt_t0/fuzzer.py new file mode 100755 index 000000000..150d1992a --- /dev/null +++ b/fuzzers/mopt_t0/fuzzer.py @@ -0,0 +1,37 @@ +# 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 MOpt fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + + afl_fuzzer.run_afl_fuzz( + input_corpus, + output_corpus, + target_binary, + additional_flags=[ + # Enable Mopt mutator with pacemaker fuzzing mode at first. This + # is also recommended in a short-time scale evaluation. + '-L', + '0', + ]) diff --git a/fuzzers/mopt_t0/runner.Dockerfile b/fuzzers/mopt_t0/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/mopt_t0/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 diff --git a/fuzzers/mopt_t1/builder.Dockerfile b/fuzzers/mopt_t1/builder.Dockerfile new file mode 100644 index 000000000..d3a094752 --- /dev/null +++ b/fuzzers/mopt_t1/builder.Dockerfile @@ -0,0 +1,31 @@ +# 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 + +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/puppet-meteor/MOpt-AFL /afl && \ + cd /afl && \ + git checkout a9a5dc5c0c291c1cdb09b2b7b27d7cbf1db7ce7b && \ + cd MOpt && AFL_NO_X86=1 make && \ + cp afl-fuzz .. + +# Use afl_driver.cpp from LLVM as our fuzzing library. +RUN apt-get update && \ + apt-get install wget -y && cd /afl/MOpt && \ + wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/afl/afl_driver.cpp -O /afl/MOpt/afl_driver.cpp && \ + clang -Wno-pointer-sign -c -o /afl/MOpt/afl-llvm-rt.o /afl/MOpt/llvm_mode/afl-llvm-rt.o.c -I/afl/MOpt && \ + clang++ -stdlib=libc++ -std=c++11 -O2 -c -o /afl/MOpt/afl_driver.o /afl/MOpt/afl_driver.cpp && \ + ar r /libAFL.a *.o diff --git a/fuzzers/mopt_t1/fuzzer.py b/fuzzers/mopt_t1/fuzzer.py new file mode 100755 index 000000000..150d1992a --- /dev/null +++ b/fuzzers/mopt_t1/fuzzer.py @@ -0,0 +1,37 @@ +# 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 MOpt fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + + afl_fuzzer.run_afl_fuzz( + input_corpus, + output_corpus, + target_binary, + additional_flags=[ + # Enable Mopt mutator with pacemaker fuzzing mode at first. This + # is also recommended in a short-time scale evaluation. + '-L', + '0', + ]) diff --git a/fuzzers/mopt_t1/runner.Dockerfile b/fuzzers/mopt_t1/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/mopt_t1/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 diff --git a/fuzzers/mopt_t2/builder.Dockerfile b/fuzzers/mopt_t2/builder.Dockerfile new file mode 100644 index 000000000..d3a094752 --- /dev/null +++ b/fuzzers/mopt_t2/builder.Dockerfile @@ -0,0 +1,31 @@ +# 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 + +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/puppet-meteor/MOpt-AFL /afl && \ + cd /afl && \ + git checkout a9a5dc5c0c291c1cdb09b2b7b27d7cbf1db7ce7b && \ + cd MOpt && AFL_NO_X86=1 make && \ + cp afl-fuzz .. + +# Use afl_driver.cpp from LLVM as our fuzzing library. +RUN apt-get update && \ + apt-get install wget -y && cd /afl/MOpt && \ + wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/afl/afl_driver.cpp -O /afl/MOpt/afl_driver.cpp && \ + clang -Wno-pointer-sign -c -o /afl/MOpt/afl-llvm-rt.o /afl/MOpt/llvm_mode/afl-llvm-rt.o.c -I/afl/MOpt && \ + clang++ -stdlib=libc++ -std=c++11 -O2 -c -o /afl/MOpt/afl_driver.o /afl/MOpt/afl_driver.cpp && \ + ar r /libAFL.a *.o diff --git a/fuzzers/mopt_t2/fuzzer.py b/fuzzers/mopt_t2/fuzzer.py new file mode 100755 index 000000000..150d1992a --- /dev/null +++ b/fuzzers/mopt_t2/fuzzer.py @@ -0,0 +1,37 @@ +# 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 MOpt fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + + afl_fuzzer.run_afl_fuzz( + input_corpus, + output_corpus, + target_binary, + additional_flags=[ + # Enable Mopt mutator with pacemaker fuzzing mode at first. This + # is also recommended in a short-time scale evaluation. + '-L', + '0', + ]) diff --git a/fuzzers/mopt_t2/runner.Dockerfile b/fuzzers/mopt_t2/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/mopt_t2/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 diff --git a/fuzzers/mopt_t3/builder.Dockerfile b/fuzzers/mopt_t3/builder.Dockerfile new file mode 100644 index 000000000..d3a094752 --- /dev/null +++ b/fuzzers/mopt_t3/builder.Dockerfile @@ -0,0 +1,31 @@ +# 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 + +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/puppet-meteor/MOpt-AFL /afl && \ + cd /afl && \ + git checkout a9a5dc5c0c291c1cdb09b2b7b27d7cbf1db7ce7b && \ + cd MOpt && AFL_NO_X86=1 make && \ + cp afl-fuzz .. + +# Use afl_driver.cpp from LLVM as our fuzzing library. +RUN apt-get update && \ + apt-get install wget -y && cd /afl/MOpt && \ + wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/afl/afl_driver.cpp -O /afl/MOpt/afl_driver.cpp && \ + clang -Wno-pointer-sign -c -o /afl/MOpt/afl-llvm-rt.o /afl/MOpt/llvm_mode/afl-llvm-rt.o.c -I/afl/MOpt && \ + clang++ -stdlib=libc++ -std=c++11 -O2 -c -o /afl/MOpt/afl_driver.o /afl/MOpt/afl_driver.cpp && \ + ar r /libAFL.a *.o diff --git a/fuzzers/mopt_t3/fuzzer.py b/fuzzers/mopt_t3/fuzzer.py new file mode 100755 index 000000000..150d1992a --- /dev/null +++ b/fuzzers/mopt_t3/fuzzer.py @@ -0,0 +1,37 @@ +# 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 MOpt fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + + afl_fuzzer.run_afl_fuzz( + input_corpus, + output_corpus, + target_binary, + additional_flags=[ + # Enable Mopt mutator with pacemaker fuzzing mode at first. This + # is also recommended in a short-time scale evaluation. + '-L', + '0', + ]) diff --git a/fuzzers/mopt_t3/runner.Dockerfile b/fuzzers/mopt_t3/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/mopt_t3/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 diff --git a/fuzzers/mopt_t4/builder.Dockerfile b/fuzzers/mopt_t4/builder.Dockerfile new file mode 100644 index 000000000..d3a094752 --- /dev/null +++ b/fuzzers/mopt_t4/builder.Dockerfile @@ -0,0 +1,31 @@ +# 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 + +# Set AFL_NO_X86 to skip flaky tests. +RUN git clone https://github.com/puppet-meteor/MOpt-AFL /afl && \ + cd /afl && \ + git checkout a9a5dc5c0c291c1cdb09b2b7b27d7cbf1db7ce7b && \ + cd MOpt && AFL_NO_X86=1 make && \ + cp afl-fuzz .. + +# Use afl_driver.cpp from LLVM as our fuzzing library. +RUN apt-get update && \ + apt-get install wget -y && cd /afl/MOpt && \ + wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/afl/afl_driver.cpp -O /afl/MOpt/afl_driver.cpp && \ + clang -Wno-pointer-sign -c -o /afl/MOpt/afl-llvm-rt.o /afl/MOpt/llvm_mode/afl-llvm-rt.o.c -I/afl/MOpt && \ + clang++ -stdlib=libc++ -std=c++11 -O2 -c -o /afl/MOpt/afl_driver.o /afl/MOpt/afl_driver.cpp && \ + ar r /libAFL.a *.o diff --git a/fuzzers/mopt_t4/fuzzer.py b/fuzzers/mopt_t4/fuzzer.py new file mode 100755 index 000000000..150d1992a --- /dev/null +++ b/fuzzers/mopt_t4/fuzzer.py @@ -0,0 +1,37 @@ +# 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 MOpt fuzzer.""" + +from fuzzers.afl import fuzzer as afl_fuzzer + + +def build(): + """Build benchmark.""" + afl_fuzzer.build() + + +def fuzz(input_corpus, output_corpus, target_binary): + """Run fuzzer.""" + afl_fuzzer.prepare_fuzz_environment(input_corpus) + + afl_fuzzer.run_afl_fuzz( + input_corpus, + output_corpus, + target_binary, + additional_flags=[ + # Enable Mopt mutator with pacemaker fuzzing mode at first. This + # is also recommended in a short-time scale evaluation. + '-L', + '0', + ]) diff --git a/fuzzers/mopt_t4/runner.Dockerfile b/fuzzers/mopt_t4/runner.Dockerfile new file mode 100644 index 000000000..0d6cf004e --- /dev/null +++ b/fuzzers/mopt_t4/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 diff --git a/fuzzers/symcc_afl/builder.Dockerfile b/fuzzers/symcc_afl/builder.Dockerfile deleted file mode 100644 index 76e4ecf7d..000000000 --- a/fuzzers/symcc_afl/builder.Dockerfile +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright 2021 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 - -# Download and compile AFL v2.56b. -# Set AFL_NO_X86 to skip flaky tests. -RUN git clone https://github.com/google/AFL.git /afl && \ - cd /afl && \ - git checkout 82b5e359463238d790cadbe2dd494d6a4928bff3 && \ - AFL_NO_X86=1 make - -## 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/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 - - -# Install the packages we need. -RUN apt-get install -y ninja-build flex bison python zlib1g-dev cargo - -# Install Z3 from binary -RUN wget -qO /tmp/z3x64.zip https://github.com/Z3Prover/z3/releases/download/z3-4.8.7/z3-4.8.7-x64-ubuntu-16.04.zip && \ - unzip -jd /usr/include /tmp/z3x64.zip "*/include/*.h" && \ - unzip -jd /usr/lib /tmp/z3x64.zip "*/bin/libz3.so" && \ - rm -f /tmp/*.zip && \ - ldconfig - -ENV CFLAGS="" -ENV CXXFLAGS="" - -# Get and install symcc. -RUN cd / && \ - git clone https://github.com/AdaLogics/adacc symcc && \ - cd symcc && \ - git checkout edda79dcb830c95ba6d303e47c698839313ef506 && \ - cd ./runtime/qsym_backend && \ - git clone https://github.com/adalogics/qsym && \ - cd qsym && \ - git checkout adalogics && \ - cd /symcc && \ - mkdir build && \ - cd build && \ - cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DQSYM_BACKEND=ON \ - -DZ3_TRUST_SYSTEM_VERSION=ON ../ && \ - ninja -j 3 && \ - cd ../examples && \ - export SYMCC_PC=1 && \ - ../build/symcc -c ./libfuzz-harness-proxy.c -o /libfuzzer-harness.o && \ - cd ../ && echo "[+] Installing cargo now 4" && \ - cargo install --path util/symcc_fuzzing_helper - -# Build libcxx with the SymCC compiler so we can instrument -# C++ code. -RUN git clone -b llvmorg-12.0.0 --depth 1 https://github.com/llvm/llvm-project.git /llvm_source && \ - mkdir /libcxx_native_install && mkdir /libcxx_native_build && \ - cd /libcxx_native_install \ - && export SYMCC_REGULAR_LIBCXX="" && \ - cmake /llvm_source/llvm \ - -G Ninja -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ - -DLLVM_DISTRIBUTION_COMPONENTS="cxx;cxxabi;cxx-headers" \ - -DLLVM_TARGETS_TO_BUILD="X86" -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_C_COMPILER=/symcc/build/symcc \ - -DCMAKE_CXX_COMPILER=/symcc/build/sym++ \ - -DHAVE_POSIX_REGEX=1 \ - -DCMAKE_INSTALL_PREFIX="/libcxx_native_build" \ - -DHAVE_STEADY_CLOCK=1 && \ - ninja distribution && \ - ninja install-distribution diff --git a/fuzzers/symcc_afl/fuzzer.py b/fuzzers/symcc_afl/fuzzer.py deleted file mode 100644 index 0c92eaa2c..000000000 --- a/fuzzers/symcc_afl/fuzzer.py +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright 2021 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. -''' Uses the SymCC-AFL hybrid from SymCC. ''' - -import os -import time -import shutil -import threading -import subprocess - -from fuzzers import utils -from fuzzers.afl import fuzzer as afl_fuzzer - - -def get_symcc_build_dir(target_directory): - """Return path to uninstrumented target directory.""" - return os.path.join(target_directory, 'uninstrumented') - - -def build(): - """Build an AFL version and SymCC version of the benchmark""" - print('Step 1: Building with AFL') - build_directory = os.environ['OUT'] - - # First build with AFL. - src = os.getenv('SRC') - work = os.getenv('WORK') - with utils.restore_directory(src), utils.restore_directory(work): - # Restore SRC to its initial state so we can build again without any - # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run - # twice in the same directory without this. - afl_fuzzer.build() - - print('Step 2: Completed AFL build') - # Copy over AFL artifacts needed by SymCC. - shutil.copy('/afl/afl-fuzz', build_directory) - shutil.copy('/afl/afl-showmap', build_directory) - - # Build the SymCC-instrumented target. - print('Step 3: Building the benchmark with SymCC') - symcc_build_dir = get_symcc_build_dir(os.environ['OUT']) - os.mkdir(symcc_build_dir) - - # Set flags to ensure compilation with SymCC. - new_env = os.environ.copy() - new_env['CC'] = '/symcc/build/symcc' - new_env['CXX'] = '/symcc/build/sym++' - new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') - new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' - new_env['OUT'] = symcc_build_dir - - new_env['CXXFLAGS'] += ' -fno-sanitize=all ' - new_env['CFLAGS'] += ' -fno-sanitize=all ' - - # Setting this environment variable instructs SymCC to use the - # libcxx library compiled with SymCC instrumentation. - new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' - - # Instructs SymCC to consider no symbolic inputs at runtime. This is needed - # if, for example, some tests are run during compilation of the benchmark. - new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' - - # Build benchmark. - utils.build_benchmark(env=new_env) - - # Copy over symcc artifacts and symbolic libc++. - shutil.copy( - '/symcc/build//SymRuntime-prefix/src/SymRuntime-build/libSymRuntime.so', - symcc_build_dir) - shutil.copy('/usr/lib/libz3.so', os.path.join(symcc_build_dir, 'libz3.so')) - shutil.copy('/libcxx_native_build/lib/libc++.so.1', symcc_build_dir) - shutil.copy('/libcxx_native_build/lib/libc++abi.so.1', symcc_build_dir) - shutil.copy('/rust/bin/symcc_fuzzing_helper', symcc_build_dir) - - -def launch_afl_thread(input_corpus, output_corpus, target_binary, - additional_flags): - """ Simple wrapper for running AFL. """ - afl_thread = threading.Thread(target=afl_fuzzer.run_afl_fuzz, - args=(input_corpus, output_corpus, - target_binary, additional_flags)) - afl_thread.start() - return afl_thread - - -def fuzz(input_corpus, output_corpus, target_binary, master_only=False): - """ - Launches a master and a secondary instance of AFL, as well as - the symcc helper. - """ - target_binary_dir = os.path.dirname(target_binary) - symcc_workdir = get_symcc_build_dir(target_binary_dir) - target_binary_name = os.path.basename(target_binary) - symcc_target_binary = os.path.join(symcc_workdir, target_binary_name) - - # Start a master and secondary instance of AFL. - # We need both because of the way SymCC works. - print('[run_fuzzer] Running AFL for SymCC') - afl_fuzzer.prepare_fuzz_environment(input_corpus) - launch_afl_thread(input_corpus, output_corpus, target_binary, - ['-M', 'afl-master']) - time.sleep(5) - - if master_only: - sharing_dir = 'afl-master' - else: - launch_afl_thread(input_corpus, output_corpus, target_binary, - ['-S', 'afl-secondary']) - time.sleep(5) - sharing_dir = 'afl-secondary' - - # Start an instance of SymCC. - # We need to ensure it uses the symbolic version of libc++. - print('Starting the SymCC helper') - new_environ = os.environ.copy() - new_environ['LD_LIBRARY_PATH'] = symcc_workdir - cmd = [ - os.path.join(symcc_workdir, - 'symcc_fuzzing_helper'), '-o', output_corpus, '-a', - sharing_dir, '-n', 'symcc', '--', symcc_target_binary, '@@' - ] - with subprocess.Popen(cmd, env=new_environ): - pass diff --git a/fuzzers/symcc_afl_single/builder.Dockerfile b/fuzzers/symcc_afl_single/builder.Dockerfile deleted file mode 100644 index 76e4ecf7d..000000000 --- a/fuzzers/symcc_afl_single/builder.Dockerfile +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright 2021 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 - -# Download and compile AFL v2.56b. -# Set AFL_NO_X86 to skip flaky tests. -RUN git clone https://github.com/google/AFL.git /afl && \ - cd /afl && \ - git checkout 82b5e359463238d790cadbe2dd494d6a4928bff3 && \ - AFL_NO_X86=1 make - -## 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/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 - - -# Install the packages we need. -RUN apt-get install -y ninja-build flex bison python zlib1g-dev cargo - -# Install Z3 from binary -RUN wget -qO /tmp/z3x64.zip https://github.com/Z3Prover/z3/releases/download/z3-4.8.7/z3-4.8.7-x64-ubuntu-16.04.zip && \ - unzip -jd /usr/include /tmp/z3x64.zip "*/include/*.h" && \ - unzip -jd /usr/lib /tmp/z3x64.zip "*/bin/libz3.so" && \ - rm -f /tmp/*.zip && \ - ldconfig - -ENV CFLAGS="" -ENV CXXFLAGS="" - -# Get and install symcc. -RUN cd / && \ - git clone https://github.com/AdaLogics/adacc symcc && \ - cd symcc && \ - git checkout edda79dcb830c95ba6d303e47c698839313ef506 && \ - cd ./runtime/qsym_backend && \ - git clone https://github.com/adalogics/qsym && \ - cd qsym && \ - git checkout adalogics && \ - cd /symcc && \ - mkdir build && \ - cd build && \ - cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DQSYM_BACKEND=ON \ - -DZ3_TRUST_SYSTEM_VERSION=ON ../ && \ - ninja -j 3 && \ - cd ../examples && \ - export SYMCC_PC=1 && \ - ../build/symcc -c ./libfuzz-harness-proxy.c -o /libfuzzer-harness.o && \ - cd ../ && echo "[+] Installing cargo now 4" && \ - cargo install --path util/symcc_fuzzing_helper - -# Build libcxx with the SymCC compiler so we can instrument -# C++ code. -RUN git clone -b llvmorg-12.0.0 --depth 1 https://github.com/llvm/llvm-project.git /llvm_source && \ - mkdir /libcxx_native_install && mkdir /libcxx_native_build && \ - cd /libcxx_native_install \ - && export SYMCC_REGULAR_LIBCXX="" && \ - cmake /llvm_source/llvm \ - -G Ninja -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ - -DLLVM_DISTRIBUTION_COMPONENTS="cxx;cxxabi;cxx-headers" \ - -DLLVM_TARGETS_TO_BUILD="X86" -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_C_COMPILER=/symcc/build/symcc \ - -DCMAKE_CXX_COMPILER=/symcc/build/sym++ \ - -DHAVE_POSIX_REGEX=1 \ - -DCMAKE_INSTALL_PREFIX="/libcxx_native_build" \ - -DHAVE_STEADY_CLOCK=1 && \ - ninja distribution && \ - ninja install-distribution diff --git a/fuzzers/symcc_aflplusplus/builder.Dockerfile b/fuzzers/symcc_aflplusplus/builder.Dockerfile deleted file mode 100644 index 5bdc0c175..000000000 --- a/fuzzers/symcc_aflplusplus/builder.Dockerfile +++ /dev/null @@ -1,87 +0,0 @@ -# Copyright 2021 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 8fc249d210ad49e3dd88d1409877ca64d9884690 - -# 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 / - -# Install the packages we need. -RUN apt-get install -y ninja-build flex bison python zlib1g-dev cargo - -# Install Z3 from binary -RUN wget -qO /tmp/z3x64.zip https://github.com/Z3Prover/z3/releases/download/z3-4.8.7/z3-4.8.7-x64-ubuntu-16.04.zip && \ - unzip -jd /usr/include /tmp/z3x64.zip "*/include/*.h" && \ - unzip -jd /usr/lib /tmp/z3x64.zip "*/bin/libz3.so" && \ - rm -f /tmp/*.zip && \ - ldconfig - -ENV CFLAGS="" -ENV CXXFLAGS="" - -# Get and install symcc. -RUN cd / && \ - git clone https://github.com/AdaLogics/adacc symcc && \ - cd symcc && \ - git checkout edda79dcb830c95ba6d303e47c698839313ef506 && \ - cd ./runtime/qsym_backend && \ - git clone https://github.com/adalogics/qsym && \ - cd qsym && \ - git checkout adalogics && \ - cd /symcc && \ - mkdir build && \ - cd build && \ - cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DQSYM_BACKEND=ON \ - -DZ3_TRUST_SYSTEM_VERSION=ON ../ && \ - ninja -j 3 && \ - cd ../examples && \ - export SYMCC_PC=1 && \ - ../build/symcc -c ./libfuzz-harness-proxy.c -o /libfuzzer-harness.o && \ - cd ../ && echo "[+] Installing cargo now 4" && \ - cargo install --path util/symcc_fuzzing_helper - -# Build libcxx with the SymCC compiler so we can instrument -# C++ code. -RUN git clone -b llvmorg-12.0.0 --depth 1 https://github.com/llvm/llvm-project.git /llvm_source && \ - mkdir /libcxx_native_install && mkdir /libcxx_native_build && \ - cd /libcxx_native_install \ - && export SYMCC_REGULAR_LIBCXX="" && \ - cmake /llvm_source/llvm \ - -G Ninja -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ - -DLLVM_DISTRIBUTION_COMPONENTS="cxx;cxxabi;cxx-headers" \ - -DLLVM_TARGETS_TO_BUILD="X86" -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_C_COMPILER=/symcc/build/symcc \ - -DCMAKE_CXX_COMPILER=/symcc/build/sym++ \ - -DHAVE_POSIX_REGEX=1 \ - -DCMAKE_INSTALL_PREFIX="/libcxx_native_build" \ - -DHAVE_STEADY_CLOCK=1 && \ - ninja distribution && \ - ninja install-distribution diff --git a/fuzzers/symcc_aflplusplus/fuzzer.py b/fuzzers/symcc_aflplusplus/fuzzer.py deleted file mode 100644 index 1737d0567..000000000 --- a/fuzzers/symcc_aflplusplus/fuzzer.py +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright 2021 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. -''' Uses the SymCC-AFL hybrid from SymCC. ''' - -import os -import time -import shutil -import threading -import subprocess - -from fuzzers import utils -from fuzzers.afl import fuzzer as afl_fuzzer -from fuzzers.aflplusplus import fuzzer as aflplusplus_fuzzer - - -def get_symcc_build_dir(target_directory): - """Return path to uninstrumented target directory.""" - return os.path.join(target_directory, 'uninstrumented') - - -def build(): - """Build an AFL version and SymCC version of the benchmark""" - print('Step 1: Building with AFL') - build_directory = os.environ['OUT'] - - # Save the environment for use in SymCC - new_env = os.environ.copy() - - # First build with AFL. - src = os.getenv('SRC') - work = os.getenv('WORK') - with utils.restore_directory(src), utils.restore_directory(work): - # Restore SRC to its initial state so we can build again without any - # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run - # twice in the same directory without this. - aflplusplus_fuzzer.build('tracepc') - - print('Step 2: Completed AFL build') - # Copy over AFL artifacts needed by SymCC. - shutil.copy('/afl/afl-fuzz', build_directory) - shutil.copy('/afl/afl-showmap', build_directory) - - # Build the SymCC-instrumented target. - print('Step 3: Building the benchmark with SymCC') - symcc_build_dir = get_symcc_build_dir(os.environ['OUT']) - os.mkdir(symcc_build_dir) - - # Set flags to ensure compilation with SymCC. - new_env['CC'] = '/symcc/build/symcc' - new_env['CXX'] = '/symcc/build/sym++' - new_env['CXXFLAGS'] = new_env['CXXFLAGS'].replace('-stlib=libc++', '') - new_env['CXXFLAGS'] += ' -ldl' - new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' - new_env['OUT'] = symcc_build_dir - - new_env['CXXFLAGS'] += ' -fno-sanitize=all ' - new_env['CFLAGS'] += ' -fno-sanitize=all ' - - # Setting this environment variable instructs SymCC to use the - # libcxx library compiled with SymCC instrumentation. - new_env['SYMCC_LIBCXX_PATH'] = '/libcxx_native_build' - - # Instructs SymCC to consider no symbolic inputs at runtime. This is needed - # if, for example, some tests are run during compilation of the benchmark. - new_env['SYMCC_NO_SYMBOLIC_INPUT'] = '1' - - # Build benchmark. - utils.build_benchmark(env=new_env) - - # Copy over symcc artifacts and symbolic libc++. - shutil.copy( - '/symcc/build//SymRuntime-prefix/src/SymRuntime-build/libSymRuntime.so', - symcc_build_dir) - shutil.copy('/usr/lib/libz3.so', os.path.join(symcc_build_dir, 'libz3.so')) - shutil.copy('/libcxx_native_build/lib/libc++.so.1', symcc_build_dir) - shutil.copy('/libcxx_native_build/lib/libc++abi.so.1', symcc_build_dir) - shutil.copy('/rust/bin/symcc_fuzzing_helper', symcc_build_dir) - - -def launch_afl_thread(input_corpus, output_corpus, target_binary, - additional_flags): - """ Simple wrapper for running AFL. """ - afl_thread = threading.Thread(target=afl_fuzzer.run_afl_fuzz, - args=(input_corpus, output_corpus, - target_binary, additional_flags)) - afl_thread.start() - return afl_thread - - -def fuzz(input_corpus, output_corpus, target_binary): - """ - Launches a master and a secondary instance of AFL, as well as - the symcc helper. - """ - target_binary_dir = os.path.dirname(target_binary) - symcc_workdir = get_symcc_build_dir(target_binary_dir) - target_binary_name = os.path.basename(target_binary) - symcc_target_binary = os.path.join(symcc_workdir, target_binary_name) - - os.environ['AFL_DISABLE_TRIM'] = '1' - - # Start a master and secondary instance of AFL. - # We need both because of the way SymCC works. - print('[run_fuzzer] Running AFL for SymCC') - afl_fuzzer.prepare_fuzz_environment(input_corpus) - launch_afl_thread(input_corpus, output_corpus, target_binary, ['-S', 'afl']) - time.sleep(5) - launch_afl_thread(input_corpus, output_corpus, target_binary, - ['-S', 'afl-secondary']) - time.sleep(5) - - # Start an instance of SymCC. - # We need to ensure it uses the symbolic version of libc++. - print('Starting the SymCC helper') - new_environ = os.environ.copy() - new_environ['LD_LIBRARY_PATH'] = symcc_workdir - cmd = [ - os.path.join(symcc_workdir, - 'symcc_fuzzing_helper'), '-o', output_corpus, '-a', - 'afl-secondary', '-n', 'symcc', '-m', '--', symcc_target_binary, '@@' - ] - with subprocess.Popen(cmd, env=new_environ): - pass diff --git a/fuzzers/symcc_aflplusplus_single/builder.Dockerfile b/fuzzers/symcc_aflplusplus_single/builder.Dockerfile deleted file mode 100644 index fa2329f14..000000000 --- a/fuzzers/symcc_aflplusplus_single/builder.Dockerfile +++ /dev/null @@ -1,89 +0,0 @@ -# Copyright 2021 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 8fc249d210ad49e3dd88d1409877ca64d9884690 - -# 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 / - -# Install the packages we need. -RUN apt-get install -y ninja-build flex bison python zlib1g-dev cargo - -# Install Z3 from binary -RUN wget -qO /tmp/z3x64.zip https://github.com/Z3Prover/z3/releases/download/z3-4.8.7/z3-4.8.7-x64-ubuntu-16.04.zip && \ - unzip -jd /usr/include /tmp/z3x64.zip "*/include/*.h" && \ - unzip -jd /usr/lib /tmp/z3x64.zip "*/bin/libz3.so" && \ - rm -f /tmp/*.zip && \ - ldconfig - -# Get and install symcc. -RUN cd / && \ - git clone https://github.com/adalogics/adacc symcc && \ - cd symcc && \ - git checkout 70efb3ef512a12b31caedcfcd9c0890813cd797e && \ - cd ./runtime/qsym_backend && \ - git clone https://github.com/adalogics/qsym && \ - cd qsym && \ - git checkout adalogics && \ - cd /symcc && \ - mkdir build && \ - cd build && \ - unset CFLAGS && unset CXXFLAGS && \ - cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DQSYM_BACKEND=ON \ - -DZ3_TRUST_SYSTEM_VERSION=ON ../ && \ - ninja -j 3 && \ - cd ../examples && \ - export SYMCC_PC=1 && \ - ../build/symcc -c ./libfuzz-harness-proxy.c -o /libfuzzer-harness.o && \ - cd ../ && echo "[+] Installing cargo now 4" && \ - cargo install --path util/symcc_fuzzing_helper - -# Build libcxx with the SymCC compiler so we can instrument -# C++ code. -RUN git clone -b llvmorg-12.0.0 --depth 1 https://github.com/llvm/llvm-project.git /llvm_source && \ - mkdir /libcxx_native_install && mkdir /libcxx_native_build && \ - cd /libcxx_native_install \ - && export SYMCC_REGULAR_LIBCXX="" && \ - unset CFLAGS && unset CXXFLAGS && \ - cmake /llvm_source/llvm \ - -G Ninja -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ - -DLLVM_DISTRIBUTION_COMPONENTS="cxx;cxxabi;cxx-headers" \ - -DLLVM_TARGETS_TO_BUILD="X86" -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_C_COMPILER=/symcc/build/symcc \ - -DCMAKE_CXX_COMPILER=/symcc/build/sym++ \ - -DHAVE_POSIX_REGEX=1 \ - -DCMAKE_INSTALL_PREFIX="/libcxx_native_build" \ - -DHAVE_STEADY_CLOCK=1 && \ - ninja distribution && \ - ninja install-distribution - -ENV SYMCC_NO_SYMBOLIC_INPUT=1 -ENV SYMCC_SILENT=1 diff --git a/fuzzers/symcc_aflplusplus_single/fuzzer.py b/fuzzers/symcc_aflplusplus_single/fuzzer.py deleted file mode 100644 index 15b4cfd02..000000000 --- a/fuzzers/symcc_aflplusplus_single/fuzzer.py +++ /dev/null @@ -1,104 +0,0 @@ -# Copyright 2021 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. -''' Uses the SymCC-AFL hybrid from SymCC. ''' - -import os -import time -import shutil -import threading -import subprocess - -from fuzzers import utils -from fuzzers.afl import fuzzer as afl_fuzzer -from fuzzers.aflplusplus import fuzzer as aflplusplus_fuzzer - - -def get_symcc_build_dir(target_directory): - """Return path to uninstrumented target directory.""" - return os.path.join(target_directory, 'uninstrumented') - - -def build(): - """Build an AFL version and SymCC version of the benchmark""" - print('Step 1: Building with AFL and SymCC') - build_directory = os.environ['OUT'] - - # First build with AFL. - src = os.getenv('SRC') - work = os.getenv('WORK') - with utils.restore_directory(src), utils.restore_directory(work): - # Restore SRC to its initial state so we can build again without any - # trouble. For some OSS-Fuzz projects, build_benchmark cannot be run - # twice in the same directory without this. - aflplusplus_fuzzer.build('tracepc', 'symcc') - - print('Step 2: Completed AFL build') - # Copy over AFL artifacts needed by SymCC. - shutil.copy('/afl/afl-fuzz', build_directory) - shutil.copy('/afl/afl-showmap', build_directory) - - # Copy over symcc artifacts and symbolic libc++. - print('Step 3: Copying SymCC files') - symcc_build_dir = get_symcc_build_dir(os.environ['OUT']) - shutil.copy( - '/symcc/build//SymRuntime-prefix/src/SymRuntime-build/libSymRuntime.so', - symcc_build_dir) - shutil.copy('/usr/lib/libz3.so', os.path.join(symcc_build_dir, 'libz3.so')) - shutil.copy('/libcxx_native_build/lib/libc++.so.1', symcc_build_dir) - shutil.copy('/libcxx_native_build/lib/libc++abi.so.1', symcc_build_dir) - shutil.copy('/rust/bin/symcc_fuzzing_helper', symcc_build_dir) - - -def launch_afl_thread(input_corpus, output_corpus, target_binary, - additional_flags): - """ Simple wrapper for running AFL. """ - afl_thread = threading.Thread(target=afl_fuzzer.run_afl_fuzz, - args=(input_corpus, output_corpus, - target_binary, additional_flags)) - afl_thread.start() - return afl_thread - - -def fuzz(input_corpus, output_corpus, target_binary): - """ - Launches a master and a secondary instance of AFL, as well as - the symcc helper. - """ - target_binary_dir = os.path.dirname(target_binary) - symcc_workdir = get_symcc_build_dir(target_binary_dir) - target_binary_name = os.path.basename(target_binary) - symcc_target_binary = os.path.join(symcc_workdir, target_binary_name) - - os.environ['AFL_DISABLE_TRIM'] = '1' - - # Start a master and secondary instance of AFL. - # We need both because of the way SymCC works. - print('[run_fuzzer] Running AFL for SymCC') - afl_fuzzer.prepare_fuzz_environment(input_corpus) - launch_afl_thread(input_corpus, output_corpus, target_binary, - ['-S', 'afl-secondary']) - time.sleep(5) - - # Start an instance of SymCC. - # We need to ensure it uses the symbolic version of libc++. - print('Starting the SymCC helper') - new_environ = os.environ.copy() - new_environ['LD_LIBRARY_PATH'] = symcc_workdir - cmd = [ - os.path.join(symcc_workdir, - 'symcc_fuzzing_helper'), '-o', output_corpus, '-a', - 'afl-secondary', '-n', 'symcc', '-m', '--', symcc_target_binary, '@@' - ] - with subprocess.Popen(cmd, env=new_environ): - pass diff --git a/fuzzers/symqemu_aflplusplus/builder.Dockerfile b/fuzzers/symqemu_aflplusplus/builder.Dockerfile deleted file mode 100644 index a15b9c410..000000000 --- a/fuzzers/symqemu_aflplusplus/builder.Dockerfile +++ /dev/null @@ -1,98 +0,0 @@ -# Copyright 2021 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 - -# Upgrade to avoid certs errors -RUN apt-get upgrade -y - -# Download and compile afl++. -RUN git clone https://github.com/AFLplusplus/AFLplusplus.git /afl && \ - cd /afl && \ - git checkout 8fc249d210ad49e3dd88d1409877ca64d9884690 - -# 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 / - -# Install the packages we need. -RUN apt-get install -y ninja-build flex bison python zlib1g-dev cargo - -# Install Z3 from binary -RUN wget -qO /tmp/z3x64.zip https://github.com/Z3Prover/z3/releases/download/z3-4.8.7/z3-4.8.7-x64-ubuntu-16.04.zip && \ - unzip -jd /usr/include /tmp/z3x64.zip "*/include/*.h" && \ - unzip -jd /usr/lib /tmp/z3x64.zip "*/bin/libz3.so" && \ - rm -f /tmp/*.zip && \ - ldconfig - -ENV CFLAGS="" -ENV CXXFLAGS="" - -# Get and install symcc. -RUN cd / && \ - git clone https://github.com/adalogics/adacc symcc && \ - cd symcc && \ - git checkout 70efb3ef512a12b31caedcfcd9c0890813cd797e && \ - cd ./runtime/qsym_backend && \ - git clone https://github.com/adalogics/qsym && \ - cd qsym && \ - git checkout adalogics && \ - cd /symcc && \ - mkdir build && \ - cd build && \ - cmake -G Ninja -DCMAKE_BUILD_TYPE=Release -DQSYM_BACKEND=ON \ - -DZ3_TRUST_SYSTEM_VERSION=ON ../ && \ - ninja -j 3 && \ - cd ../examples && \ - export SYMCC_PC=1 && \ - ../build/symcc -c ./libfuzz-harness-proxy.c -o /libfuzzer-harness.o && \ - cd ../ && echo "[+] Installing cargo now 4" && \ - cargo install --path util/symcc_fuzzing_helper - -RUN cd / && \ - wget https://raw.githubusercontent.com/llvm/llvm-project/5feb80e748924606531ba28c97fe65145c65372e/compiler-rt/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c -O /StandaloneFuzzTargetMain.c && \ - clang -O2 -c /StandaloneFuzzTargetMain.c && \ - ar rc /libStandaloneFuzzTarget.a StandaloneFuzzTargetMain.o && \ - rm /StandaloneFuzzTargetMain.c - -RUN git clone https://github.com/eurecom-s3/symqemu --depth 1 /symqemu/src -RUN mkdir /symqemu/build && \ - cd /symqemu/build && \ - ../src/configure \ - --audio-drv-list= \ - --disable-bluez \ - --disable-sdl \ - --disable-gtk \ - --disable-vte \ - --disable-opengl \ - --disable-virglrenderer \ - --target-list=x86_64-linux-user \ - --enable-capstone=git \ - --disable-werror \ - --symcc-source=/symcc/ \ - --symcc-build=/symcc/build && \ - make && \ - cd /symqemu && \ - rm -rf src diff --git a/fuzzers/symqemu_aflplusplus/fuzzer.py b/fuzzers/symqemu_aflplusplus/fuzzer.py deleted file mode 100644 index bb8e1c0ec..000000000 --- a/fuzzers/symqemu_aflplusplus/fuzzer.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright 2021 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. -''' Uses the SymCC-AFL hybrid from SymCC. ''' - -import os -import time -import shutil -import threading -import subprocess - -from fuzzers.afl import fuzzer as afl_fuzzer -from fuzzers.aflplusplus import fuzzer as aflplusplus_fuzzer - - -def get_symcc_build_dir(target_directory): - """Return path to uninstrumented target directory.""" - return os.path.join(target_directory, 'uninstrumented') - - -def build(): - """Build an AFL version and SymCC version of the benchmark""" - - # Backup the environment. - orig_env = os.environ.copy() - #src = os.getenv('SRC') - #work = os.getenv('WORK') - build_directory = os.getenv('OUT') - fuzz_target = os.getenv('FUZZ_TARGET') - - # First, build an uninstrumented binary for Eclipser. - aflplusplus_fuzzer.build('qemu', 'eclipser') - eclipser_dir = get_symcc_build_dir(build_directory) - os.mkdir(eclipser_dir) - fuzz_binary = build_directory + '/' + fuzz_target - shutil.copy(fuzz_binary, eclipser_dir) - if os.path.isdir(build_directory + '/seeds'): - shutil.rmtree(build_directory + '/seeds') - - # Second, build an instrumented binary for AFL++. - os.environ = orig_env - aflplusplus_fuzzer.build('tracepc') - print('[build] Copying afl-fuzz to $OUT directory') - - # Copy afl-fuzz - shutil.copy('/afl/afl-fuzz', build_directory) - shutil.copy('/afl/afl-showmap', build_directory) - shutil.copy('/rust/bin/symcc_fuzzing_helper', eclipser_dir) - - symcc_build_dir = get_symcc_build_dir(os.environ['OUT']) - - # Copy over symcc artifacts and symbolic libc++. - shutil.copy( - '/symcc/build//SymRuntime-prefix/src/SymRuntime-build/libSymRuntime.so', - symcc_build_dir) - shutil.copy('/usr/lib/libz3.so', os.path.join(symcc_build_dir, 'libz3.so')) - shutil.copy('/rust/bin/symcc_fuzzing_helper', symcc_build_dir) - shutil.copy('/symqemu/build/x86_64-linux-user/symqemu-x86_64', - symcc_build_dir) - - -def launch_afl_thread(input_corpus, output_corpus, target_binary, - additional_flags): - """ Simple wrapper for running AFL. """ - afl_thread = threading.Thread(target=afl_fuzzer.run_afl_fuzz, - args=(input_corpus, output_corpus, - target_binary, additional_flags)) - afl_thread.start() - return afl_thread - - -def fuzz(input_corpus, output_corpus, target_binary): - """ - Launches a master and a secondary instance of AFL, as well as - the symcc helper. - """ - target_binary_dir = os.path.dirname(target_binary) - symcc_workdir = get_symcc_build_dir(target_binary_dir) - target_binary_name = os.path.basename(target_binary) - symcc_target_binary = os.path.join(symcc_workdir, target_binary_name) - - os.environ['AFL_DISABLE_TRIM'] = '1' - - # Start a master and secondary instance of AFL. - # We need both because of the way SymCC works. - print('[run_fuzzer] Running AFL for SymCC') - afl_fuzzer.prepare_fuzz_environment(input_corpus) - launch_afl_thread(input_corpus, output_corpus, target_binary, - ['-S', 'afl-secondary']) - time.sleep(5) - - # Start an instance of SymCC. - # We need to ensure it uses the symbolic version of libc++. - symqemu_target = os.path.join(symcc_workdir, 'symqemu-x86_64') - if os.path.isfile(symqemu_target): - print('Found symqemu target') - else: - print('Did not find symqemu target') - - print('Starting the SymCC helper') - new_environ = os.environ.copy() - new_environ['LD_LIBRARY_PATH'] = symcc_workdir - cmd = [ - os.path.join(symcc_workdir, 'symcc_fuzzing_helper'), '-o', - output_corpus, '-a', 'afl-secondary', '-n', 'symqemu', '-m', '--', - symqemu_target, symcc_target_binary, '@@' - ] - print(f'Running command: {" ".join(cmd)}') - with subprocess.Popen(cmd, env=new_environ): - pass diff --git a/fuzzers/symqemu_aflplusplus/runner.Dockerfile b/fuzzers/symqemu_aflplusplus/runner.Dockerfile deleted file mode 100644 index e63ac957d..000000000 --- a/fuzzers/symqemu_aflplusplus/runner.Dockerfile +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright 2021 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 install -y wget -RUN sed -i -- 's/# deb-src/deb-src/g' /etc/apt/sources.list -#RUN echo deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main >> /etc/apt/sources.list && \ -# wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - -#RUN echo deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu xenial main >> /etc/apt/sources.list && \ -# apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 1E9377A2BA9EF27F -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 - -# Install the packages we need. -RUN apt-get install -y ninja-build python zlib1g-dev cargo - -RUN apt-get install -y \ - libtool \ - wget \ - automake \ - autoconf \ - bison \ - git \ - build-essential \ - gdb \ - g++ \ - cmake \ - cargo \ - rustc \ - sudo \ - joe \ - vim \ - zlib1g \ - zlib1g-dev \ - wget \ - bison \ - flex \ - gdb \ - strace -RUN apt-get build-dep -y qemu - -ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/out" - diff --git a/fuzzers/symsan/CMakeLists_bloaty.txt b/fuzzers/symsan/CMakeLists_bloaty.txt deleted file mode 100644 index 8132cf3ef..000000000 --- a/fuzzers/symsan/CMakeLists_bloaty.txt +++ /dev/null @@ -1,406 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -cmake_policy(SET CMP0048 NEW) -if(POLICY CMP0091) - cmake_policy(SET CMP0091 NEW) -endif() -project (Bloaty VERSION 1.1) -include(CTest) -set(CMAKE_CXX_STANDARD 17) -set_property(GLOBAL PROPERTY USE_FOLDERS ON) # Group projects in visual studio - -# Options we define for users. -option(BLOATY_ENABLE_ASAN "Enable address sanitizer." OFF) -option(BLOATY_ENABLE_UBSAN "Enable undefined behavior sanitizer." OFF) -option(BLOATY_ENABLE_CMAKETARGETS "Enable installing cmake target files." ON) -option(BLOATY_ENABLE_BUILDID "Enable build id." ON) -option(BLOATY_ENABLE_RE2 "Enable the support for regular expression functions." ON) -option(BLOATY_PREFER_SYSTEM_CAPSTONE "Prefer to use the system capstone if available" YES) - -if(UNIX OR MINGW) -find_package(PkgConfig) -find_package(ZLIB) -if(BLOATY_ENABLE_RE2) - pkg_search_module(RE2 re2) -endif() -if(BLOATY_PREFER_SYSTEM_CAPSTONE) - pkg_search_module(CAPSTONE capstone) -endif() -pkg_search_module(PROTOBUF protobuf) -if(BLOATY_ENABLE_RE2) - if(RE2_FOUND) - MESSAGE(STATUS "System re2 found, using") - else() - MESSAGE(STATUS "System re2 not found, using bundled version") - endif() -endif() -if(CAPSTONE_FOUND) - MESSAGE(STATUS "System capstone found, using") -else() - MESSAGE(STATUS "System capstone not found, using bundled version") -endif() -if(PROTOBUF_FOUND) - MESSAGE(STATUS "System protobuf found, using") -else() - MESSAGE(STATUS "System protobuf not found, using bundled version") -endif() -if (ZLIB_FOUND) - MESSAGE(STATUS "System zlib found, using") -else() - MESSAGE(STATUS "System zlib not found, using bundled version") -endif() -endif() - -# Set default build type. -if(NOT CMAKE_BUILD_TYPE) - message(STATUS "Setting build type to 'RelWithDebInfo' as none was specified.") - set(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING - "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." - FORCE) -endif() - -# Check out Git submodules. -if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.gitmodules") - execute_process (COMMAND git submodule update --init --recursive - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) -endif() - -# Add third_party libraries, disabling as much as we can of their builds. - -add_definitions(-D_LIBCXXABI_FUNC_VIS=) # For Demumble. -if(BLOATY_ENABLE_RE2) - add_definitions(-DUSE_RE2) -endif() - -# Set MSVC runtime before including thirdparty libraries -if(MSVC) - if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.15) - set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$:Debug>) - else() - # Link also the runtime library statically so that MSVCR*.DLL is not required at runtime. - # https://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx - # This is achieved by replacing msvc option /MD with /MT and /MDd with /MTd - # http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F - foreach(flag_var - CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE - CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO) - if (flag_var MATCHES "/MD") - string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") - endif() - endforeach() - endif() -endif() - -set(THREADS_PREFER_PTHREAD_FLAG TRUE) -find_package(Threads REQUIRED) - -if(UNIX OR MINGW) - if(BLOATY_ENABLE_RE2) - if(RE2_FOUND) - include_directories(${RE2_INCLUDE_DIRS}) - else() - set(RE2_BUILD_TESTING OFF CACHE BOOL "enable testing for RE2" FORCE) - add_subdirectory(third_party/re2) - include_directories(third_party/re2) - endif() - endif() - if(CAPSTONE_FOUND) - include_directories(${CAPSTONE_INCLUDE_DIRS}) - else() - set(CAPSTONE_BUILD_SHARED OFF CACHE BOOL "Build shared library" FORCE) - set(CAPSTONE_BUILD_TESTS OFF CACHE BOOL "Build tests" FORCE) - add_subdirectory(third_party/capstone) - include_directories(third_party/capstone/include) - endif() - if(PROTOBUF_FOUND) - include_directories(${PROTOBUF_INCLUDE_DIRS}) - else() - set(protobuf_BUILD_TESTS OFF CACHE BOOL "enable tests for proto2" FORCE) - set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "enable shared libs for proto2" FORCE) - add_subdirectory(third_party/protobuf/cmake) - include_directories(SYSTEM third_party/protobuf/src) - endif() - if(NOT ZLIB_FOUND) - add_subdirectory(third_party/zlib) - include_directories(SYSTEM third_party/zlib) - endif() -else() - if(BLOATY_ENABLE_RE2) - set(RE2_BUILD_TESTING OFF CACHE BOOL "enable testing for RE2" FORCE) - add_subdirectory(third_party/re2) - include_directories(third_party/re2) - set_property(TARGET re2 PROPERTY FOLDER "third_party") - endif() - - set(CAPSTONE_BUILD_SHARED OFF CACHE BOOL "Build shared library" FORCE) - set(CAPSTONE_BUILD_TESTS OFF CACHE BOOL "Build tests" FORCE) - add_subdirectory(third_party/capstone) - include_directories(third_party/capstone/include) - set_property(TARGET capstone-static PROPERTY FOLDER "third_party") - - set(protobuf_BUILD_TESTS OFF CACHE BOOL "enable tests for proto2" FORCE) - set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "enable shared libs for proto2" FORCE) - add_subdirectory(third_party/protobuf/cmake) - include_directories(SYSTEM third_party/protobuf/src) - - add_subdirectory(third_party/zlib) - include_directories(third_party/zlib) - include_directories(${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib) - set_property(TARGET example PROPERTY FOLDER "third_party") - set_property(TARGET minigzip PROPERTY FOLDER "third_party") - set_property(TARGET zlib PROPERTY FOLDER "third_party") - set_property(TARGET zlibstatic PROPERTY FOLDER "third_party") - set_property(TARGET libprotobuf PROPERTY FOLDER "third_party") - set_property(TARGET libprotobuf-lite PROPERTY FOLDER "third_party") - set_property(TARGET libprotoc PROPERTY FOLDER "third_party") - set_property(TARGET protoc PROPERTY FOLDER "third_party") -endif() - -include_directories(.) -include_directories(src) -include_directories(third_party/abseil-cpp) -include_directories("${CMAKE_CURRENT_BINARY_DIR}/src") - -# Baseline build flags. -if(MSVC) - set(CMAKE_CXX_FLAGS "/EHsc /wd4018 /D_CRT_SECURE_NO_WARNINGS /DNOMINMAX") -else() - set(CMAKE_CXX_FLAGS "-W -Wall -Wno-sign-compare") - set(CMAKE_CXX_FLAGS_DEBUG "-g1") - set(CMAKE_CXX_FLAGS_RELEASE "-O2") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g1") -endif() - -if(APPLE) -elseif(UNIX) - if(BLOATY_ENABLE_BUILDID) - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--build-id") - endif() -endif() - -# When using Ninja, compiler output won't be colorized without this. -include(CheckCXXCompilerFlag) -CHECK_CXX_COMPILER_FLAG(-fdiagnostics-color=always SUPPORTS_COLOR_ALWAYS) -if(SUPPORTS_COLOR_ALWAYS) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always") -endif() - -# Implement ASAN/UBSAN options -if(BLOATY_ENABLE_ASAN) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address") - set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fsanitize=address") -endif() - -if(BLOATY_ENABLE_UBSAN) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined") - set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fsanitize=undefined") -endif() - -if(DEFINED ENV{CXXFLAGS}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{CXXFLAGS}") -endif() - -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/src) -if(PROTOC_FOUND) -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/bloaty.pb.cc - DEPENDS protoc ${CMAKE_CURRENT_SOURCE_DIR}/src/bloaty.proto - COMMAND protoc ${CMAKE_CURRENT_SOURCE_DIR}/src/bloaty.proto - --cpp_out=${CMAKE_CURRENT_BINARY_DIR}/src - -I${CMAKE_CURRENT_SOURCE_DIR}/src -) -else() -add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/bloaty.pb.cc - COMMAND protoc ${CMAKE_CURRENT_SOURCE_DIR}/src/bloaty.proto - --cpp_out=${CMAKE_CURRENT_BINARY_DIR}/src - -I${CMAKE_CURRENT_SOURCE_DIR}/src -) -endif() - -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/src/bloaty_package.bloaty - DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) - -add_library(libbloaty STATIC - src/bloaty.cc - src/bloaty.h - src/disassemble.cc - ${CMAKE_CURRENT_BINARY_DIR}/src/bloaty.pb.cc - src/dwarf/attr.h - src/dwarf/attr.cc - src/dwarf/dwarf_util.cc - src/dwarf/debug_info.cc - src/dwarf/line_info.cc - src/dwarf.cc - src/dwarf_constants.h - src/eh_frame.cc - src/elf.cc - src/macho.cc - src/pe.cc - third_party/lief_pe/pe_structures.h - src/range_map.cc - src/range_map.h - src/re.h - src/util.cc - src/util.h - src/webassembly.cc - # Until Abseil has a proper CMake build system - third_party/abseil-cpp/absl/base/internal/raw_logging.cc # Grrrr... - third_party/abseil-cpp/absl/base/internal/throw_delegate.cc - third_party/abseil-cpp/absl/debugging/internal/demangle.cc - third_party/abseil-cpp/absl/numeric/int128.cc - third_party/abseil-cpp/absl/strings/ascii.cc - third_party/abseil-cpp/absl/strings/charconv.cc - third_party/abseil-cpp/absl/strings/escaping.cc - third_party/abseil-cpp/absl/strings/internal/charconv_bigint.cc - third_party/abseil-cpp/absl/strings/internal/charconv_parse.cc - third_party/abseil-cpp/absl/strings/internal/escaping.cc - third_party/abseil-cpp/absl/strings/internal/memutil.cc - third_party/abseil-cpp/absl/strings/internal/utf8.cc - third_party/abseil-cpp/absl/strings/match.cc - third_party/abseil-cpp/absl/strings/numbers.cc - third_party/abseil-cpp/absl/strings/str_cat.cc - third_party/abseil-cpp/absl/strings/string_view.cc - third_party/abseil-cpp/absl/strings/str_split.cc - third_party/abseil-cpp/absl/strings/substitute.cc - third_party/abseil-cpp/absl/types/bad_optional_access.cc - # One source file, no special build system needed. - ) -set_property(TARGET libbloaty PROPERTY FOLDER "bloaty") - -if(UNIX OR MINGW) - set(LIBBLOATY_LIBS libbloaty) - if(PROTOBUF_FOUND) - list(APPEND LIBBLOATY_LIBS ${PROTOBUF_LIBRARIES}) - else() - list(APPEND LIBBLOATY_LIBS libprotoc) - endif() - if(BLOATY_ENABLE_RE2) - if(RE2_FOUND) - list(APPEND LIBBLOATY_LIBS ${RE2_LIBRARIES}) - else() - list(APPEND LIBBLOATY_LIBS re2) - endif() - endif() - if(CAPSTONE_FOUND) - list(APPEND LIBBLOATY_LIBS ${CAPSTONE_LIBRARIES}) - else() - list(APPEND LIBBLOATY_LIBS capstone-static) - endif() - if(ZLIB_FOUND) - list(APPEND LIBBLOATY_LIBS ZLIB::ZLIB) - else() - list(APPEND LIBBLOATY_LIBS zlibstatic) - endif() -else() - set(LIBBLOATY_LIBS libbloaty libprotoc capstone-static) - if(BLOATY_ENABLE_RE2) - list(APPEND LIBBLOATY_LIBS re2) - endif() - list(APPEND LIBBLOATY_LIBS zlibstatic) -endif() - -if(UNIX OR MINGW) - if(BLOATY_ENABLE_RE2) - if(RE2_FOUND) - link_directories(${RE2_LIBRARY_DIRS}) - endif() - endif() - if(CAPSTONE_FOUND) - link_directories(${CAPSTONE_LIBRARY_DIRS}) - endif() - if(PROTOBUF_FOUND) - link_directories(${PROTOBUF_LIBRARY_DIRS}) - endif() -endif() - -list(APPEND LIBBLOATY_LIBS Threads::Threads) - -if(DEFINED ENV{LIB_FUZZING_ENGINE}) - message("LIB_FUZZING_ENGINE set, building fuzz_target instead of Bloaty") - add_executable(fuzz_target tests/fuzz_target.cc) - target_link_libraries(fuzz_target ${LIBBLOATY_LIBS} $ENV{LIB_FUZZING_ENGINE}) -else() - add_executable(bloaty src/main.cc) - target_link_libraries(bloaty ${LIBBLOATY_LIBS}) - - set_property(TARGET bloaty PROPERTY FOLDER "bloaty") - - if(BLOATY_ENABLE_CMAKETARGETS) - install( - TARGETS bloaty - EXPORT ${PROJECT_NAME}Targets - RUNTIME DESTINATION bin - ) - else() - install( - TARGETS bloaty - RUNTIME DESTINATION bin - ) - endif() - - if (IS_DIRECTORY "${PROJECT_SOURCE_DIR}/tests") - enable_testing() - - find_package(Python COMPONENTS Interpreter) - find_program(LIT_EXECUTABLE NAMES lit-script.py lit.py lit) - find_program(FILECHECK_EXECUTABLE FileCheck) - find_program(YAML2OBJ_EXECUTABLE yaml2obj) - if(Python_FOUND AND LIT_EXECUTABLE AND FILECHECK_EXECUTABLE AND YAML2OBJ_EXECUTABLE) - set(BLOATY_SRC_DIR ${PROJECT_SOURCE_DIR}) - set(BLOATY_OBJ_DIR ${PROJECT_BINARY_DIR}) - configure_file(tests/lit.site.cfg.in tests/lit.site.cfg @ONLY) - - add_custom_target(check-bloaty - COMMAND ${Python_EXECUTABLE} ${LIT_EXECUTABLE} -sv ${PROJECT_BINARY_DIR}/tests --param bloaty=$ - DEPENDS - bloaty - ${CMAKE_CURRENT_SOURCE_DIR}/tests/lit.cfg - ${CMAKE_CURRENT_BINARY_DIR}/tests/lit.site.cfg - COMMENT "Running bloaty tests..." - USES_TERMINAL) - set_property(TARGET check-bloaty PROPERTY FOLDER "tests") - endif() - - if(BUILD_TESTING) - option(INSTALL_GTEST "" OFF) - add_subdirectory(third_party/googletest) - include_directories(third_party/googletest/googletest/include) - include_directories(third_party/googletest/googlemock/include) - - set(TEST_TARGETS - bloaty_test - bloaty_test_pe - bloaty_misc_test - range_map_test - ) - - foreach(target ${TEST_TARGETS}) - add_executable(${target} tests/${target}.cc) - target_link_libraries(${target} ${LIBBLOATY_LIBS} gtest_main gmock) - set_property(TARGET ${target} PROPERTY FOLDER "tests") - endforeach(target) - - add_executable(fuzz_test tests/fuzz_target.cc tests/fuzz_driver.cc) - target_link_libraries(fuzz_test ${LIBBLOATY_LIBS}) - set_property(TARGET fuzz_test PROPERTY FOLDER "tests") - - foreach(testlib gmock gmock_main gtest gtest_main) - set_property(TARGET ${testlib} PROPERTY FOLDER "tests/libs") - endforeach(testlib) - - file(GLOB fuzz_corpus tests/testdata/fuzz_corpus/*) - - add_test(NAME range_map_test COMMAND range_map_test) - add_test(NAME bloaty_test_x86-64 COMMAND bloaty_test WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/linux-x86_64) - add_test(NAME bloaty_test_x86 COMMAND bloaty_test WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/linux-x86) - add_test(NAME bloaty_test_pe_x64 COMMAND bloaty_test_pe WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/PE/x64) - add_test(NAME bloaty_test_pe_x86 COMMAND bloaty_test_pe WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/PE/x86) - add_test(NAME bloaty_misc_test COMMAND bloaty_misc_test WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/misc) - add_test(NAME fuzz_test COMMAND fuzz_test ${fuzz_corpus} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests/testdata/fuzz_corpus) - endif() - endif() - - if(BLOATY_ENABLE_CMAKETARGETS) - install(EXPORT ${PROJECT_NAME}Targets NAMESPACE ${PROJECT_NAME} DESTINATION lib/${PROJECT_NAME}) - endif() -endif() diff --git a/fuzzers/symsan/build_freetype2.sh b/fuzzers/symsan/build_freetype2.sh deleted file mode 100755 index ae8d5831d..000000000 --- a/fuzzers/symsan/build_freetype2.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/bash -ex -# 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. - -INSTALL_DIR="$PWD/install" - -mkdir $OUT/seeds -# TRT/fonts is the full seed folder, but they're too big -cp TRT/fonts/TestKERNOne.otf $OUT/seeds/ -cp TRT/fonts/TestGLYFOne.ttf $OUT/seeds/ - -tar xf libarchive-3.4.3.tar.xz - -cd libarchive-3.4.3 -./configure --prefix="$INSTALL_DIR" --disable-shared --with-xml2=no -make clean -make -j $(nproc) -make install -cd .. - -cd freetype2 -./autogen.sh -./configure --with-harfbuzz=no --with-bzip2=no --with-png=no --without-zlib -make clean -make all -j $(nproc) - -$CXX $CXXFLAGS -std=c++11 -I"$INSTALL_DIR/include" -I include -I . src/tools/ftfuzzer/ftfuzzer.cc \ - objs/.libs/libfreetype.a $FUZZER_LIB -L"$INSTALL_DIR/lib" -larchive \ - -o $OUT/ftfuzzer diff --git a/fuzzers/symsan/build_proj.sh b/fuzzers/symsan/build_proj.sh deleted file mode 100644 index 169d196b2..000000000 --- a/fuzzers/symsan/build_proj.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -ex -# 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. - - -set -e - -if [ "$SRC" == "" ]; then - echo "SRC env var not defined" - exit 1 -fi - -if [ "$OUT" == "" ]; then - echo "OUT env var not defined" - exit 1 -fi - -if [ "$CXX" == "" ]; then - echo "CXX env var not defined" - exit 1 -fi - -if [ "$LIB_FUZZING_ENGINE" = "" ]; then - export LIB_FUZZING_ENGINE=-lFuzzingEngine -fi - -I386_PACKAGES="zlib1g-dev:i386 libssl-dev:i386 libsqlite3-dev:i386" -X64_PACKAGES="zlib1g-dev libssl-dev libsqlite3-dev" - -if [ "$ARCHITECTURE" = "i386" ]; then - apt-get install -y $I386_PACKAGES -else - apt-get install -y $X64_PACKAGES -fi - -# build libcurl.a (builing against Ubuntu libcurl.a doesn't work easily) -cd curl -autoreconf -i -./configure --disable-shared --without-ssl --prefix=$SRC/install -make clean -s -make -j$(nproc) -s -make install -cd .. - -# build libtiff.a -cd libtiff -./autogen.sh -./configure --disable-shared --prefix=$SRC/install -make -j$(nproc) -make install -cd .. - -mkdir build -cd build -cmake .. -DBUILD_SHARED_LIBS:BOOL=OFF \ - -DCURL_INCLUDE_DIR:PATH="$SRC/install/include" \ - -DCURL_LIBRARY_RELEASE:FILEPATH="$SRC/install/lib/libcurl.a" \ - -DTIFF_INCLUDE_DIR:PATH="$SRC/install/include" \ - -DTIFF_LIBRARY_RELEASE:FILEPATH="$SRC/install/lib/libtiff.a" \ - -DCMAKE_INSTALL_PREFIX=$SRC/install \ - -DBUILD_APPS:BOOL=OFF \ - -DBUILD_TESTING:BOOL=OFF -make clean -s -make -j$(nproc) -s -make install -cd .. - -EXTRA_LIBS="-lpthread -Wl,-Bstatic -lsqlite3 -L$SRC/install/lib -ltiff -lcurl -lssl -lcrypto -lz -Wl,-Bdynamic" - -build_fuzzer() -{ - fuzzerName=$1 - sourceFilename=$2 - shift - shift - echo "Building fuzzer $fuzzerName" - $CXX $CXXFLAGS -std=c++11 -fvisibility=hidden -llzma -Isrc -Iinclude \ - $sourceFilename $* -o $OUT/$fuzzerName \ - $LIB_FUZZING_ENGINE "$SRC/install/lib/libproj.a" $EXTRA_LIBS -} - -build_fuzzer proj_crs_to_crs_fuzzer test/fuzzers/proj_crs_to_crs_fuzzer.cpp - -echo "[libfuzzer]" > $OUT/proj_crs_to_crs_fuzzer.options -echo "max_len = 10000" >> $OUT/proj_crs_to_crs_fuzzer.options - -cp -r data/* $OUT diff --git a/fuzzers/symsan/builder.Dockerfile b/fuzzers/symsan/builder.Dockerfile deleted file mode 100644 index 8b9094f24..000000000 --- a/fuzzers/symsan/builder.Dockerfile +++ /dev/null @@ -1,59 +0,0 @@ -# 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=gcr.io/fuzzbench/base-builder -ARG parent_image -FROM $parent_image - -RUN apt-get update -y && \ - apt-get -y install wget python3-dev python3-setuptools apt-transport-https \ - libboost-all-dev texinfo libz3-dev \ - build-essential automake flex bison libglib2.0-dev libpixman-1-dev libgtk-3-dev ninja-build libnl-genl-3-dev \ - lsb-release software-properties-common autoconf curl zlib1g-dev cmake protobuf-compiler libprotobuf-dev - -RUN if [ -x "$(command -v rustc)" ]; then rustup self uninstall -y; fi -RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y - -RUN wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && ./llvm.sh 12 - -# Download and compile afl++. -RUN git clone https://github.com/AFLplusplus/AFLplusplus.git /afl && \ - cd /afl && \ - git checkout 33eba1fc5652060e8d877b02135fce2325813d0c && \ - unset CFLAGS && unset CXXFLAGS && \ - export CC=clang && export AFL_NO_X86=1 && \ - PYTHON_INCLUDE=/ make && make install && \ - cp utils/aflpp_driver/libAFLDriver.a / - -ENV PATH="/out/bin:${PATH}" -ENV PATH="/root/.cargo/bin:${PATH}" -RUN cp /usr/local/lib/libpython3.8.so.1.0 /out/ - -RUN git clone https://github.com/chenju2k6/symsan /symsan - -RUN apt-get install -y libc++abi-12-dev libc++-12-dev libunwind-dev - -RUN cd /symsan && git checkout jigsaw && \ - unset CFLAGS && \ - unset CXXFLAGS && \ - mkdir build && \ - cd build && \ - CC=clang-12 CXX=clang++-12 cmake -DCMAKE_INSTALL_PREFIX=. ../ && \ - make -j && make install && \ - cd ../fuzzer/cpp_core && mkdir build && cd build && cmake .. && make -j && \ - cd ../../../ && cargo build --release && \ - cp target/release/libruntime_fast.a build/lib/symsan - -COPY libfuzz-harness-proxy.c / -RUN KO_DONT_OPTIMIZE=1 USE_TRACK=1 KO_CC=clang-12 KO_USE_FASTGEN=1 /symsan/build/bin/ko-clang -c /libfuzz-harness-proxy.c -o /libfuzzer-harness.o -RUN KO_DONT_OPTIMIZE=1 KO_CC=clang-12 /symsan/build/bin/ko-clang -c /libfuzz-harness-proxy.c -o /libfuzzer-harness-fast.o diff --git a/fuzzers/symsan/bz2.abilist b/fuzzers/symsan/bz2.abilist deleted file mode 100644 index 934f4b876..000000000 --- a/fuzzers/symsan/bz2.abilist +++ /dev/null @@ -1,33 +0,0 @@ -fun:BZ2_blockSort=uninstrumented -fun:BZ2_bsInitWrite=uninstrumented -fun:BZ2_bzBuffToBuffCompress=uninstrumented -fun:BZ2_bzBuffToBuffDecompress=uninstrumented -fun:BZ2_bzCompress=uninstrumented -fun:BZ2_bzCompressEnd=uninstrumented -fun:BZ2_bzCompressInit=uninstrumented -fun:BZ2_bzDecompress=uninstrumented -fun:BZ2_bzDecompressEnd=uninstrumented -fun:BZ2_bzDecompressInit=uninstrumented -fun:BZ2_bzRead=uninstrumented -fun:BZ2_bzReadClose=uninstrumented -fun:BZ2_bzReadGetUnused=uninstrumented -fun:BZ2_bzReadOpen=uninstrumented -fun:BZ2_bzWrite=uninstrumented -fun:BZ2_bzWriteClose=uninstrumented -fun:BZ2_bzWriteClose64=uninstrumented -fun:BZ2_bzWriteOpen=uninstrumented -fun:BZ2_bz__AssertH__fail=uninstrumented -fun:BZ2_bzclose=uninstrumented -fun:BZ2_bzdopen=uninstrumented -fun:BZ2_bzerror=uninstrumented -fun:BZ2_bzflush=uninstrumented -fun:BZ2_bzlibVersion=uninstrumented -fun:BZ2_bzopen=uninstrumented -fun:BZ2_bzread=uninstrumented -fun:BZ2_bzwrite=uninstrumented -fun:BZ2_compressBlock=uninstrumented -fun:BZ2_decompress=uninstrumented -fun:BZ2_hbAssignCodes=uninstrumented -fun:BZ2_hbCreateDecodeTables=uninstrumented -fun:BZ2_hbMakeCodeLengths=uninstrumented -fun:BZ2_indexIntoF=uninstrumented diff --git a/fuzzers/symsan/cares.abilist b/fuzzers/symsan/cares.abilist deleted file mode 100644 index 471278b70..000000000 --- a/fuzzers/symsan/cares.abilist +++ /dev/null @@ -1,89 +0,0 @@ -fun:ares__bitncmp=uninstrumented -fun:ares__close_sockets=uninstrumented -fun:ares__destroy_servers_state=uninstrumented -fun:ares__expand_name_for_response=uninstrumented -fun:ares__free_query=uninstrumented -fun:ares__generate_new_id=uninstrumented -fun:ares__get_hostent=uninstrumented -fun:ares__init_list_head=uninstrumented -fun:ares__init_list_node=uninstrumented -fun:ares__init_servers_state=uninstrumented -fun:ares__insert_in_list=uninstrumented -fun:ares__is_list_empty=uninstrumented -fun:ares__is_onion_domain=uninstrumented -fun:ares__read_line=uninstrumented -fun:ares__remove_from_list=uninstrumented -fun:ares__send_query=uninstrumented -fun:ares__socket_close=uninstrumented -fun:ares__timedout=uninstrumented -fun:ares__tvnow=uninstrumented -fun:ares_cancel=uninstrumented -fun:ares_create_query=uninstrumented -fun:ares_destroy=uninstrumented -fun:ares_destroy_options=uninstrumented -fun:ares_dup=uninstrumented -fun:ares_expand_name=uninstrumented -fun:ares_expand_string=uninstrumented -fun:ares_fds=uninstrumented -fun:ares_free_data=uninstrumented -fun:ares_free_hostent=uninstrumented -fun:ares_free_string=uninstrumented -fun:ares_get_servers=uninstrumented -fun:ares_get_servers_ports=uninstrumented -fun:ares_gethostbyaddr=uninstrumented -fun:ares_gethostbyname=uninstrumented -fun:ares_gethostbyname_file=uninstrumented -fun:ares_getnameinfo=uninstrumented -fun:ares_getsock=uninstrumented -fun:ares_inet_net_pton=uninstrumented -fun:ares_inet_ntop=uninstrumented -fun:ares_inet_pton=uninstrumented -fun:ares_init=uninstrumented -fun:ares_init_options=uninstrumented -fun:ares_library_cleanup=uninstrumented -fun:ares_library_init=uninstrumented -fun:ares_library_init_mem=uninstrumented -fun:ares_library_initialized=uninstrumented -fun:ares_malloc_data=uninstrumented -fun:ares_mkquery=uninstrumented -fun:ares_parse_a_reply=uninstrumented -fun:ares_parse_aaaa_reply=uninstrumented -fun:ares_parse_mx_reply=uninstrumented -fun:ares_parse_naptr_reply=uninstrumented -fun:ares_parse_ns_reply=uninstrumented -fun:ares_parse_ptr_reply=uninstrumented -fun:ares_parse_soa_reply=uninstrumented -fun:ares_parse_srv_reply=uninstrumented -fun:ares_parse_txt_reply=uninstrumented -fun:ares_parse_txt_reply_ext=uninstrumented -fun:ares_process=uninstrumented -fun:ares_process_fd=uninstrumented -fun:ares_query=uninstrumented -fun:ares_save_options=uninstrumented -fun:ares_search=uninstrumented -fun:ares_send=uninstrumented -fun:ares_set_local_dev=uninstrumented -fun:ares_set_local_ip4=uninstrumented -fun:ares_set_local_ip6=uninstrumented -fun:ares_set_servers=uninstrumented -fun:ares_set_servers_csv=uninstrumented -fun:ares_set_servers_ports=uninstrumented -fun:ares_set_servers_ports_csv=uninstrumented -fun:ares_set_socket_callback=uninstrumented -fun:ares_set_socket_configure_callback=uninstrumented -fun:ares_set_socket_functions=uninstrumented -fun:ares_set_sortlist=uninstrumented -fun:ares_strdup=uninstrumented -fun:ares_strerror=uninstrumented -fun:ares_strsplit=uninstrumented -fun:ares_strsplit_free=uninstrumented -fun:ares_timeout=uninstrumented -fun:ares_version=uninstrumented -fun:aresx_sitoss=uninstrumented -fun:aresx_sitous=uninstrumented -fun:aresx_sltosi=uninstrumented -fun:aresx_sztosi=uninstrumented -fun:aresx_sztoui=uninstrumented -fun:aresx_uztosi=uninstrumented -fun:aresx_uztosl=uninstrumented -fun:aresx_uztoss=uninstrumented diff --git a/fuzzers/symsan/fres.sh b/fuzzers/symsan/fres.sh deleted file mode 100755 index 28bbf62e0..000000000 --- a/fuzzers/symsan/fres.sh +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright 2021 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. -#!/bin/bash -RUST_LOG=info /out/fastgen --sync_afl -i - -o /out/corpus -t $1 -- $2 @@ diff --git a/fuzzers/symsan/fuz.sh b/fuzzers/symsan/fuz.sh deleted file mode 100755 index 6190c4bc9..000000000 --- a/fuzzers/symsan/fuz.sh +++ /dev/null @@ -1,13 +0,0 @@ -# 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. -#!/bin/bash -RUST_LOG=info /out/fastgen --sync_afl -i /out/seeds -o /out/corpus -t $1 -- $2 @@ diff --git a/fuzzers/symsan/fuzzer.py b/fuzzers/symsan/fuzzer.py deleted file mode 100644 index 87649ffe2..000000000 --- a/fuzzers/symsan/fuzzer.py +++ /dev/null @@ -1,350 +0,0 @@ -# Copyright 2021 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. -''' Uses the SymSan-AFL hybrid from SymSan. ''' - -import shutil -import glob -import os -import subprocess -import threading - -from fuzzers.afl import fuzzer as afl_fuzzer -from fuzzers.aflplusplus import fuzzer as aflplusplus_fuzzer - -# Helper library that contains important functions for building. -from fuzzers import utils - -OSS_FUZZ_LIB_FUZZING_ENGINE_PATH = '/usr/lib/libFuzzingEngine.a' - - -def build_benchmark_symsan(env, benchmark_name): - """Build a benchmark using fuzzer library.""" - if not env: - env = os.environ.copy() - - # Add OSS-Fuzz environment variable for fuzzer library. - fuzzer_lib = env['FUZZER_LIB'] - env['LIB_FUZZING_ENGINE'] = fuzzer_lib - if os.path.exists(fuzzer_lib): - # Make /usr/lib/libFuzzingEngine.a point to our library for OSS-Fuzz - # so we can build projects that are using -lFuzzingEngine. - shutil.copy(fuzzer_lib, OSS_FUZZ_LIB_FUZZING_ENGINE_PATH) - - build_script_name = 'build_' + benchmark_name + '.sh' - build_script = os.path.join('/src/fuzzers/symsan', build_script_name) - - benchmark = os.getenv('BENCHMARK') - fuzzer = os.getenv('FUZZER') - print(f'Building benchmark {benchmark} with fuzzer {fuzzer}') - subprocess.check_call(['/bin/bash', '-ex', build_script], env=env) - - -def is_benchmark(name): - """Check the benchmark under built.""" - benchmark = os.getenv('BENCHMARK', None) - return benchmark is not None and name in benchmark - - -def get_symsan_build_dir(target_directory): - """Return path to CmpLog target directory.""" - return os.path.join(target_directory, 'symsantrack') - - -def get_symsan_build_fast_dir(target_directory): - """Return path to CmpLog target directory.""" - return os.path.join(target_directory, 'symsanfast') - - -def get_cmplog_build_directory(target_directory): - """Return path to CmpLog target directory.""" - return os.path.join(target_directory, 'cmplog') - - -def fix_flags(new_env): - """Fix symsan/symsan_fast build flags""" - new_env['CC'] = '/symsan/build/bin/ko-clang' - new_env['CXX'] = '/symsan/build/bin/ko-clang++' - new_env['KO_CC'] = 'clang-12' - new_env['KO_CXX'] = 'clang++-12' - if not is_benchmark('libjpeg'): - new_env['CXXFLAGS'] = '' - new_env['CFLAGS'] = '' - if is_benchmark('libpcap'): - new_env['CXXFLAGS'] = '-libverbs' - if is_benchmark('libgit'): - new_env['CXXFLAGS'] = '-lpcre' - if is_benchmark('file_magic'): - new_env['CXXFLAGS'] = '-llzma' - if is_benchmark('wireshark'): - new_env['CXXFLAGS'] = '-llzma -licuuc' - - if is_benchmark('curl_curl_fuzzer_http'): - new_env['SANITIZER'] = 'memory' - if is_benchmark('libxslt_xpath'): - new_env['SANITIZER'] = 'memory' - if is_benchmark('openssl_x509'): - new_env['CFLAGS'] = '-fsanitize=memory' - - -def fix_abilist(): - """Fix abilist for symsan""" - if is_benchmark('proj'): - with open('/symsan/build/lib/symsan/dfsan_abilist.txt', - 'a', - encoding='utf-8') as abilist: - abilist.write('fun:sqlite3_*=uninstrumented\n') - abilist.write('fun:sqlite3_*=discard\n') - if is_benchmark('bloaty'): - with open('/symsan/build/lib/symsan/dfsan_abilist.txt', - 'a', - encoding='utf-8') as abilist: - abilist.write('fun:*google8protobuf*=uninstrumented\n') - if is_benchmark('libarchive'): - with open('/symsan/build/lib/symsan/dfsan_abilist.txt', - 'a', - encoding='utf-8') as abilist: - with open('/src/fuzzers/symsan/xml.abilist', 'r', - encoding='utf-8') as xml: - abilist.write(xml.read()) - with open('/src/fuzzers/symsan/bz2.abilist', 'r', - encoding='utf-8') as bz2: - abilist.write(bz2.read()) - if is_benchmark('libgit'): - with open('/symsan/build/lib/symsan/dfsan_abilist.txt', - 'a', - encoding='utf-8') as abilist: - with open('/src/fuzzers/symsan/pcre.abilist', 'r', - encoding='utf-8') as pcre: - abilist.write(pcre.read()) - if is_benchmark('wireshark'): - with open('/symsan/build/lib/symsan/dfsan_abilist.txt', - 'a', - encoding='utf-8') as abilist: - with open('/src/fuzzers/symsan/gcry.abilist', 'r', - encoding='utf-8') as gcry: - abilist.write(gcry.read()) - with open('/src/fuzzers/symsan/cares.abilist', - 'r', - encoding='utf-8') as cares: - abilist.write(cares.read()) - with open('/src/fuzzers/symsan/glib.abilist', 'r', - encoding='utf-8') as glib: - abilist.write(glib.read()) - with open('/src/fuzzers/symsan/xml.abilist', 'r', - encoding='utf-8') as xml: - abilist.write(xml.read()) - - -def build_symsan_fast(build_directory, src, work): - """Build symsan fast binaries.""" - symsan_build_fast_directory = get_symsan_build_fast_dir(build_directory) - os.mkdir(symsan_build_fast_directory) - - new_env = os.environ.copy() - - fix_flags(new_env) - new_env['KO_USE_NATIVE_LIBCXX'] = '1' - new_env['FUZZER_LIB'] = '/libfuzzer-harness-fast.o' - new_env['OUT'] = symsan_build_fast_directory - new_env['KO_DONT_OPTIMIZE'] = '1' - new_env['CXXFLAGS'] = new_env['CXXFLAGS'] + ' -stdlib=libc++' - - fuzz_target = os.getenv('FUZZ_TARGET') - if fuzz_target: - new_env['FUZZ_TARGET'] = os.path.join(symsan_build_fast_directory, - os.path.basename(fuzz_target)) - - with utils.restore_directory(src), utils.restore_directory(work): - if is_benchmark('freetype2_ftfuzzer'): - build_benchmark_symsan(new_env, 'freetype2') - elif is_benchmark('proj'): - build_benchmark_symsan(new_env, 'proj') - elif is_benchmark('bloaty'): - shutil.copy('/src/fuzzers/symsan/CMakeLists_bloaty.txt', - '/src/bloaty/CMakeLists.txt') - utils.build_benchmark(env=new_env) - else: - utils.build_benchmark(env=new_env) - - -def build_symsan(build_directory, src, work): - """Build symsan track binaries.""" - symsan_build_directory = get_symsan_build_dir(build_directory) - os.mkdir(symsan_build_directory) - new_env = os.environ.copy() - - fix_flags(new_env) - fix_abilist() - new_env['FUZZER_LIB'] = '/libfuzzer-harness.o' - new_env['OUT'] = symsan_build_directory - new_env['KO_DONT_OPTIMIZE'] = '1' - new_env['USE_TRACK'] = '1' - new_env['KO_USE_FASTGEN'] = '1' - # For CmpLog build, set the OUT and FUZZ_TARGET environment - # variable to point to the new CmpLog build directory. - fuzz_target = os.getenv('FUZZ_TARGET') - if fuzz_target: - new_env['FUZZ_TARGET'] = os.path.join(symsan_build_directory, - os.path.basename(fuzz_target)) - - with utils.restore_directory(src), utils.restore_directory(work): - if is_benchmark('freetype2_ftfuzzer'): - build_benchmark_symsan(new_env, 'freetype2') - elif is_benchmark('proj'): - build_benchmark_symsan(new_env, 'proj') - elif is_benchmark('bloaty'): - shutil.copy('/src/fuzzers/symsan/CMakeLists_bloaty.txt', - '/src/bloaty/CMakeLists.txt') - utils.build_benchmark(env=new_env) - else: - utils.build_benchmark(env=new_env) - - -def update_protobuf(): - """Update protobuf version to 3.9.1""" - command = [ - 'wget', '-P', '/src', - 'https://github.com/protocolbuffers/protobuf/releases/\ -download/v3.9.1/protobuf-cpp-3.9.1.tar.gz' - ] - subprocess.check_call(command) - command = ['tar', '-xvf', 'protobuf-cpp-3.9.1.tar.gz'] - subprocess.check_call(command, cwd='/src') - command = ['./autogen.sh'] - subprocess.check_call(command, cwd='/src/protobuf-3.9.1') - command = ['./configure'] - subprocess.check_call(command, cwd='/src/protobuf-3.9.1') - command = ['make'] - subprocess.check_call(command, cwd='/src/protobuf-3.9.1') - command = ['make', 'install'] - subprocess.check_call(command, cwd='/src/protobuf-3.9.1') - command = ['ldconfig'] - subprocess.check_call(command) - for filename in glob.glob('/usr/lib/x86_64-linux-gnu/libprotobuf*'): - os.remove(filename) - - -def build(): # pylint: disable=too-many-branches,too-many-statements - """Build benchmark.""" - # BUILD_MODES is not already supported by fuzzbench, meanwhile we provide - # a default configuration. - - src = os.getenv('SRC') - work = os.getenv('WORK') - build_directory = os.environ['OUT'] - - if is_benchmark('bloaty'): - update_protobuf() - - if is_benchmark('libpcap_fuzz_both'): - os.environ['CXXFLAGS'] = os.environ['CXXFLAGS'] + ' -libverbs' - if is_benchmark('libgit'): - os.environ['CXXFLAGS'] = os.environ['CXXFLAGS'] + ' -lpcre' - if is_benchmark('file_magic'): - os.environ['CXXFLAGS'] = os.environ['CXXFLAGS'] + ' -llzma' - if is_benchmark('wireshark'): - os.environ['CXXFLAGS'] = os.environ['CXXFLAGS'] + ' -llzma -licuuc' - - with utils.restore_directory(src), utils.restore_directory(work): - if is_benchmark('njs') or is_benchmark('muparser') or is_benchmark( - 'bloaty'): - os.remove('/usr/local/lib/libc++.a') - os.remove('/usr/local/lib/libc++abi.a') - build_symsan(build_directory, src, work) - build_symsan_fast(build_directory, src, work) - aflplusplus_fuzzer.build('tracepc', 'cmplog', 'dict2file') - - shutil.copy('/symsan/target/release/fastgen', os.environ['OUT']) - - -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 launch_afl_thread(input_corpus, output_corpus, target_binary, - additional_flags): - """ Simple wrapper for running AFL. """ - afl_thread = threading.Thread(target=afl_fuzzer.run_afl_fuzz, - args=(input_corpus, output_corpus, - target_binary, additional_flags)) - afl_thread.start() - return afl_thread - - -def fuzz(input_corpus, output_corpus, target_binary, flags=tuple(), skip=False): - """Run fuzzer.""" - # Calculate CmpLog binary path from the instrumented target binary. - target_binary_directory = os.path.dirname(target_binary) - cmplog_target_binary_directory = ( - get_cmplog_build_directory(target_binary_directory)) - target_binary_name = os.path.basename(target_binary) - cmplog_target_binary = os.path.join(cmplog_target_binary_directory, - target_binary_name) - - target_binary_name = os.path.basename(target_binary) - - symsantrack_binary = os.path.join( - get_symsan_build_dir(target_binary_directory), target_binary_name) - symsanfast_binary = os.path.join( - get_symsan_build_fast_dir(target_binary_directory), target_binary_name) - - afl_fuzzer.prepare_fuzz_environment(input_corpus) - # decomment this to enable libdislocator. - # os.environ['AFL_ALIGNED_ALLOC'] = '1' # align malloc to max_align_t - # os.environ['AFL_PRELOAD'] = '/afl/libdislocator.so' - - flags = list(flags) - - if os.path.exists('./afl++.dict'): - flags += ['-x', './afl++.dict'] - # Move the following to skip for upcoming _double tests: - if os.path.exists(cmplog_target_binary): - flags += ['-c', cmplog_target_binary] - - if not skip: - if not flags or not flags[0] == '-Q' and '-p' not in flags: - flags += ['-p', 'fast'] - if ((not flags or (not '-l' in flags and not '-R' in flags)) and - os.path.exists(cmplog_target_binary)): - flags += ['-l', '2'] - os.environ['AFL_DISABLE_TRIM'] = '1' - if 'ADDITIONAL_ARGS' in os.environ: - flags += os.environ['ADDITIONAL_ARGS'].split(' ') - print('target binary is ' + target_binary) - #run fastgen - fastgen_cmd = [ - '/bin/bash', '-ex', '/out/fuz.sh', symsantrack_binary, symsanfast_binary - ] - fastgen_restart_cmd = [ - '/bin/bash', '-ex', '/out/fres.sh', symsantrack_binary, - symsanfast_binary - ] - - launch_afl_thread(input_corpus, - output_corpus, - target_binary, - additional_flags=flags) - - with subprocess.Popen(fastgen_cmd, stdout=None, stderr=None) as ori: - ori.wait() - - while True: - with subprocess.Popen(fastgen_restart_cmd, stdout=None, - stderr=None) as res: - res.wait() diff --git a/fuzzers/symsan/gcry.abilist b/fuzzers/symsan/gcry.abilist deleted file mode 100644 index 4e9720567..000000000 --- a/fuzzers/symsan/gcry.abilist +++ /dev/null @@ -1,877 +0,0 @@ -fun:__gcry_burn_stack=uninstrumented -fun:_gcry_3des_amd64_cbc_dec=uninstrumented -fun:_gcry_3des_amd64_cfb_dec=uninstrumented -fun:_gcry_3des_amd64_crypt_block=uninstrumented -fun:_gcry_3des_amd64_ctr_enc=uninstrumented -fun:_gcry_3des_cbc_dec=uninstrumented -fun:_gcry_3des_cfb_dec=uninstrumented -fun:_gcry_3des_ctr_enc=uninstrumented -fun:_gcry_Camellia_DecryptBlock=uninstrumented -fun:_gcry_Camellia_Ekeygen=uninstrumented -fun:_gcry_Camellia_EncryptBlock=uninstrumented -fun:_gcry_aes_aesni_cbc_dec=uninstrumented -fun:_gcry_aes_aesni_cbc_enc=uninstrumented -fun:_gcry_aes_aesni_cfb_dec=uninstrumented -fun:_gcry_aes_aesni_cfb_enc=uninstrumented -fun:_gcry_aes_aesni_ctr_enc=uninstrumented -fun:_gcry_aes_aesni_decrypt=uninstrumented -fun:_gcry_aes_aesni_do_setkey=uninstrumented -fun:_gcry_aes_aesni_encrypt=uninstrumented -fun:_gcry_aes_aesni_ocb_auth=uninstrumented -fun:_gcry_aes_aesni_ocb_crypt=uninstrumented -fun:_gcry_aes_aesni_prepare_decryption=uninstrumented -fun:_gcry_aes_amd64_decrypt_block=uninstrumented -fun:_gcry_aes_amd64_encrypt_block=uninstrumented -fun:_gcry_aes_cbc_dec=uninstrumented -fun:_gcry_aes_cbc_enc=uninstrumented -fun:_gcry_aes_cfb_dec=uninstrumented -fun:_gcry_aes_cfb_enc=uninstrumented -fun:_gcry_aes_ctr_enc=uninstrumented -fun:_gcry_aes_ocb_auth=uninstrumented -fun:_gcry_aes_ocb_crypt=uninstrumented -fun:_gcry_aes_padlock_decrypt=uninstrumented -fun:_gcry_aes_padlock_encrypt=uninstrumented -fun:_gcry_aes_ssse3_cbc_dec=uninstrumented -fun:_gcry_aes_ssse3_cbc_enc=uninstrumented -fun:_gcry_aes_ssse3_cfb_dec=uninstrumented -fun:_gcry_aes_ssse3_cfb_enc=uninstrumented -fun:_gcry_aes_ssse3_ctr_enc=uninstrumented -fun:_gcry_aes_ssse3_dec_preload=uninstrumented -fun:_gcry_aes_ssse3_decrypt=uninstrumented -fun:_gcry_aes_ssse3_decrypt_core=uninstrumented -fun:_gcry_aes_ssse3_do_setkey=uninstrumented -fun:_gcry_aes_ssse3_enc_preload=uninstrumented -fun:_gcry_aes_ssse3_encrypt=uninstrumented -fun:_gcry_aes_ssse3_encrypt_core=uninstrumented -fun:_gcry_aes_ssse3_ocb_auth=uninstrumented -fun:_gcry_aes_ssse3_ocb_crypt=uninstrumented -fun:_gcry_aes_ssse3_prepare_decryption=uninstrumented -fun:_gcry_aes_ssse3_schedule_core=uninstrumented -fun:_gcry_arcfour_amd64=uninstrumented -fun:_gcry_assert_failed=uninstrumented -fun:_gcry_blake2_init_with_key=uninstrumented -fun:_gcry_blowfish_amd64_cbc_dec=uninstrumented -fun:_gcry_blowfish_amd64_cfb_dec=uninstrumented -fun:_gcry_blowfish_amd64_ctr_enc=uninstrumented -fun:_gcry_blowfish_amd64_decrypt_block=uninstrumented -fun:_gcry_blowfish_amd64_do_encrypt=uninstrumented -fun:_gcry_blowfish_amd64_encrypt_block=uninstrumented -fun:_gcry_blowfish_cbc_dec=uninstrumented -fun:_gcry_blowfish_cfb_dec=uninstrumented -fun:_gcry_blowfish_ctr_enc=uninstrumented -fun:_gcry_bug=uninstrumented -fun:_gcry_calloc=uninstrumented -fun:_gcry_calloc_secure=uninstrumented -fun:_gcry_camellia_aesni_avx2_cbc_dec=uninstrumented -fun:_gcry_camellia_aesni_avx2_cfb_dec=uninstrumented -fun:_gcry_camellia_aesni_avx2_ctr_enc=uninstrumented -fun:_gcry_camellia_aesni_avx2_ocb_auth=uninstrumented -fun:_gcry_camellia_aesni_avx2_ocb_dec=uninstrumented -fun:_gcry_camellia_aesni_avx2_ocb_enc=uninstrumented -fun:_gcry_camellia_aesni_avx_cbc_dec=uninstrumented -fun:_gcry_camellia_aesni_avx_cfb_dec=uninstrumented -fun:_gcry_camellia_aesni_avx_ctr_enc=uninstrumented -fun:_gcry_camellia_aesni_avx_keygen=uninstrumented -fun:_gcry_camellia_aesni_avx_ocb_auth=uninstrumented -fun:_gcry_camellia_aesni_avx_ocb_dec=uninstrumented -fun:_gcry_camellia_aesni_avx_ocb_enc=uninstrumented -fun:_gcry_camellia_cbc_dec=uninstrumented -fun:_gcry_camellia_cfb_dec=uninstrumented -fun:_gcry_camellia_ctr_enc=uninstrumented -fun:_gcry_camellia_decrypt128=uninstrumented -fun:_gcry_camellia_decrypt256=uninstrumented -fun:_gcry_camellia_encrypt128=uninstrumented -fun:_gcry_camellia_encrypt256=uninstrumented -fun:_gcry_camellia_ocb_auth=uninstrumented -fun:_gcry_camellia_ocb_crypt=uninstrumented -fun:_gcry_camellia_setup128=uninstrumented -fun:_gcry_camellia_setup192=uninstrumented -fun:_gcry_camellia_setup256=uninstrumented -fun:_gcry_cast5_amd64_cbc_dec=uninstrumented -fun:_gcry_cast5_amd64_cfb_dec=uninstrumented -fun:_gcry_cast5_amd64_ctr_enc=uninstrumented -fun:_gcry_cast5_amd64_decrypt_block=uninstrumented -fun:_gcry_cast5_amd64_encrypt_block=uninstrumented -fun:_gcry_cast5_cbc_dec=uninstrumented -fun:_gcry_cast5_cfb_dec=uninstrumented -fun:_gcry_cast5_ctr_enc=uninstrumented -fun:_gcry_chacha20_amd64_avx2_blocks=uninstrumented -fun:_gcry_chacha20_amd64_sse2_blocks=uninstrumented -fun:_gcry_chacha20_amd64_ssse3_blocks=uninstrumented -fun:_gcry_check_heap=uninstrumented -fun:_gcry_check_version=uninstrumented -fun:_gcry_cipher_aeswrap_decrypt=uninstrumented -fun:_gcry_cipher_aeswrap_encrypt=uninstrumented -fun:_gcry_cipher_algo_info=uninstrumented -fun:_gcry_cipher_algo_name=uninstrumented -fun:_gcry_cipher_authenticate=uninstrumented -fun:_gcry_cipher_cbc_decrypt=uninstrumented -fun:_gcry_cipher_cbc_encrypt=uninstrumented -fun:_gcry_cipher_ccm_authenticate=uninstrumented -fun:_gcry_cipher_ccm_check_tag=uninstrumented -fun:_gcry_cipher_ccm_decrypt=uninstrumented -fun:_gcry_cipher_ccm_encrypt=uninstrumented -fun:_gcry_cipher_ccm_get_tag=uninstrumented -fun:_gcry_cipher_ccm_set_lengths=uninstrumented -fun:_gcry_cipher_ccm_set_nonce=uninstrumented -fun:_gcry_cipher_ccm_tag=uninstrumented -fun:_gcry_cipher_cfb8_decrypt=uninstrumented -fun:_gcry_cipher_cfb8_encrypt=uninstrumented -fun:_gcry_cipher_cfb_decrypt=uninstrumented -fun:_gcry_cipher_cfb_encrypt=uninstrumented -fun:_gcry_cipher_checktag=uninstrumented -fun:_gcry_cipher_close=uninstrumented -fun:_gcry_cipher_cmac_authenticate=uninstrumented -fun:_gcry_cipher_cmac_check_tag=uninstrumented -fun:_gcry_cipher_cmac_get_tag=uninstrumented -fun:_gcry_cipher_cmac_set_subkeys=uninstrumented -fun:_gcry_cipher_ctl=uninstrumented -fun:_gcry_cipher_ctr_encrypt=uninstrumented -fun:_gcry_cipher_decrypt=uninstrumented -fun:_gcry_cipher_encrypt=uninstrumented -fun:_gcry_cipher_gcm_authenticate=uninstrumented -fun:_gcry_cipher_gcm_check_tag=uninstrumented -fun:_gcry_cipher_gcm_decrypt=uninstrumented -fun:_gcry_cipher_gcm_encrypt=uninstrumented -fun:_gcry_cipher_gcm_get_tag=uninstrumented -fun:_gcry_cipher_gcm_setiv=uninstrumented -fun:_gcry_cipher_gcm_setkey=uninstrumented -fun:_gcry_cipher_get_algo_blklen=uninstrumented -fun:_gcry_cipher_get_algo_keylen=uninstrumented -fun:_gcry_cipher_getctr=uninstrumented -fun:_gcry_cipher_gettag=uninstrumented -fun:_gcry_cipher_info=uninstrumented -fun:_gcry_cipher_init=uninstrumented -fun:_gcry_cipher_map_name=uninstrumented -fun:_gcry_cipher_mode_from_oid=uninstrumented -fun:_gcry_cipher_ocb_authenticate=uninstrumented -fun:_gcry_cipher_ocb_check_tag=uninstrumented -fun:_gcry_cipher_ocb_decrypt=uninstrumented -fun:_gcry_cipher_ocb_encrypt=uninstrumented -fun:_gcry_cipher_ocb_get_tag=uninstrumented -fun:_gcry_cipher_ocb_set_nonce=uninstrumented -fun:_gcry_cipher_ofb_encrypt=uninstrumented -fun:_gcry_cipher_open=uninstrumented -fun:_gcry_cipher_open_internal=uninstrumented -fun:_gcry_cipher_poly1305_authenticate=uninstrumented -fun:_gcry_cipher_poly1305_check_tag=uninstrumented -fun:_gcry_cipher_poly1305_decrypt=uninstrumented -fun:_gcry_cipher_poly1305_encrypt=uninstrumented -fun:_gcry_cipher_poly1305_get_tag=uninstrumented -fun:_gcry_cipher_poly1305_setiv=uninstrumented -fun:_gcry_cipher_poly1305_setkey=uninstrumented -fun:_gcry_cipher_selftest=uninstrumented -fun:_gcry_cipher_selftest_alloc_ctx=uninstrumented -fun:_gcry_cipher_setctr=uninstrumented -fun:_gcry_cipher_setiv=uninstrumented -fun:_gcry_cipher_setkey=uninstrumented -fun:_gcry_cipher_xts_crypt=uninstrumented -fun:_gcry_compat_identification=uninstrumented -fun:_gcry_crc24rfc2440_intel_pclmul=uninstrumented -fun:_gcry_crc32_intel_pclmul=uninstrumented -fun:_gcry_create_nonce=uninstrumented -fun:_gcry_ctx_alloc=uninstrumented -fun:_gcry_ctx_find_pointer=uninstrumented -fun:_gcry_ctx_get_pointer=uninstrumented -fun:_gcry_ctx_release=uninstrumented -fun:_gcry_derive_x931_prime=uninstrumented -fun:_gcry_detect_hw_features=uninstrumented -fun:_gcry_disable_hw_feature=uninstrumented -fun:_gcry_divide_by_zero=uninstrumented -fun:_gcry_dsa_gen_k=uninstrumented -fun:_gcry_dsa_gen_rfc6979_k=uninstrumented -fun:_gcry_dsa_modify_k=uninstrumented -fun:_gcry_dsa_normalize_hash=uninstrumented -fun:_gcry_ecc_compute_public=uninstrumented -fun:_gcry_ecc_curve_copy=uninstrumented -fun:_gcry_ecc_curve_free=uninstrumented -fun:_gcry_ecc_dialect2str=uninstrumented -fun:_gcry_ecc_ec2os=uninstrumented -fun:_gcry_ecc_ecdsa_sign=uninstrumented -fun:_gcry_ecc_ecdsa_verify=uninstrumented -fun:_gcry_ecc_eddsa_compute_h_d=uninstrumented -fun:_gcry_ecc_eddsa_decodepoint=uninstrumented -fun:_gcry_ecc_eddsa_encodepoint=uninstrumented -fun:_gcry_ecc_eddsa_ensure_compact=uninstrumented -fun:_gcry_ecc_eddsa_genkey=uninstrumented -fun:_gcry_ecc_eddsa_recover_x=uninstrumented -fun:_gcry_ecc_eddsa_sign=uninstrumented -fun:_gcry_ecc_eddsa_verify=uninstrumented -fun:_gcry_ecc_fill_in_curve=uninstrumented -fun:_gcry_ecc_get_curve=uninstrumented -fun:_gcry_ecc_get_mpi=uninstrumented -fun:_gcry_ecc_get_param_sexp=uninstrumented -fun:_gcry_ecc_get_point=uninstrumented -fun:_gcry_ecc_gost_sign=uninstrumented -fun:_gcry_ecc_gost_verify=uninstrumented -fun:_gcry_ecc_model2str=uninstrumented -fun:_gcry_ecc_mont_decodepoint=uninstrumented -fun:_gcry_ecc_os2ec=uninstrumented -fun:_gcry_ecc_set_mpi=uninstrumented -fun:_gcry_ecc_set_point=uninstrumented -fun:_gcry_ecc_update_curve_param=uninstrumented -fun:_gcry_enable_quick_random_gen=uninstrumented -fun:_gcry_enforced_fips_mode=uninstrumented -fun:_gcry_enum_hw_features=uninstrumented -fun:_gcry_fast_random_poll=uninstrumented -fun:_gcry_fatal_error=uninstrumented -fun:_gcry_fips186_4_prime_check=uninstrumented -fun:_gcry_fips_is_operational=uninstrumented -fun:_gcry_fips_mode=uninstrumented -fun:_gcry_fips_noreturn=uninstrumented -fun:_gcry_fips_run_selftests=uninstrumented -fun:_gcry_fips_signal_error=uninstrumented -fun:_gcry_fips_test_error_or_operational=uninstrumented -fun:_gcry_fips_test_operational=uninstrumented -fun:_gcry_free=uninstrumented -fun:_gcry_generate_elg_prime=uninstrumented -fun:_gcry_generate_fips186_2_prime=uninstrumented -fun:_gcry_generate_fips186_3_prime=uninstrumented -fun:_gcry_generate_public_prime=uninstrumented -fun:_gcry_generate_secret_prime=uninstrumented -fun:_gcry_get_config=uninstrumented -fun:_gcry_get_debug_flag=uninstrumented -fun:_gcry_get_hw_features=uninstrumented -fun:_gcry_get_rng_type=uninstrumented -fun:_gcry_gettext=uninstrumented -fun:_gcry_ghash_intel_pclmul=uninstrumented -fun:_gcry_ghash_setup_intel_pclmul=uninstrumented -fun:_gcry_global_is_operational=uninstrumented -fun:_gcry_gost_enc_data=uninstrumented -fun:_gcry_hash_selftest_check_one=uninstrumented -fun:_gcry_hmac256_file=uninstrumented -fun:_gcry_hmac256_finalize=uninstrumented -fun:_gcry_hmac256_new=uninstrumented -fun:_gcry_hmac256_release=uninstrumented -fun:_gcry_hmac256_update=uninstrumented -fun:_gcry_hmac_selftest=uninstrumented -fun:_gcry_hwf_detect_x86=uninstrumented -fun:_gcry_inactivate_fips_mode=uninstrumented -fun:_gcry_initialize_fips_mode=uninstrumented -fun:_gcry_is_fips_mode_inactive=uninstrumented -fun:_gcry_is_secure=uninstrumented -fun:_gcry_kdf_derive=uninstrumented -fun:_gcry_kdf_pkdf2=uninstrumented -fun:_gcry_kdf_scrypt=uninstrumented -fun:_gcry_log=uninstrumented -fun:_gcry_log_bug=uninstrumented -fun:_gcry_log_debug=uninstrumented -fun:_gcry_log_error=uninstrumented -fun:_gcry_log_fatal=uninstrumented -fun:_gcry_log_info=uninstrumented -fun:_gcry_log_printf=uninstrumented -fun:_gcry_log_printhex=uninstrumented -fun:_gcry_log_printmpi=uninstrumented -fun:_gcry_log_printsxp=uninstrumented -fun:_gcry_log_verbosity=uninstrumented -fun:_gcry_logv=uninstrumented -fun:_gcry_mac_algo_info=uninstrumented -fun:_gcry_mac_algo_name=uninstrumented -fun:_gcry_mac_close=uninstrumented -fun:_gcry_mac_ctl=uninstrumented -fun:_gcry_mac_get_algo=uninstrumented -fun:_gcry_mac_get_algo_keylen=uninstrumented -fun:_gcry_mac_get_algo_maclen=uninstrumented -fun:_gcry_mac_init=uninstrumented -fun:_gcry_mac_map_name=uninstrumented -fun:_gcry_mac_open=uninstrumented -fun:_gcry_mac_read=uninstrumented -fun:_gcry_mac_setiv=uninstrumented -fun:_gcry_mac_setkey=uninstrumented -fun:_gcry_mac_verify=uninstrumented -fun:_gcry_mac_write=uninstrumented -fun:_gcry_malloc=uninstrumented -fun:_gcry_malloc_secure=uninstrumented -fun:_gcry_md_algo_info=uninstrumented -fun:_gcry_md_algo_name=uninstrumented -fun:_gcry_md_block_write=uninstrumented -fun:_gcry_md_close=uninstrumented -fun:_gcry_md_copy=uninstrumented -fun:_gcry_md_ctl=uninstrumented -fun:_gcry_md_debug=uninstrumented -fun:_gcry_md_enable=uninstrumented -fun:_gcry_md_extract=uninstrumented -fun:_gcry_md_get=uninstrumented -fun:_gcry_md_get_algo=uninstrumented -fun:_gcry_md_get_algo_dlen=uninstrumented -fun:_gcry_md_hash_buffer=uninstrumented -fun:_gcry_md_hash_buffers=uninstrumented -fun:_gcry_md_info=uninstrumented -fun:_gcry_md_init=uninstrumented -fun:_gcry_md_is_enabled=uninstrumented -fun:_gcry_md_is_secure=uninstrumented -fun:_gcry_md_map_name=uninstrumented -fun:_gcry_md_open=uninstrumented -fun:_gcry_md_read=uninstrumented -fun:_gcry_md_reset=uninstrumented -fun:_gcry_md_selftest=uninstrumented -fun:_gcry_md_setkey=uninstrumented -fun:_gcry_md_write=uninstrumented -fun:_gcry_mpi_abs=uninstrumented -fun:_gcry_mpi_add=uninstrumented -fun:_gcry_mpi_add_ui=uninstrumented -fun:_gcry_mpi_addm=uninstrumented -fun:_gcry_mpi_alloc=uninstrumented -fun:_gcry_mpi_alloc_like=uninstrumented -fun:_gcry_mpi_alloc_limb_space=uninstrumented -fun:_gcry_mpi_alloc_secure=uninstrumented -fun:_gcry_mpi_alloc_set_ui=uninstrumented -fun:_gcry_mpi_aprint=uninstrumented -fun:_gcry_mpi_assign_limb_space=uninstrumented -fun:_gcry_mpi_barrett_free=uninstrumented -fun:_gcry_mpi_barrett_init=uninstrumented -fun:_gcry_mpi_clear=uninstrumented -fun:_gcry_mpi_clear_bit=uninstrumented -fun:_gcry_mpi_clear_flag=uninstrumented -fun:_gcry_mpi_clear_highbit=uninstrumented -fun:_gcry_mpi_cmp=uninstrumented -fun:_gcry_mpi_cmp_ui=uninstrumented -fun:_gcry_mpi_cmpabs=uninstrumented -fun:_gcry_mpi_const=uninstrumented -fun:_gcry_mpi_copy=uninstrumented -fun:_gcry_mpi_div=uninstrumented -fun:_gcry_mpi_divisible_ui=uninstrumented -fun:_gcry_mpi_ec_add_points=uninstrumented -fun:_gcry_mpi_ec_bad_point=uninstrumented -fun:_gcry_mpi_ec_curve_point=uninstrumented -fun:_gcry_mpi_ec_decode_point=uninstrumented -fun:_gcry_mpi_ec_dup_point=uninstrumented -fun:_gcry_mpi_ec_ec2os=uninstrumented -fun:_gcry_mpi_ec_ed25519_mod=uninstrumented -fun:_gcry_mpi_ec_free=uninstrumented -fun:_gcry_mpi_ec_get_affine=uninstrumented -fun:_gcry_mpi_ec_get_mpi=uninstrumented -fun:_gcry_mpi_ec_get_point=uninstrumented -fun:_gcry_mpi_ec_get_reset=uninstrumented -fun:_gcry_mpi_ec_mul_point=uninstrumented -fun:_gcry_mpi_ec_new=uninstrumented -fun:_gcry_mpi_ec_p_internal_new=uninstrumented -fun:_gcry_mpi_ec_p_new=uninstrumented -fun:_gcry_mpi_ec_set_mpi=uninstrumented -fun:_gcry_mpi_ec_set_point=uninstrumented -fun:_gcry_mpi_ec_sub_points=uninstrumented -fun:_gcry_mpi_fdiv_q=uninstrumented -fun:_gcry_mpi_fdiv_qr=uninstrumented -fun:_gcry_mpi_fdiv_r=uninstrumented -fun:_gcry_mpi_fdiv_r_ui=uninstrumented -fun:_gcry_mpi_free=uninstrumented -fun:_gcry_mpi_free_limb_space=uninstrumented -fun:_gcry_mpi_gcd=uninstrumented -fun:_gcry_mpi_get_buffer=uninstrumented -fun:_gcry_mpi_get_buffer_extra=uninstrumented -fun:_gcry_mpi_get_const=uninstrumented -fun:_gcry_mpi_get_flag=uninstrumented -fun:_gcry_mpi_get_hw_config=uninstrumented -fun:_gcry_mpi_get_nbits=uninstrumented -fun:_gcry_mpi_get_opaque=uninstrumented -fun:_gcry_mpi_get_opaque_copy=uninstrumented -fun:_gcry_mpi_get_secure_buffer=uninstrumented -fun:_gcry_mpi_get_ui=uninstrumented -fun:_gcry_mpi_immutable_failed=uninstrumented -fun:_gcry_mpi_init=uninstrumented -fun:_gcry_mpi_invm=uninstrumented -fun:_gcry_mpi_is_neg=uninstrumented -fun:_gcry_mpi_lshift=uninstrumented -fun:_gcry_mpi_lshift_limbs=uninstrumented -fun:_gcry_mpi_m_check=uninstrumented -fun:_gcry_mpi_mod=uninstrumented -fun:_gcry_mpi_mod_barrett=uninstrumented -fun:_gcry_mpi_mul=uninstrumented -fun:_gcry_mpi_mul_2exp=uninstrumented -fun:_gcry_mpi_mul_barrett=uninstrumented -fun:_gcry_mpi_mul_ui=uninstrumented -fun:_gcry_mpi_mulm=uninstrumented -fun:_gcry_mpi_mulpowm=uninstrumented -fun:_gcry_mpi_neg=uninstrumented -fun:_gcry_mpi_new=uninstrumented -fun:_gcry_mpi_normalize=uninstrumented -fun:_gcry_mpi_point_copy=uninstrumented -fun:_gcry_mpi_point_free_parts=uninstrumented -fun:_gcry_mpi_point_get=uninstrumented -fun:_gcry_mpi_point_init=uninstrumented -fun:_gcry_mpi_point_log=uninstrumented -fun:_gcry_mpi_point_new=uninstrumented -fun:_gcry_mpi_point_release=uninstrumented -fun:_gcry_mpi_point_set=uninstrumented -fun:_gcry_mpi_point_snatch_get=uninstrumented -fun:_gcry_mpi_point_snatch_set=uninstrumented -fun:_gcry_mpi_powm=uninstrumented -fun:_gcry_mpi_print=uninstrumented -fun:_gcry_mpi_randomize=uninstrumented -fun:_gcry_mpi_release=uninstrumented -fun:_gcry_mpi_resize=uninstrumented -fun:_gcry_mpi_rshift=uninstrumented -fun:_gcry_mpi_rshift_limbs=uninstrumented -fun:_gcry_mpi_scan=uninstrumented -fun:_gcry_mpi_set=uninstrumented -fun:_gcry_mpi_set_bit=uninstrumented -fun:_gcry_mpi_set_buffer=uninstrumented -fun:_gcry_mpi_set_cond=uninstrumented -fun:_gcry_mpi_set_flag=uninstrumented -fun:_gcry_mpi_set_highbit=uninstrumented -fun:_gcry_mpi_set_opaque=uninstrumented -fun:_gcry_mpi_set_opaque_copy=uninstrumented -fun:_gcry_mpi_set_ui=uninstrumented -fun:_gcry_mpi_snatch=uninstrumented -fun:_gcry_mpi_snew=uninstrumented -fun:_gcry_mpi_sub=uninstrumented -fun:_gcry_mpi_sub_ui=uninstrumented -fun:_gcry_mpi_subm=uninstrumented -fun:_gcry_mpi_swap=uninstrumented -fun:_gcry_mpi_swap_cond=uninstrumented -fun:_gcry_mpi_tdiv_q_2exp=uninstrumented -fun:_gcry_mpi_tdiv_qr=uninstrumented -fun:_gcry_mpi_tdiv_r=uninstrumented -fun:_gcry_mpi_test_bit=uninstrumented -fun:_gcry_mpi_to_octet_string=uninstrumented -fun:_gcry_mpi_trailing_zeros=uninstrumented -fun:_gcry_mpih_add=uninstrumented -fun:_gcry_mpih_add_1=uninstrumented -fun:_gcry_mpih_cmp=uninstrumented -fun:_gcry_mpih_divmod_1=uninstrumented -fun:_gcry_mpih_divrem=uninstrumented -fun:_gcry_mpih_mod_1=uninstrumented -fun:_gcry_mpih_mul=uninstrumented -fun:_gcry_mpih_mul_karatsuba_case=uninstrumented -fun:_gcry_mpih_mul_n=uninstrumented -fun:_gcry_mpih_release_karatsuba_ctx=uninstrumented -fun:_gcry_mpih_sqr_n=uninstrumented -fun:_gcry_mpih_sqr_n_basecase=uninstrumented -fun:_gcry_mpih_sub=uninstrumented -fun:_gcry_mpih_sub_1=uninstrumented -fun:_gcry_pk_algo_info=uninstrumented -fun:_gcry_pk_algo_name=uninstrumented -fun:_gcry_pk_ctl=uninstrumented -fun:_gcry_pk_decrypt=uninstrumented -fun:_gcry_pk_ecc_get_sexp=uninstrumented -fun:_gcry_pk_encrypt=uninstrumented -fun:_gcry_pk_genkey=uninstrumented -fun:_gcry_pk_get_curve=uninstrumented -fun:_gcry_pk_get_keygrip=uninstrumented -fun:_gcry_pk_get_nbits=uninstrumented -fun:_gcry_pk_get_param=uninstrumented -fun:_gcry_pk_init=uninstrumented -fun:_gcry_pk_map_name=uninstrumented -fun:_gcry_pk_selftest=uninstrumented -fun:_gcry_pk_sign=uninstrumented -fun:_gcry_pk_testkey=uninstrumented -fun:_gcry_pk_util_data_to_mpi=uninstrumented -fun:_gcry_pk_util_free_encoding_ctx=uninstrumented -fun:_gcry_pk_util_get_nbits=uninstrumented -fun:_gcry_pk_util_get_rsa_use_e=uninstrumented -fun:_gcry_pk_util_init_encoding_ctx=uninstrumented -fun:_gcry_pk_util_parse_flaglist=uninstrumented -fun:_gcry_pk_util_preparse_encval=uninstrumented -fun:_gcry_pk_util_preparse_sigval=uninstrumented -fun:_gcry_pk_verify=uninstrumented -fun:_gcry_poly1305_amd64_avx2_blocks=uninstrumented -fun:_gcry_poly1305_amd64_avx2_finish_ext=uninstrumented -fun:_gcry_poly1305_amd64_avx2_init_ext=uninstrumented -fun:_gcry_poly1305_amd64_sse2_blocks=uninstrumented -fun:_gcry_poly1305_amd64_sse2_finish_ext=uninstrumented -fun:_gcry_poly1305_amd64_sse2_init_ext=uninstrumented -fun:_gcry_poly1305_finish=uninstrumented -fun:_gcry_poly1305_init=uninstrumented -fun:_gcry_poly1305_update=uninstrumented -fun:_gcry_post_syscall=uninstrumented -fun:_gcry_pre_syscall=uninstrumented -fun:_gcry_prime_check=uninstrumented -fun:_gcry_prime_generate=uninstrumented -fun:_gcry_prime_group_generator=uninstrumented -fun:_gcry_prime_release_factors=uninstrumented -fun:_gcry_primegen_init=uninstrumented -fun:_gcry_private_check_heap=uninstrumented -fun:_gcry_private_enable_m_guard=uninstrumented -fun:_gcry_private_free=uninstrumented -fun:_gcry_private_is_secure=uninstrumented -fun:_gcry_private_malloc=uninstrumented -fun:_gcry_private_malloc_secure=uninstrumented -fun:_gcry_private_realloc=uninstrumented -fun:_gcry_pubkey_get_sexp=uninstrumented -fun:_gcry_random_add_bytes=uninstrumented -fun:_gcry_random_bytes=uninstrumented -fun:_gcry_random_bytes_secure=uninstrumented -fun:_gcry_random_close_fds=uninstrumented -fun:_gcry_random_dump_stats=uninstrumented -fun:_gcry_random_initialize=uninstrumented -fun:_gcry_random_is_faked=uninstrumented -fun:_gcry_random_progress=uninstrumented -fun:_gcry_random_read_conf=uninstrumented -fun:_gcry_random_selftest=uninstrumented -fun:_gcry_randomize=uninstrumented -fun:_gcry_realloc=uninstrumented -fun:_gcry_register_pk_dsa_progress=uninstrumented -fun:_gcry_register_pk_ecc_progress=uninstrumented -fun:_gcry_register_pk_elg_progress=uninstrumented -fun:_gcry_register_primegen_progress=uninstrumented -fun:_gcry_register_random_progress=uninstrumented -fun:_gcry_rmd160_hash_buffer=uninstrumented -fun:_gcry_rndhw_failed_p=uninstrumented -fun:_gcry_rndhw_poll_fast=uninstrumented -fun:_gcry_rndhw_poll_slow=uninstrumented -fun:_gcry_rndjent_dump_stats=uninstrumented -fun:_gcry_rndjent_get_version=uninstrumented -fun:_gcry_rndjent_poll=uninstrumented -fun:_gcry_rndlinux_gather_random=uninstrumented -fun:_gcry_rngcsprng_add_bytes=uninstrumented -fun:_gcry_rngcsprng_close_fds=uninstrumented -fun:_gcry_rngcsprng_dump_stats=uninstrumented -fun:_gcry_rngcsprng_enable_quick_gen=uninstrumented -fun:_gcry_rngcsprng_fast_poll=uninstrumented -fun:_gcry_rngcsprng_initialize=uninstrumented -fun:_gcry_rngcsprng_is_faked=uninstrumented -fun:_gcry_rngcsprng_randomize=uninstrumented -fun:_gcry_rngcsprng_secure_alloc=uninstrumented -fun:_gcry_rngcsprng_set_daemon_socket=uninstrumented -fun:_gcry_rngcsprng_set_seed_file=uninstrumented -fun:_gcry_rngcsprng_update_seed_file=uninstrumented -fun:_gcry_rngcsprng_use_daemon=uninstrumented -fun:_gcry_rngdrbg_add_bytes=uninstrumented -fun:_gcry_rngdrbg_cavs_test=uninstrumented -fun:_gcry_rngdrbg_close_fds=uninstrumented -fun:_gcry_rngdrbg_dump_stats=uninstrumented -fun:_gcry_rngdrbg_healthcheck_one=uninstrumented -fun:_gcry_rngdrbg_inititialize=uninstrumented -fun:_gcry_rngdrbg_is_faked=uninstrumented -fun:_gcry_rngdrbg_randomize=uninstrumented -fun:_gcry_rngdrbg_reinit=uninstrumented -fun:_gcry_rngdrbg_selftest=uninstrumented -fun:_gcry_rngsystem_add_bytes=uninstrumented -fun:_gcry_rngsystem_close_fds=uninstrumented -fun:_gcry_rngsystem_dump_stats=uninstrumented -fun:_gcry_rngsystem_initialize=uninstrumented -fun:_gcry_rngsystem_is_faked=uninstrumented -fun:_gcry_rngsystem_randomize=uninstrumented -fun:_gcry_rsa_oaep_decode=uninstrumented -fun:_gcry_rsa_oaep_encode=uninstrumented -fun:_gcry_rsa_pkcs1_decode_for_enc=uninstrumented -fun:_gcry_rsa_pkcs1_encode_for_enc=uninstrumented -fun:_gcry_rsa_pkcs1_encode_for_sig=uninstrumented -fun:_gcry_rsa_pkcs1_encode_raw_for_sig=uninstrumented -fun:_gcry_rsa_pss_encode=uninstrumented -fun:_gcry_rsa_pss_verify=uninstrumented -fun:_gcry_salsa20_amd64_encrypt_blocks=uninstrumented -fun:_gcry_salsa20_amd64_ivsetup=uninstrumented -fun:_gcry_salsa20_amd64_keysetup=uninstrumented -fun:_gcry_secmem_dump_stats=uninstrumented -fun:_gcry_secmem_free=uninstrumented -fun:_gcry_secmem_get_flags=uninstrumented -fun:_gcry_secmem_init=uninstrumented -fun:_gcry_secmem_malloc=uninstrumented -fun:_gcry_secmem_module_init=uninstrumented -fun:_gcry_secmem_realloc=uninstrumented -fun:_gcry_secmem_set_auto_expand=uninstrumented -fun:_gcry_secmem_set_flags=uninstrumented -fun:_gcry_secmem_term=uninstrumented -fun:_gcry_secure_random_alloc=uninstrumented -fun:_gcry_selftest_helper_cbc=uninstrumented -fun:_gcry_selftest_helper_cfb=uninstrumented -fun:_gcry_selftest_helper_ctr=uninstrumented -fun:_gcry_serpent_avx2_cbc_dec=uninstrumented -fun:_gcry_serpent_avx2_cfb_dec=uninstrumented -fun:_gcry_serpent_avx2_ctr_enc=uninstrumented -fun:_gcry_serpent_avx2_ocb_auth=uninstrumented -fun:_gcry_serpent_avx2_ocb_dec=uninstrumented -fun:_gcry_serpent_avx2_ocb_enc=uninstrumented -fun:_gcry_serpent_cbc_dec=uninstrumented -fun:_gcry_serpent_cfb_dec=uninstrumented -fun:_gcry_serpent_ctr_enc=uninstrumented -fun:_gcry_serpent_ocb_auth=uninstrumented -fun:_gcry_serpent_ocb_crypt=uninstrumented -fun:_gcry_serpent_sse2_cbc_dec=uninstrumented -fun:_gcry_serpent_sse2_cfb_dec=uninstrumented -fun:_gcry_serpent_sse2_ctr_enc=uninstrumented -fun:_gcry_serpent_sse2_ocb_auth=uninstrumented -fun:_gcry_serpent_sse2_ocb_dec=uninstrumented -fun:_gcry_serpent_sse2_ocb_enc=uninstrumented -fun:_gcry_set_allocation_handler=uninstrumented -fun:_gcry_set_enforced_fips_mode=uninstrumented -fun:_gcry_set_fatalerror_handler=uninstrumented -fun:_gcry_set_gettext_handler=uninstrumented -fun:_gcry_set_log_handler=uninstrumented -fun:_gcry_set_log_verbosity=uninstrumented -fun:_gcry_set_outofcore_handler=uninstrumented -fun:_gcry_set_preferred_rng_type=uninstrumented -fun:_gcry_set_progress_handler=uninstrumented -fun:_gcry_set_random_daemon_socket=uninstrumented -fun:_gcry_set_random_seed_file=uninstrumented -fun:_gcry_sexp_alist=uninstrumented -fun:_gcry_sexp_append=uninstrumented -fun:_gcry_sexp_build=uninstrumented -fun:_gcry_sexp_build_array=uninstrumented -fun:_gcry_sexp_cadr=uninstrumented -fun:_gcry_sexp_canon_len=uninstrumented -fun:_gcry_sexp_car=uninstrumented -fun:_gcry_sexp_cdr=uninstrumented -fun:_gcry_sexp_cons=uninstrumented -fun:_gcry_sexp_create=uninstrumented -fun:_gcry_sexp_dump=uninstrumented -fun:_gcry_sexp_extract_param=uninstrumented -fun:_gcry_sexp_find_token=uninstrumented -fun:_gcry_sexp_length=uninstrumented -fun:_gcry_sexp_new=uninstrumented -fun:_gcry_sexp_nth=uninstrumented -fun:_gcry_sexp_nth_buffer=uninstrumented -fun:_gcry_sexp_nth_data=uninstrumented -fun:_gcry_sexp_nth_mpi=uninstrumented -fun:_gcry_sexp_nth_string=uninstrumented -fun:_gcry_sexp_prepend=uninstrumented -fun:_gcry_sexp_release=uninstrumented -fun:_gcry_sexp_sprint=uninstrumented -fun:_gcry_sexp_sscan=uninstrumented -fun:_gcry_sexp_vbuild=uninstrumented -fun:_gcry_sexp_vextract_param=uninstrumented -fun:_gcry_sexp_vlist=uninstrumented -fun:_gcry_sha1_hash_buffer=uninstrumented -fun:_gcry_sha1_hash_buffers=uninstrumented -fun:_gcry_sha1_mixblock=uninstrumented -fun:_gcry_sha1_mixblock_init=uninstrumented -fun:_gcry_sha1_transform_amd64_avx=uninstrumented -fun:_gcry_sha1_transform_amd64_avx_bmi2=uninstrumented -fun:_gcry_sha1_transform_amd64_ssse3=uninstrumented -fun:_gcry_sha256_hash_buffer=uninstrumented -fun:_gcry_sha256_hash_buffers=uninstrumented -fun:_gcry_sha256_transform_amd64_avx=uninstrumented -fun:_gcry_sha256_transform_amd64_avx2=uninstrumented -fun:_gcry_sha256_transform_amd64_ssse3=uninstrumented -fun:_gcry_sha512_hash_buffer=uninstrumented -fun:_gcry_sha512_hash_buffers=uninstrumented -fun:_gcry_sha512_transform_amd64_avx=uninstrumented -fun:_gcry_sha512_transform_amd64_avx2=uninstrumented -fun:_gcry_sha512_transform_amd64_ssse3=uninstrumented -fun:_gcry_strdup=uninstrumented -fun:_gcry_strtokenize=uninstrumented -fun:_gcry_twofish_amd64_cbc_dec=uninstrumented -fun:_gcry_twofish_amd64_cfb_dec=uninstrumented -fun:_gcry_twofish_amd64_ctr_enc=uninstrumented -fun:_gcry_twofish_amd64_decrypt_block=uninstrumented -fun:_gcry_twofish_amd64_encrypt_block=uninstrumented -fun:_gcry_twofish_amd64_ocb_auth=uninstrumented -fun:_gcry_twofish_amd64_ocb_dec=uninstrumented -fun:_gcry_twofish_amd64_ocb_enc=uninstrumented -fun:_gcry_twofish_avx2_cbc_dec=uninstrumented -fun:_gcry_twofish_avx2_cfb_dec=uninstrumented -fun:_gcry_twofish_avx2_ctr_enc=uninstrumented -fun:_gcry_twofish_avx2_ocb_auth=uninstrumented -fun:_gcry_twofish_avx2_ocb_dec=uninstrumented -fun:_gcry_twofish_avx2_ocb_enc=uninstrumented -fun:_gcry_twofish_cbc_dec=uninstrumented -fun:_gcry_twofish_cfb_dec=uninstrumented -fun:_gcry_twofish_ctr_enc=uninstrumented -fun:_gcry_twofish_ocb_auth=uninstrumented -fun:_gcry_twofish_ocb_crypt=uninstrumented -fun:_gcry_update_random_seed_file=uninstrumented -fun:_gcry_use_random_daemon=uninstrumented -fun:_gcry_vcontrol=uninstrumented -fun:_gcry_whirlpool_transform_amd64=uninstrumented -fun:_gcry_xcalloc=uninstrumented -fun:_gcry_xcalloc_secure=uninstrumented -fun:_gcry_xmalloc=uninstrumented -fun:_gcry_xmalloc_secure=uninstrumented -fun:_gcry_xrealloc=uninstrumented -fun:_gcry_xstrdup=uninstrumented -fun:gcry_calloc=uninstrumented -fun:gcry_calloc_secure=uninstrumented -fun:gcry_check_version=uninstrumented -fun:gcry_cipher_algo_info=uninstrumented -fun:gcry_cipher_algo_name=uninstrumented -fun:gcry_cipher_authenticate=uninstrumented -fun:gcry_cipher_checktag=uninstrumented -fun:gcry_cipher_close=uninstrumented -fun:gcry_cipher_ctl=uninstrumented -fun:gcry_cipher_decrypt=uninstrumented -fun:gcry_cipher_encrypt=uninstrumented -fun:gcry_cipher_get_algo_blklen=uninstrumented -fun:gcry_cipher_get_algo_keylen=uninstrumented -fun:gcry_cipher_gettag=uninstrumented -fun:gcry_cipher_info=uninstrumented -fun:gcry_cipher_map_name=uninstrumented -fun:gcry_cipher_mode_from_oid=uninstrumented -fun:gcry_cipher_open=uninstrumented -fun:gcry_cipher_setctr=uninstrumented -fun:gcry_cipher_setiv=uninstrumented -fun:gcry_cipher_setkey=uninstrumented -fun:gcry_control=uninstrumented -fun:gcry_create_nonce=uninstrumented -fun:gcry_ctx_release=uninstrumented -fun:gcry_err_code_from_errno=uninstrumented -fun:gcry_err_code_to_errno=uninstrumented -fun:gcry_err_make_from_errno=uninstrumented -fun:gcry_error_from_errno=uninstrumented -fun:gcry_free=uninstrumented -fun:gcry_get_config=uninstrumented -fun:gcry_is_secure=uninstrumented -fun:gcry_kdf_derive=uninstrumented -fun:gcry_log_debug=uninstrumented -fun:gcry_log_debughex=uninstrumented -fun:gcry_log_debugmpi=uninstrumented -fun:gcry_log_debugpnt=uninstrumented -fun:gcry_log_debugsxp=uninstrumented -fun:gcry_mac_algo_info=uninstrumented -fun:gcry_mac_algo_name=uninstrumented -fun:gcry_mac_close=uninstrumented -fun:gcry_mac_ctl=uninstrumented -fun:gcry_mac_get_algo=uninstrumented -fun:gcry_mac_get_algo_keylen=uninstrumented -fun:gcry_mac_get_algo_maclen=uninstrumented -fun:gcry_mac_map_name=uninstrumented -fun:gcry_mac_open=uninstrumented -fun:gcry_mac_read=uninstrumented -fun:gcry_mac_setiv=uninstrumented -fun:gcry_mac_setkey=uninstrumented -fun:gcry_mac_verify=uninstrumented -fun:gcry_mac_write=uninstrumented -fun:gcry_malloc=uninstrumented -fun:gcry_malloc_secure=uninstrumented -fun:gcry_md_algo_info=uninstrumented -fun:gcry_md_algo_name=uninstrumented -fun:gcry_md_close=uninstrumented -fun:gcry_md_copy=uninstrumented -fun:gcry_md_ctl=uninstrumented -fun:gcry_md_debug=uninstrumented -fun:gcry_md_enable=uninstrumented -fun:gcry_md_extract=uninstrumented -fun:gcry_md_get_algo=uninstrumented -fun:gcry_md_get_algo_dlen=uninstrumented -fun:gcry_md_hash_buffer=uninstrumented -fun:gcry_md_hash_buffers=uninstrumented -fun:gcry_md_info=uninstrumented -fun:gcry_md_is_enabled=uninstrumented -fun:gcry_md_is_secure=uninstrumented -fun:gcry_md_map_name=uninstrumented -fun:gcry_md_open=uninstrumented -fun:gcry_md_read=uninstrumented -fun:gcry_md_reset=uninstrumented -fun:gcry_md_setkey=uninstrumented -fun:gcry_md_write=uninstrumented -fun:gcry_mpi_abs=uninstrumented -fun:gcry_mpi_add=uninstrumented -fun:gcry_mpi_add_ui=uninstrumented -fun:gcry_mpi_addm=uninstrumented -fun:gcry_mpi_aprint=uninstrumented -fun:gcry_mpi_clear_bit=uninstrumented -fun:gcry_mpi_clear_flag=uninstrumented -fun:gcry_mpi_clear_highbit=uninstrumented -fun:gcry_mpi_cmp=uninstrumented -fun:gcry_mpi_cmp_ui=uninstrumented -fun:gcry_mpi_copy=uninstrumented -fun:gcry_mpi_div=uninstrumented -fun:gcry_mpi_dump=uninstrumented -fun:gcry_mpi_ec_add=uninstrumented -fun:gcry_mpi_ec_curve_point=uninstrumented -fun:gcry_mpi_ec_decode_point=uninstrumented -fun:gcry_mpi_ec_dup=uninstrumented -fun:gcry_mpi_ec_get_affine=uninstrumented -fun:gcry_mpi_ec_get_mpi=uninstrumented -fun:gcry_mpi_ec_get_point=uninstrumented -fun:gcry_mpi_ec_mul=uninstrumented -fun:gcry_mpi_ec_new=uninstrumented -fun:gcry_mpi_ec_set_mpi=uninstrumented -fun:gcry_mpi_ec_set_point=uninstrumented -fun:gcry_mpi_ec_sub=uninstrumented -fun:gcry_mpi_gcd=uninstrumented -fun:gcry_mpi_get_flag=uninstrumented -fun:gcry_mpi_get_nbits=uninstrumented -fun:gcry_mpi_get_opaque=uninstrumented -fun:gcry_mpi_get_ui=uninstrumented -fun:gcry_mpi_invm=uninstrumented -fun:gcry_mpi_is_neg=uninstrumented -fun:gcry_mpi_lshift=uninstrumented -fun:gcry_mpi_mod=uninstrumented -fun:gcry_mpi_mul=uninstrumented -fun:gcry_mpi_mul_2exp=uninstrumented -fun:gcry_mpi_mul_ui=uninstrumented -fun:gcry_mpi_mulm=uninstrumented -fun:gcry_mpi_neg=uninstrumented -fun:gcry_mpi_new=uninstrumented -fun:gcry_mpi_point_copy=uninstrumented -fun:gcry_mpi_point_get=uninstrumented -fun:gcry_mpi_point_new=uninstrumented -fun:gcry_mpi_point_release=uninstrumented -fun:gcry_mpi_point_set=uninstrumented -fun:gcry_mpi_point_snatch_get=uninstrumented -fun:gcry_mpi_point_snatch_set=uninstrumented -fun:gcry_mpi_powm=uninstrumented -fun:gcry_mpi_print=uninstrumented -fun:gcry_mpi_randomize=uninstrumented -fun:gcry_mpi_release=uninstrumented -fun:gcry_mpi_rshift=uninstrumented -fun:gcry_mpi_scan=uninstrumented -fun:gcry_mpi_set=uninstrumented -fun:gcry_mpi_set_bit=uninstrumented -fun:gcry_mpi_set_flag=uninstrumented -fun:gcry_mpi_set_highbit=uninstrumented -fun:gcry_mpi_set_opaque=uninstrumented -fun:gcry_mpi_set_opaque_copy=uninstrumented -fun:gcry_mpi_set_ui=uninstrumented -fun:gcry_mpi_snatch=uninstrumented -fun:gcry_mpi_snew=uninstrumented -fun:gcry_mpi_sub=uninstrumented -fun:gcry_mpi_sub_ui=uninstrumented -fun:gcry_mpi_subm=uninstrumented -fun:gcry_mpi_swap=uninstrumented -fun:gcry_mpi_test_bit=uninstrumented -fun:gcry_pk_algo_info=uninstrumented -fun:gcry_pk_algo_name=uninstrumented -fun:gcry_pk_ctl=uninstrumented -fun:gcry_pk_decrypt=uninstrumented -fun:gcry_pk_encrypt=uninstrumented -fun:gcry_pk_genkey=uninstrumented -fun:gcry_pk_get_curve=uninstrumented -fun:gcry_pk_get_keygrip=uninstrumented -fun:gcry_pk_get_nbits=uninstrumented -fun:gcry_pk_get_param=uninstrumented -fun:gcry_pk_map_name=uninstrumented -fun:gcry_pk_sign=uninstrumented -fun:gcry_pk_testkey=uninstrumented -fun:gcry_pk_verify=uninstrumented -fun:gcry_prime_check=uninstrumented -fun:gcry_prime_generate=uninstrumented -fun:gcry_prime_group_generator=uninstrumented -fun:gcry_prime_release_factors=uninstrumented -fun:gcry_pubkey_get_sexp=uninstrumented -fun:gcry_random_add_bytes=uninstrumented -fun:gcry_random_bytes=uninstrumented -fun:gcry_random_bytes_secure=uninstrumented -fun:gcry_randomize=uninstrumented -fun:gcry_realloc=uninstrumented -fun:gcry_set_allocation_handler=uninstrumented -fun:gcry_set_fatalerror_handler=uninstrumented -fun:gcry_set_gettext_handler=uninstrumented -fun:gcry_set_log_handler=uninstrumented -fun:gcry_set_outofcore_handler=uninstrumented -fun:gcry_set_progress_handler=uninstrumented -fun:gcry_sexp_alist=uninstrumented -fun:gcry_sexp_append=uninstrumented -fun:gcry_sexp_build=uninstrumented -fun:gcry_sexp_build_array=uninstrumented -fun:gcry_sexp_cadr=uninstrumented -fun:gcry_sexp_canon_len=uninstrumented -fun:gcry_sexp_car=uninstrumented -fun:gcry_sexp_cdr=uninstrumented -fun:gcry_sexp_cons=uninstrumented -fun:gcry_sexp_create=uninstrumented -fun:gcry_sexp_dump=uninstrumented -fun:gcry_sexp_extract_param=uninstrumented -fun:gcry_sexp_find_token=uninstrumented -fun:gcry_sexp_length=uninstrumented -fun:gcry_sexp_new=uninstrumented -fun:gcry_sexp_nth=uninstrumented -fun:gcry_sexp_nth_buffer=uninstrumented -fun:gcry_sexp_nth_data=uninstrumented -fun:gcry_sexp_nth_mpi=uninstrumented -fun:gcry_sexp_nth_string=uninstrumented -fun:gcry_sexp_prepend=uninstrumented -fun:gcry_sexp_release=uninstrumented -fun:gcry_sexp_sprint=uninstrumented -fun:gcry_sexp_sscan=uninstrumented -fun:gcry_sexp_vlist=uninstrumented -fun:gcry_strdup=uninstrumented -fun:gcry_strerror=uninstrumented -fun:gcry_strsource=uninstrumented -fun:gcry_xcalloc=uninstrumented -fun:gcry_xcalloc_secure=uninstrumented -fun:gcry_xmalloc=uninstrumented -fun:gcry_xmalloc_secure=uninstrumented -fun:gcry_xrealloc=uninstrumented -fun:gcry_xstrdup=uninstrumented diff --git a/fuzzers/symsan/glib.abilist b/fuzzers/symsan/glib.abilist deleted file mode 100644 index dddc96754..000000000 --- a/fuzzers/symsan/glib.abilist +++ /dev/null @@ -1,1732 +0,0 @@ -fun:_g_async_queue_get_mutex=uninstrumented -fun:_g_charset_get_aliases=uninstrumented -fun:_g_locale_charset_raw=uninstrumented -fun:_g_locale_charset_unalias=uninstrumented -fun:_g_locale_get_charset_aliases=uninstrumented -fun:_g_log_fallback_handler=uninstrumented -fun:_g_main_create_unix_signal_watch=uninstrumented -fun:_g_utf8_normalize_wc=uninstrumented -fun:g_access=uninstrumented -fun:g_allocator_free=uninstrumented -fun:g_allocator_new=uninstrumented -fun:g_array_append_vals=uninstrumented -fun:g_array_binary_search=uninstrumented -fun:g_array_copy=uninstrumented -fun:g_array_free=uninstrumented -fun:g_array_get_element_size=uninstrumented -fun:g_array_insert_vals=uninstrumented -fun:g_array_new=uninstrumented -fun:g_array_prepend_vals=uninstrumented -fun:g_array_ref=uninstrumented -fun:g_array_remove_index=uninstrumented -fun:g_array_remove_index_fast=uninstrumented -fun:g_array_remove_range=uninstrumented -fun:g_array_set_clear_func=uninstrumented -fun:g_array_set_size=uninstrumented -fun:g_array_sized_new=uninstrumented -fun:g_array_sort=uninstrumented -fun:g_array_sort_with_data=uninstrumented -fun:g_array_steal=uninstrumented -fun:g_array_unref=uninstrumented -fun:g_ascii_digit_value=uninstrumented -fun:g_ascii_dtostr=uninstrumented -fun:g_ascii_formatd=uninstrumented -fun:g_ascii_strcasecmp=uninstrumented -fun:g_ascii_strdown=uninstrumented -fun:g_ascii_string_to_signed=uninstrumented -fun:g_ascii_string_to_unsigned=uninstrumented -fun:g_ascii_strncasecmp=uninstrumented -fun:g_ascii_strtod=uninstrumented -fun:g_ascii_strtoll=uninstrumented -fun:g_ascii_strtoull=uninstrumented -fun:g_ascii_strup=uninstrumented -fun:g_ascii_tolower=uninstrumented -fun:g_ascii_toupper=uninstrumented -fun:g_ascii_xdigit_value=uninstrumented -fun:g_assert_warning=uninstrumented -fun:g_assertion_message=uninstrumented -fun:g_assertion_message_cmpnum=uninstrumented -fun:g_assertion_message_cmpstr=uninstrumented -fun:g_assertion_message_error=uninstrumented -fun:g_assertion_message_expr=uninstrumented -fun:g_async_queue_length=uninstrumented -fun:g_async_queue_length_unlocked=uninstrumented -fun:g_async_queue_lock=uninstrumented -fun:g_async_queue_new=uninstrumented -fun:g_async_queue_new_full=uninstrumented -fun:g_async_queue_pop=uninstrumented -fun:g_async_queue_pop_unlocked=uninstrumented -fun:g_async_queue_push=uninstrumented -fun:g_async_queue_push_front=uninstrumented -fun:g_async_queue_push_front_unlocked=uninstrumented -fun:g_async_queue_push_sorted=uninstrumented -fun:g_async_queue_push_sorted_unlocked=uninstrumented -fun:g_async_queue_push_unlocked=uninstrumented -fun:g_async_queue_ref=uninstrumented -fun:g_async_queue_ref_unlocked=uninstrumented -fun:g_async_queue_remove=uninstrumented -fun:g_async_queue_remove_unlocked=uninstrumented -fun:g_async_queue_sort=uninstrumented -fun:g_async_queue_sort_unlocked=uninstrumented -fun:g_async_queue_timed_pop=uninstrumented -fun:g_async_queue_timed_pop_unlocked=uninstrumented -fun:g_async_queue_timeout_pop=uninstrumented -fun:g_async_queue_timeout_pop_unlocked=uninstrumented -fun:g_async_queue_try_pop=uninstrumented -fun:g_async_queue_try_pop_unlocked=uninstrumented -fun:g_async_queue_unlock=uninstrumented -fun:g_async_queue_unref=uninstrumented -fun:g_async_queue_unref_and_unlock=uninstrumented -fun:g_atexit=uninstrumented -fun:g_atomic_int_add=uninstrumented -fun:g_atomic_int_and=uninstrumented -fun:g_atomic_int_compare_and_exchange=uninstrumented -fun:g_atomic_int_dec_and_test=uninstrumented -fun:g_atomic_int_exchange_and_add=uninstrumented -fun:g_atomic_int_get=uninstrumented -fun:g_atomic_int_inc=uninstrumented -fun:g_atomic_int_or=uninstrumented -fun:g_atomic_int_set=uninstrumented -fun:g_atomic_int_xor=uninstrumented -fun:g_atomic_pointer_add=uninstrumented -fun:g_atomic_pointer_and=uninstrumented -fun:g_atomic_pointer_compare_and_exchange=uninstrumented -fun:g_atomic_pointer_get=uninstrumented -fun:g_atomic_pointer_or=uninstrumented -fun:g_atomic_pointer_set=uninstrumented -fun:g_atomic_pointer_xor=uninstrumented -fun:g_atomic_rc_box_acquire=uninstrumented -fun:g_atomic_rc_box_alloc=uninstrumented -fun:g_atomic_rc_box_alloc0=uninstrumented -fun:g_atomic_rc_box_dup=uninstrumented -fun:g_atomic_rc_box_get_size=uninstrumented -fun:g_atomic_rc_box_release=uninstrumented -fun:g_atomic_rc_box_release_full=uninstrumented -fun:g_atomic_ref_count_compare=uninstrumented -fun:g_atomic_ref_count_dec=uninstrumented -fun:g_atomic_ref_count_inc=uninstrumented -fun:g_atomic_ref_count_init=uninstrumented -fun:g_base64_decode=uninstrumented -fun:g_base64_decode_inplace=uninstrumented -fun:g_base64_decode_step=uninstrumented -fun:g_base64_encode=uninstrumented -fun:g_base64_encode_close=uninstrumented -fun:g_base64_encode_step=uninstrumented -fun:g_basename=uninstrumented -fun:g_bit_lock=uninstrumented -fun:g_bit_nth_lsf=uninstrumented -fun:g_bit_nth_msf=uninstrumented -fun:g_bit_storage=uninstrumented -fun:g_bit_trylock=uninstrumented -fun:g_bit_unlock=uninstrumented -fun:g_blow_chunks=uninstrumented -fun:g_bookmark_file_add_application=uninstrumented -fun:g_bookmark_file_add_group=uninstrumented -fun:g_bookmark_file_error_quark=uninstrumented -fun:g_bookmark_file_free=uninstrumented -fun:g_bookmark_file_get_added=uninstrumented -fun:g_bookmark_file_get_app_info=uninstrumented -fun:g_bookmark_file_get_applications=uninstrumented -fun:g_bookmark_file_get_description=uninstrumented -fun:g_bookmark_file_get_groups=uninstrumented -fun:g_bookmark_file_get_icon=uninstrumented -fun:g_bookmark_file_get_is_private=uninstrumented -fun:g_bookmark_file_get_mime_type=uninstrumented -fun:g_bookmark_file_get_modified=uninstrumented -fun:g_bookmark_file_get_size=uninstrumented -fun:g_bookmark_file_get_title=uninstrumented -fun:g_bookmark_file_get_uris=uninstrumented -fun:g_bookmark_file_get_visited=uninstrumented -fun:g_bookmark_file_has_application=uninstrumented -fun:g_bookmark_file_has_group=uninstrumented -fun:g_bookmark_file_has_item=uninstrumented -fun:g_bookmark_file_load_from_data=uninstrumented -fun:g_bookmark_file_load_from_data_dirs=uninstrumented -fun:g_bookmark_file_load_from_file=uninstrumented -fun:g_bookmark_file_move_item=uninstrumented -fun:g_bookmark_file_new=uninstrumented -fun:g_bookmark_file_remove_application=uninstrumented -fun:g_bookmark_file_remove_group=uninstrumented -fun:g_bookmark_file_remove_item=uninstrumented -fun:g_bookmark_file_set_added=uninstrumented -fun:g_bookmark_file_set_app_info=uninstrumented -fun:g_bookmark_file_set_description=uninstrumented -fun:g_bookmark_file_set_groups=uninstrumented -fun:g_bookmark_file_set_icon=uninstrumented -fun:g_bookmark_file_set_is_private=uninstrumented -fun:g_bookmark_file_set_mime_type=uninstrumented -fun:g_bookmark_file_set_modified=uninstrumented -fun:g_bookmark_file_set_title=uninstrumented -fun:g_bookmark_file_set_visited=uninstrumented -fun:g_bookmark_file_to_data=uninstrumented -fun:g_bookmark_file_to_file=uninstrumented -fun:g_build_filename=uninstrumented -fun:g_build_filename_valist=uninstrumented -fun:g_build_filenamev=uninstrumented -fun:g_build_path=uninstrumented -fun:g_build_pathv=uninstrumented -fun:g_byte_array_append=uninstrumented -fun:g_byte_array_free=uninstrumented -fun:g_byte_array_free_to_bytes=uninstrumented -fun:g_byte_array_new=uninstrumented -fun:g_byte_array_new_take=uninstrumented -fun:g_byte_array_prepend=uninstrumented -fun:g_byte_array_ref=uninstrumented -fun:g_byte_array_remove_index=uninstrumented -fun:g_byte_array_remove_index_fast=uninstrumented -fun:g_byte_array_remove_range=uninstrumented -fun:g_byte_array_set_size=uninstrumented -fun:g_byte_array_sized_new=uninstrumented -fun:g_byte_array_sort=uninstrumented -fun:g_byte_array_sort_with_data=uninstrumented -fun:g_byte_array_steal=uninstrumented -fun:g_byte_array_unref=uninstrumented -fun:g_bytes_compare=uninstrumented -fun:g_bytes_equal=uninstrumented -fun:g_bytes_get_data=uninstrumented -fun:g_bytes_get_size=uninstrumented -fun:g_bytes_hash=uninstrumented -fun:g_bytes_new=uninstrumented -fun:g_bytes_new_from_bytes=uninstrumented -fun:g_bytes_new_static=uninstrumented -fun:g_bytes_new_take=uninstrumented -fun:g_bytes_new_with_free_func=uninstrumented -fun:g_bytes_ref=uninstrumented -fun:g_bytes_unref=uninstrumented -fun:g_bytes_unref_to_array=uninstrumented -fun:g_bytes_unref_to_data=uninstrumented -fun:g_cache_destroy=uninstrumented -fun:g_cache_insert=uninstrumented -fun:g_cache_key_foreach=uninstrumented -fun:g_cache_new=uninstrumented -fun:g_cache_remove=uninstrumented -fun:g_cache_value_foreach=uninstrumented -fun:g_canonicalize_filename=uninstrumented -fun:g_chdir=uninstrumented -fun:g_check_setuid=uninstrumented -fun:g_checksum_copy=uninstrumented -fun:g_checksum_free=uninstrumented -fun:g_checksum_get_digest=uninstrumented -fun:g_checksum_get_string=uninstrumented -fun:g_checksum_new=uninstrumented -fun:g_checksum_reset=uninstrumented -fun:g_checksum_type_get_length=uninstrumented -fun:g_checksum_update=uninstrumented -fun:g_child_watch_add=uninstrumented -fun:g_child_watch_add_full=uninstrumented -fun:g_child_watch_source_new=uninstrumented -fun:g_chmod=uninstrumented -fun:g_clear_error=uninstrumented -fun:g_clear_handle_id=uninstrumented -fun:g_clear_list=uninstrumented -fun:g_clear_pointer=uninstrumented -fun:g_clear_slist=uninstrumented -fun:g_close=uninstrumented -fun:g_completion_add_items=uninstrumented -fun:g_completion_clear_items=uninstrumented -fun:g_completion_complete=uninstrumented -fun:g_completion_complete_utf8=uninstrumented -fun:g_completion_free=uninstrumented -fun:g_completion_new=uninstrumented -fun:g_completion_remove_items=uninstrumented -fun:g_completion_set_compare=uninstrumented -fun:g_compute_checksum_for_bytes=uninstrumented -fun:g_compute_checksum_for_data=uninstrumented -fun:g_compute_checksum_for_string=uninstrumented -fun:g_compute_hmac_for_bytes=uninstrumented -fun:g_compute_hmac_for_data=uninstrumented -fun:g_compute_hmac_for_string=uninstrumented -fun:g_cond_broadcast=uninstrumented -fun:g_cond_clear=uninstrumented -fun:g_cond_free=uninstrumented -fun:g_cond_init=uninstrumented -fun:g_cond_new=uninstrumented -fun:g_cond_signal=uninstrumented -fun:g_cond_timed_wait=uninstrumented -fun:g_cond_wait=uninstrumented -fun:g_cond_wait_until=uninstrumented -fun:g_convert=uninstrumented -fun:g_convert_error_quark=uninstrumented -fun:g_convert_with_fallback=uninstrumented -fun:g_convert_with_iconv=uninstrumented -fun:g_creat=uninstrumented -fun:g_datalist_clear=uninstrumented -fun:g_datalist_foreach=uninstrumented -fun:g_datalist_get_data=uninstrumented -fun:g_datalist_get_flags=uninstrumented -fun:g_datalist_id_dup_data=uninstrumented -fun:g_datalist_id_get_data=uninstrumented -fun:g_datalist_id_remove_no_notify=uninstrumented -fun:g_datalist_id_replace_data=uninstrumented -fun:g_datalist_id_set_data_full=uninstrumented -fun:g_datalist_init=uninstrumented -fun:g_datalist_set_flags=uninstrumented -fun:g_datalist_unset_flags=uninstrumented -fun:g_dataset_destroy=uninstrumented -fun:g_dataset_foreach=uninstrumented -fun:g_dataset_id_get_data=uninstrumented -fun:g_dataset_id_remove_no_notify=uninstrumented -fun:g_dataset_id_set_data_full=uninstrumented -fun:g_date_add_days=uninstrumented -fun:g_date_add_months=uninstrumented -fun:g_date_add_years=uninstrumented -fun:g_date_clamp=uninstrumented -fun:g_date_clear=uninstrumented -fun:g_date_compare=uninstrumented -fun:g_date_copy=uninstrumented -fun:g_date_days_between=uninstrumented -fun:g_date_free=uninstrumented -fun:g_date_get_day=uninstrumented -fun:g_date_get_day_of_year=uninstrumented -fun:g_date_get_days_in_month=uninstrumented -fun:g_date_get_iso8601_week_of_year=uninstrumented -fun:g_date_get_julian=uninstrumented -fun:g_date_get_monday_week_of_year=uninstrumented -fun:g_date_get_monday_weeks_in_year=uninstrumented -fun:g_date_get_month=uninstrumented -fun:g_date_get_sunday_week_of_year=uninstrumented -fun:g_date_get_sunday_weeks_in_year=uninstrumented -fun:g_date_get_weekday=uninstrumented -fun:g_date_get_year=uninstrumented -fun:g_date_is_first_of_month=uninstrumented -fun:g_date_is_last_of_month=uninstrumented -fun:g_date_is_leap_year=uninstrumented -fun:g_date_new=uninstrumented -fun:g_date_new_dmy=uninstrumented -fun:g_date_new_julian=uninstrumented -fun:g_date_order=uninstrumented -fun:g_date_set_day=uninstrumented -fun:g_date_set_dmy=uninstrumented -fun:g_date_set_julian=uninstrumented -fun:g_date_set_month=uninstrumented -fun:g_date_set_parse=uninstrumented -fun:g_date_set_time=uninstrumented -fun:g_date_set_time_t=uninstrumented -fun:g_date_set_time_val=uninstrumented -fun:g_date_set_year=uninstrumented -fun:g_date_strftime=uninstrumented -fun:g_date_subtract_days=uninstrumented -fun:g_date_subtract_months=uninstrumented -fun:g_date_subtract_years=uninstrumented -fun:g_date_time_add=uninstrumented -fun:g_date_time_add_days=uninstrumented -fun:g_date_time_add_full=uninstrumented -fun:g_date_time_add_hours=uninstrumented -fun:g_date_time_add_minutes=uninstrumented -fun:g_date_time_add_months=uninstrumented -fun:g_date_time_add_seconds=uninstrumented -fun:g_date_time_add_weeks=uninstrumented -fun:g_date_time_add_years=uninstrumented -fun:g_date_time_compare=uninstrumented -fun:g_date_time_difference=uninstrumented -fun:g_date_time_equal=uninstrumented -fun:g_date_time_format=uninstrumented -fun:g_date_time_format_iso8601=uninstrumented -fun:g_date_time_get_day_of_month=uninstrumented -fun:g_date_time_get_day_of_week=uninstrumented -fun:g_date_time_get_day_of_year=uninstrumented -fun:g_date_time_get_hour=uninstrumented -fun:g_date_time_get_microsecond=uninstrumented -fun:g_date_time_get_minute=uninstrumented -fun:g_date_time_get_month=uninstrumented -fun:g_date_time_get_second=uninstrumented -fun:g_date_time_get_seconds=uninstrumented -fun:g_date_time_get_timezone=uninstrumented -fun:g_date_time_get_timezone_abbreviation=uninstrumented -fun:g_date_time_get_utc_offset=uninstrumented -fun:g_date_time_get_week_numbering_year=uninstrumented -fun:g_date_time_get_week_of_year=uninstrumented -fun:g_date_time_get_year=uninstrumented -fun:g_date_time_get_ymd=uninstrumented -fun:g_date_time_hash=uninstrumented -fun:g_date_time_is_daylight_savings=uninstrumented -fun:g_date_time_new=uninstrumented -fun:g_date_time_new_from_iso8601=uninstrumented -fun:g_date_time_new_from_timeval_local=uninstrumented -fun:g_date_time_new_from_timeval_utc=uninstrumented -fun:g_date_time_new_from_unix_local=uninstrumented -fun:g_date_time_new_from_unix_utc=uninstrumented -fun:g_date_time_new_local=uninstrumented -fun:g_date_time_new_now=uninstrumented -fun:g_date_time_new_now_local=uninstrumented -fun:g_date_time_new_now_utc=uninstrumented -fun:g_date_time_new_utc=uninstrumented -fun:g_date_time_ref=uninstrumented -fun:g_date_time_to_local=uninstrumented -fun:g_date_time_to_timeval=uninstrumented -fun:g_date_time_to_timezone=uninstrumented -fun:g_date_time_to_unix=uninstrumented -fun:g_date_time_to_utc=uninstrumented -fun:g_date_time_unref=uninstrumented -fun:g_date_to_struct_tm=uninstrumented -fun:g_date_valid=uninstrumented -fun:g_date_valid_day=uninstrumented -fun:g_date_valid_dmy=uninstrumented -fun:g_date_valid_julian=uninstrumented -fun:g_date_valid_month=uninstrumented -fun:g_date_valid_weekday=uninstrumented -fun:g_date_valid_year=uninstrumented -fun:g_dcgettext=uninstrumented -fun:g_dgettext=uninstrumented -fun:g_dir_close=uninstrumented -fun:g_dir_make_tmp=uninstrumented -fun:g_dir_new_from_dirp=uninstrumented -fun:g_dir_open=uninstrumented -fun:g_dir_open_with_errno=uninstrumented -fun:g_dir_read_name=uninstrumented -fun:g_dir_rewind=uninstrumented -fun:g_direct_equal=uninstrumented -fun:g_direct_hash=uninstrumented -fun:g_dngettext=uninstrumented -fun:g_double_equal=uninstrumented -fun:g_double_hash=uninstrumented -fun:g_dpgettext=uninstrumented -fun:g_dpgettext2=uninstrumented -fun:g_environ_getenv=uninstrumented -fun:g_environ_setenv=uninstrumented -fun:g_environ_unsetenv=uninstrumented -fun:g_error_copy=uninstrumented -fun:g_error_free=uninstrumented -fun:g_error_matches=uninstrumented -fun:g_error_new=uninstrumented -fun:g_error_new_literal=uninstrumented -fun:g_error_new_valist=uninstrumented -fun:g_file_error_from_errno=uninstrumented -fun:g_file_error_quark=uninstrumented -fun:g_file_get_contents=uninstrumented -fun:g_file_open_tmp=uninstrumented -fun:g_file_read_link=uninstrumented -fun:g_file_set_contents=uninstrumented -fun:g_file_test=uninstrumented -fun:g_filename_display_basename=uninstrumented -fun:g_filename_display_name=uninstrumented -fun:g_filename_from_uri=uninstrumented -fun:g_filename_from_utf8=uninstrumented -fun:g_filename_to_uri=uninstrumented -fun:g_filename_to_utf8=uninstrumented -fun:g_find_program_in_path=uninstrumented -fun:g_fopen=uninstrumented -fun:g_format_size=uninstrumented -fun:g_format_size_for_display=uninstrumented -fun:g_format_size_full=uninstrumented -fun:g_fprintf=uninstrumented -fun:g_free=uninstrumented -fun:g_freopen=uninstrumented -fun:g_fsync=uninstrumented -fun:g_get_application_name=uninstrumented -fun:g_get_charset=uninstrumented -fun:g_get_codeset=uninstrumented -fun:g_get_console_charset=uninstrumented -fun:g_get_current_dir=uninstrumented -fun:g_get_current_time=uninstrumented -fun:g_get_environ=uninstrumented -fun:g_get_filename_charsets=uninstrumented -fun:g_get_home_dir=uninstrumented -fun:g_get_host_name=uninstrumented -fun:g_get_language_names=uninstrumented -fun:g_get_language_names_with_category=uninstrumented -fun:g_get_locale_variants=uninstrumented -fun:g_get_monotonic_time=uninstrumented -fun:g_get_num_processors=uninstrumented -fun:g_get_os_info=uninstrumented -fun:g_get_prgname=uninstrumented -fun:g_get_real_name=uninstrumented -fun:g_get_real_time=uninstrumented -fun:g_get_system_config_dirs=uninstrumented -fun:g_get_system_data_dirs=uninstrumented -fun:g_get_tmp_dir=uninstrumented -fun:g_get_user_cache_dir=uninstrumented -fun:g_get_user_config_dir=uninstrumented -fun:g_get_user_data_dir=uninstrumented -fun:g_get_user_name=uninstrumented -fun:g_get_user_runtime_dir=uninstrumented -fun:g_get_user_special_dir=uninstrumented -fun:g_get_worker_context=uninstrumented -fun:g_getenv=uninstrumented -fun:g_hash_table_add=uninstrumented -fun:g_hash_table_contains=uninstrumented -fun:g_hash_table_destroy=uninstrumented -fun:g_hash_table_find=uninstrumented -fun:g_hash_table_foreach=uninstrumented -fun:g_hash_table_foreach_remove=uninstrumented -fun:g_hash_table_foreach_steal=uninstrumented -fun:g_hash_table_get_keys=uninstrumented -fun:g_hash_table_get_keys_as_array=uninstrumented -fun:g_hash_table_get_values=uninstrumented -fun:g_hash_table_insert=uninstrumented -fun:g_hash_table_iter_get_hash_table=uninstrumented -fun:g_hash_table_iter_init=uninstrumented -fun:g_hash_table_iter_next=uninstrumented -fun:g_hash_table_iter_remove=uninstrumented -fun:g_hash_table_iter_replace=uninstrumented -fun:g_hash_table_iter_steal=uninstrumented -fun:g_hash_table_lookup=uninstrumented -fun:g_hash_table_lookup_extended=uninstrumented -fun:g_hash_table_new=uninstrumented -fun:g_hash_table_new_full=uninstrumented -fun:g_hash_table_ref=uninstrumented -fun:g_hash_table_remove=uninstrumented -fun:g_hash_table_remove_all=uninstrumented -fun:g_hash_table_replace=uninstrumented -fun:g_hash_table_size=uninstrumented -fun:g_hash_table_steal=uninstrumented -fun:g_hash_table_steal_all=uninstrumented -fun:g_hash_table_steal_extended=uninstrumented -fun:g_hash_table_unref=uninstrumented -fun:g_hmac_copy=uninstrumented -fun:g_hmac_get_digest=uninstrumented -fun:g_hmac_get_string=uninstrumented -fun:g_hmac_new=uninstrumented -fun:g_hmac_ref=uninstrumented -fun:g_hmac_unref=uninstrumented -fun:g_hmac_update=uninstrumented -fun:g_hook_alloc=uninstrumented -fun:g_hook_compare_ids=uninstrumented -fun:g_hook_destroy=uninstrumented -fun:g_hook_destroy_link=uninstrumented -fun:g_hook_find=uninstrumented -fun:g_hook_find_data=uninstrumented -fun:g_hook_find_func=uninstrumented -fun:g_hook_find_func_data=uninstrumented -fun:g_hook_first_valid=uninstrumented -fun:g_hook_free=uninstrumented -fun:g_hook_get=uninstrumented -fun:g_hook_insert_before=uninstrumented -fun:g_hook_insert_sorted=uninstrumented -fun:g_hook_list_clear=uninstrumented -fun:g_hook_list_init=uninstrumented -fun:g_hook_list_invoke=uninstrumented -fun:g_hook_list_invoke_check=uninstrumented -fun:g_hook_list_marshal=uninstrumented -fun:g_hook_list_marshal_check=uninstrumented -fun:g_hook_next_valid=uninstrumented -fun:g_hook_prepend=uninstrumented -fun:g_hook_ref=uninstrumented -fun:g_hook_unref=uninstrumented -fun:g_hostname_is_ascii_encoded=uninstrumented -fun:g_hostname_is_ip_address=uninstrumented -fun:g_hostname_is_non_ascii=uninstrumented -fun:g_hostname_to_ascii=uninstrumented -fun:g_hostname_to_unicode=uninstrumented -fun:g_iconv=uninstrumented -fun:g_iconv_close=uninstrumented -fun:g_iconv_open=uninstrumented -fun:g_idle_add=uninstrumented -fun:g_idle_add_full=uninstrumented -fun:g_idle_remove_by_data=uninstrumented -fun:g_idle_source_new=uninstrumented -fun:g_int64_equal=uninstrumented -fun:g_int64_hash=uninstrumented -fun:g_int_equal=uninstrumented -fun:g_int_hash=uninstrumented -fun:g_intern_static_string=uninstrumented -fun:g_intern_string=uninstrumented -fun:g_io_add_watch=uninstrumented -fun:g_io_add_watch_full=uninstrumented -fun:g_io_channel_close=uninstrumented -fun:g_io_channel_error_from_errno=uninstrumented -fun:g_io_channel_error_quark=uninstrumented -fun:g_io_channel_flush=uninstrumented -fun:g_io_channel_get_buffer_condition=uninstrumented -fun:g_io_channel_get_buffer_size=uninstrumented -fun:g_io_channel_get_buffered=uninstrumented -fun:g_io_channel_get_close_on_unref=uninstrumented -fun:g_io_channel_get_encoding=uninstrumented -fun:g_io_channel_get_flags=uninstrumented -fun:g_io_channel_get_line_term=uninstrumented -fun:g_io_channel_init=uninstrumented -fun:g_io_channel_new_file=uninstrumented -fun:g_io_channel_read=uninstrumented -fun:g_io_channel_read_chars=uninstrumented -fun:g_io_channel_read_line=uninstrumented -fun:g_io_channel_read_line_string=uninstrumented -fun:g_io_channel_read_to_end=uninstrumented -fun:g_io_channel_read_unichar=uninstrumented -fun:g_io_channel_ref=uninstrumented -fun:g_io_channel_seek=uninstrumented -fun:g_io_channel_seek_position=uninstrumented -fun:g_io_channel_set_buffer_size=uninstrumented -fun:g_io_channel_set_buffered=uninstrumented -fun:g_io_channel_set_close_on_unref=uninstrumented -fun:g_io_channel_set_encoding=uninstrumented -fun:g_io_channel_set_flags=uninstrumented -fun:g_io_channel_set_line_term=uninstrumented -fun:g_io_channel_shutdown=uninstrumented -fun:g_io_channel_unix_get_fd=uninstrumented -fun:g_io_channel_unix_new=uninstrumented -fun:g_io_channel_unref=uninstrumented -fun:g_io_channel_write=uninstrumented -fun:g_io_channel_write_chars=uninstrumented -fun:g_io_channel_write_unichar=uninstrumented -fun:g_io_create_watch=uninstrumented -fun:g_key_file_error_quark=uninstrumented -fun:g_key_file_free=uninstrumented -fun:g_key_file_get_boolean=uninstrumented -fun:g_key_file_get_boolean_list=uninstrumented -fun:g_key_file_get_comment=uninstrumented -fun:g_key_file_get_double=uninstrumented -fun:g_key_file_get_double_list=uninstrumented -fun:g_key_file_get_groups=uninstrumented -fun:g_key_file_get_int64=uninstrumented -fun:g_key_file_get_integer=uninstrumented -fun:g_key_file_get_integer_list=uninstrumented -fun:g_key_file_get_keys=uninstrumented -fun:g_key_file_get_locale_for_key=uninstrumented -fun:g_key_file_get_locale_string=uninstrumented -fun:g_key_file_get_locale_string_list=uninstrumented -fun:g_key_file_get_start_group=uninstrumented -fun:g_key_file_get_string=uninstrumented -fun:g_key_file_get_string_list=uninstrumented -fun:g_key_file_get_uint64=uninstrumented -fun:g_key_file_get_value=uninstrumented -fun:g_key_file_has_group=uninstrumented -fun:g_key_file_has_key=uninstrumented -fun:g_key_file_load_from_bytes=uninstrumented -fun:g_key_file_load_from_data=uninstrumented -fun:g_key_file_load_from_data_dirs=uninstrumented -fun:g_key_file_load_from_dirs=uninstrumented -fun:g_key_file_load_from_file=uninstrumented -fun:g_key_file_new=uninstrumented -fun:g_key_file_ref=uninstrumented -fun:g_key_file_remove_comment=uninstrumented -fun:g_key_file_remove_group=uninstrumented -fun:g_key_file_remove_key=uninstrumented -fun:g_key_file_save_to_file=uninstrumented -fun:g_key_file_set_boolean=uninstrumented -fun:g_key_file_set_boolean_list=uninstrumented -fun:g_key_file_set_comment=uninstrumented -fun:g_key_file_set_double=uninstrumented -fun:g_key_file_set_double_list=uninstrumented -fun:g_key_file_set_int64=uninstrumented -fun:g_key_file_set_integer=uninstrumented -fun:g_key_file_set_integer_list=uninstrumented -fun:g_key_file_set_list_separator=uninstrumented -fun:g_key_file_set_locale_string=uninstrumented -fun:g_key_file_set_locale_string_list=uninstrumented -fun:g_key_file_set_string=uninstrumented -fun:g_key_file_set_string_list=uninstrumented -fun:g_key_file_set_uint64=uninstrumented -fun:g_key_file_set_value=uninstrumented -fun:g_key_file_to_data=uninstrumented -fun:g_key_file_unref=uninstrumented -fun:g_list_alloc=uninstrumented -fun:g_list_append=uninstrumented -fun:g_list_concat=uninstrumented -fun:g_list_copy=uninstrumented -fun:g_list_copy_deep=uninstrumented -fun:g_list_delete_link=uninstrumented -fun:g_list_find=uninstrumented -fun:g_list_find_custom=uninstrumented -fun:g_list_first=uninstrumented -fun:g_list_foreach=uninstrumented -fun:g_list_free=uninstrumented -fun:g_list_free_1=uninstrumented -fun:g_list_free_full=uninstrumented -fun:g_list_index=uninstrumented -fun:g_list_insert=uninstrumented -fun:g_list_insert_before=uninstrumented -fun:g_list_insert_before_link=uninstrumented -fun:g_list_insert_sorted=uninstrumented -fun:g_list_insert_sorted_with_data=uninstrumented -fun:g_list_last=uninstrumented -fun:g_list_length=uninstrumented -fun:g_list_nth=uninstrumented -fun:g_list_nth_data=uninstrumented -fun:g_list_nth_prev=uninstrumented -fun:g_list_pop_allocator=uninstrumented -fun:g_list_position=uninstrumented -fun:g_list_prepend=uninstrumented -fun:g_list_push_allocator=uninstrumented -fun:g_list_remove=uninstrumented -fun:g_list_remove_all=uninstrumented -fun:g_list_remove_link=uninstrumented -fun:g_list_reverse=uninstrumented -fun:g_list_sort=uninstrumented -fun:g_list_sort_with_data=uninstrumented -fun:g_listenv=uninstrumented -fun:g_locale_from_utf8=uninstrumented -fun:g_locale_to_utf8=uninstrumented -fun:g_log=uninstrumented -fun:g_log_default_handler=uninstrumented -fun:g_log_remove_handler=uninstrumented -fun:g_log_set_always_fatal=uninstrumented -fun:g_log_set_default_handler=uninstrumented -fun:g_log_set_fatal_mask=uninstrumented -fun:g_log_set_handler=uninstrumented -fun:g_log_set_handler_full=uninstrumented -fun:g_log_set_writer_func=uninstrumented -fun:g_log_structured=uninstrumented -fun:g_log_structured_array=uninstrumented -fun:g_log_structured_standard=uninstrumented -fun:g_log_variant=uninstrumented -fun:g_log_writer_default=uninstrumented -fun:g_log_writer_format_fields=uninstrumented -fun:g_log_writer_is_journald=uninstrumented -fun:g_log_writer_journald=uninstrumented -fun:g_log_writer_standard_streams=uninstrumented -fun:g_log_writer_supports_color=uninstrumented -fun:g_logv=uninstrumented -fun:g_lstat=uninstrumented -fun:g_main_context_acquire=uninstrumented -fun:g_main_context_add_poll=uninstrumented -fun:g_main_context_check=uninstrumented -fun:g_main_context_default=uninstrumented -fun:g_main_context_dispatch=uninstrumented -fun:g_main_context_find_source_by_funcs_user_data=uninstrumented -fun:g_main_context_find_source_by_id=uninstrumented -fun:g_main_context_find_source_by_user_data=uninstrumented -fun:g_main_context_get_poll_func=uninstrumented -fun:g_main_context_get_thread_default=uninstrumented -fun:g_main_context_invoke=uninstrumented -fun:g_main_context_invoke_full=uninstrumented -fun:g_main_context_is_owner=uninstrumented -fun:g_main_context_iteration=uninstrumented -fun:g_main_context_new=uninstrumented -fun:g_main_context_new_with_next_id=uninstrumented -fun:g_main_context_pending=uninstrumented -fun:g_main_context_pop_thread_default=uninstrumented -fun:g_main_context_prepare=uninstrumented -fun:g_main_context_push_thread_default=uninstrumented -fun:g_main_context_query=uninstrumented -fun:g_main_context_ref=uninstrumented -fun:g_main_context_ref_thread_default=uninstrumented -fun:g_main_context_release=uninstrumented -fun:g_main_context_remove_poll=uninstrumented -fun:g_main_context_set_poll_func=uninstrumented -fun:g_main_context_unref=uninstrumented -fun:g_main_context_wait=uninstrumented -fun:g_main_context_wakeup=uninstrumented -fun:g_main_current_source=uninstrumented -fun:g_main_depth=uninstrumented -fun:g_main_loop_get_context=uninstrumented -fun:g_main_loop_is_running=uninstrumented -fun:g_main_loop_new=uninstrumented -fun:g_main_loop_quit=uninstrumented -fun:g_main_loop_ref=uninstrumented -fun:g_main_loop_run=uninstrumented -fun:g_main_loop_unref=uninstrumented -fun:g_malloc=uninstrumented -fun:g_malloc0=uninstrumented -fun:g_malloc0_n=uninstrumented -fun:g_malloc_n=uninstrumented -fun:g_mapped_file_free=uninstrumented -fun:g_mapped_file_get_bytes=uninstrumented -fun:g_mapped_file_get_contents=uninstrumented -fun:g_mapped_file_get_length=uninstrumented -fun:g_mapped_file_new=uninstrumented -fun:g_mapped_file_new_from_fd=uninstrumented -fun:g_mapped_file_ref=uninstrumented -fun:g_mapped_file_unref=uninstrumented -fun:g_markup_collect_attributes=uninstrumented -fun:g_markup_error_quark=uninstrumented -fun:g_markup_escape_text=uninstrumented -fun:g_markup_parse_context_end_parse=uninstrumented -fun:g_markup_parse_context_free=uninstrumented -fun:g_markup_parse_context_get_element=uninstrumented -fun:g_markup_parse_context_get_element_stack=uninstrumented -fun:g_markup_parse_context_get_position=uninstrumented -fun:g_markup_parse_context_get_user_data=uninstrumented -fun:g_markup_parse_context_new=uninstrumented -fun:g_markup_parse_context_parse=uninstrumented -fun:g_markup_parse_context_pop=uninstrumented -fun:g_markup_parse_context_push=uninstrumented -fun:g_markup_parse_context_ref=uninstrumented -fun:g_markup_parse_context_unref=uninstrumented -fun:g_markup_printf_escaped=uninstrumented -fun:g_markup_vprintf_escaped=uninstrumented -fun:g_match_info_expand_references=uninstrumented -fun:g_match_info_fetch=uninstrumented -fun:g_match_info_fetch_all=uninstrumented -fun:g_match_info_fetch_named=uninstrumented -fun:g_match_info_fetch_named_pos=uninstrumented -fun:g_match_info_fetch_pos=uninstrumented -fun:g_match_info_free=uninstrumented -fun:g_match_info_get_match_count=uninstrumented -fun:g_match_info_get_regex=uninstrumented -fun:g_match_info_get_string=uninstrumented -fun:g_match_info_is_partial_match=uninstrumented -fun:g_match_info_matches=uninstrumented -fun:g_match_info_next=uninstrumented -fun:g_match_info_ref=uninstrumented -fun:g_match_info_unref=uninstrumented -fun:g_mem_chunk_alloc=uninstrumented -fun:g_mem_chunk_alloc0=uninstrumented -fun:g_mem_chunk_clean=uninstrumented -fun:g_mem_chunk_destroy=uninstrumented -fun:g_mem_chunk_free=uninstrumented -fun:g_mem_chunk_info=uninstrumented -fun:g_mem_chunk_new=uninstrumented -fun:g_mem_chunk_print=uninstrumented -fun:g_mem_chunk_reset=uninstrumented -fun:g_mem_is_system_malloc=uninstrumented -fun:g_mem_profile=uninstrumented -fun:g_mem_set_vtable=uninstrumented -fun:g_memdup=uninstrumented -fun:g_mkdir=uninstrumented -fun:g_mkdir_with_parents=uninstrumented -fun:g_mkdtemp=uninstrumented -fun:g_mkdtemp_full=uninstrumented -fun:g_mkstemp=uninstrumented -fun:g_mkstemp_full=uninstrumented -fun:g_mutex_clear=uninstrumented -fun:g_mutex_free=uninstrumented -fun:g_mutex_init=uninstrumented -fun:g_mutex_lock=uninstrumented -fun:g_mutex_new=uninstrumented -fun:g_mutex_trylock=uninstrumented -fun:g_mutex_unlock=uninstrumented -fun:g_node_child_index=uninstrumented -fun:g_node_child_position=uninstrumented -fun:g_node_children_foreach=uninstrumented -fun:g_node_copy=uninstrumented -fun:g_node_copy_deep=uninstrumented -fun:g_node_depth=uninstrumented -fun:g_node_destroy=uninstrumented -fun:g_node_find=uninstrumented -fun:g_node_find_child=uninstrumented -fun:g_node_first_sibling=uninstrumented -fun:g_node_get_root=uninstrumented -fun:g_node_insert=uninstrumented -fun:g_node_insert_after=uninstrumented -fun:g_node_insert_before=uninstrumented -fun:g_node_is_ancestor=uninstrumented -fun:g_node_last_child=uninstrumented -fun:g_node_last_sibling=uninstrumented -fun:g_node_max_height=uninstrumented -fun:g_node_n_children=uninstrumented -fun:g_node_n_nodes=uninstrumented -fun:g_node_new=uninstrumented -fun:g_node_nth_child=uninstrumented -fun:g_node_pop_allocator=uninstrumented -fun:g_node_prepend=uninstrumented -fun:g_node_push_allocator=uninstrumented -fun:g_node_reverse_children=uninstrumented -fun:g_node_traverse=uninstrumented -fun:g_node_unlink=uninstrumented -fun:g_nullify_pointer=uninstrumented -fun:g_number_parser_error_quark=uninstrumented -fun:g_on_error_query=uninstrumented -fun:g_on_error_stack_trace=uninstrumented -fun:g_once_impl=uninstrumented -fun:g_once_init_enter=uninstrumented -fun:g_once_init_enter_impl=uninstrumented -fun:g_once_init_leave=uninstrumented -fun:g_open=uninstrumented -fun:g_option_context_add_group=uninstrumented -fun:g_option_context_add_main_entries=uninstrumented -fun:g_option_context_free=uninstrumented -fun:g_option_context_get_description=uninstrumented -fun:g_option_context_get_help=uninstrumented -fun:g_option_context_get_help_enabled=uninstrumented -fun:g_option_context_get_ignore_unknown_options=uninstrumented -fun:g_option_context_get_main_group=uninstrumented -fun:g_option_context_get_strict_posix=uninstrumented -fun:g_option_context_get_summary=uninstrumented -fun:g_option_context_new=uninstrumented -fun:g_option_context_parse=uninstrumented -fun:g_option_context_parse_strv=uninstrumented -fun:g_option_context_set_description=uninstrumented -fun:g_option_context_set_help_enabled=uninstrumented -fun:g_option_context_set_ignore_unknown_options=uninstrumented -fun:g_option_context_set_main_group=uninstrumented -fun:g_option_context_set_strict_posix=uninstrumented -fun:g_option_context_set_summary=uninstrumented -fun:g_option_context_set_translate_func=uninstrumented -fun:g_option_context_set_translation_domain=uninstrumented -fun:g_option_error_quark=uninstrumented -fun:g_option_group_add_entries=uninstrumented -fun:g_option_group_free=uninstrumented -fun:g_option_group_new=uninstrumented -fun:g_option_group_ref=uninstrumented -fun:g_option_group_set_error_hook=uninstrumented -fun:g_option_group_set_parse_hooks=uninstrumented -fun:g_option_group_set_translate_func=uninstrumented -fun:g_option_group_set_translation_domain=uninstrumented -fun:g_option_group_unref=uninstrumented -fun:g_parse_debug_string=uninstrumented -fun:g_path_get_basename=uninstrumented -fun:g_path_get_dirname=uninstrumented -fun:g_path_is_absolute=uninstrumented -fun:g_path_skip_root=uninstrumented -fun:g_pattern_match=uninstrumented -fun:g_pattern_match_simple=uninstrumented -fun:g_pattern_match_string=uninstrumented -fun:g_pattern_spec_equal=uninstrumented -fun:g_pattern_spec_free=uninstrumented -fun:g_pattern_spec_new=uninstrumented -fun:g_pointer_bit_lock=uninstrumented -fun:g_pointer_bit_trylock=uninstrumented -fun:g_pointer_bit_unlock=uninstrumented -fun:g_poll=uninstrumented -fun:g_prefix_error=uninstrumented -fun:g_print=uninstrumented -fun:g_printerr=uninstrumented -fun:g_printf=uninstrumented -fun:g_printf_string_upper_bound=uninstrumented -fun:g_private_get=uninstrumented -fun:g_private_new=uninstrumented -fun:g_private_replace=uninstrumented -fun:g_private_set=uninstrumented -fun:g_private_set_alloc0=uninstrumented -fun:g_propagate_error=uninstrumented -fun:g_propagate_prefixed_error=uninstrumented -fun:g_ptr_array_add=uninstrumented -fun:g_ptr_array_copy=uninstrumented -fun:g_ptr_array_extend=uninstrumented -fun:g_ptr_array_extend_and_steal=uninstrumented -fun:g_ptr_array_find=uninstrumented -fun:g_ptr_array_find_with_equal_func=uninstrumented -fun:g_ptr_array_foreach=uninstrumented -fun:g_ptr_array_free=uninstrumented -fun:g_ptr_array_insert=uninstrumented -fun:g_ptr_array_new=uninstrumented -fun:g_ptr_array_new_full=uninstrumented -fun:g_ptr_array_new_with_free_func=uninstrumented -fun:g_ptr_array_ref=uninstrumented -fun:g_ptr_array_remove=uninstrumented -fun:g_ptr_array_remove_fast=uninstrumented -fun:g_ptr_array_remove_index=uninstrumented -fun:g_ptr_array_remove_index_fast=uninstrumented -fun:g_ptr_array_remove_range=uninstrumented -fun:g_ptr_array_set_free_func=uninstrumented -fun:g_ptr_array_set_size=uninstrumented -fun:g_ptr_array_sized_new=uninstrumented -fun:g_ptr_array_sort=uninstrumented -fun:g_ptr_array_sort_with_data=uninstrumented -fun:g_ptr_array_steal=uninstrumented -fun:g_ptr_array_steal_index=uninstrumented -fun:g_ptr_array_steal_index_fast=uninstrumented -fun:g_ptr_array_unref=uninstrumented -fun:g_qsort_with_data=uninstrumented -fun:g_quark_from_static_string=uninstrumented -fun:g_quark_from_string=uninstrumented -fun:g_quark_init=uninstrumented -fun:g_quark_to_string=uninstrumented -fun:g_quark_try_string=uninstrumented -fun:g_queue_clear=uninstrumented -fun:g_queue_clear_full=uninstrumented -fun:g_queue_copy=uninstrumented -fun:g_queue_delete_link=uninstrumented -fun:g_queue_find=uninstrumented -fun:g_queue_find_custom=uninstrumented -fun:g_queue_foreach=uninstrumented -fun:g_queue_free=uninstrumented -fun:g_queue_free_full=uninstrumented -fun:g_queue_get_length=uninstrumented -fun:g_queue_index=uninstrumented -fun:g_queue_init=uninstrumented -fun:g_queue_insert_after=uninstrumented -fun:g_queue_insert_after_link=uninstrumented -fun:g_queue_insert_before=uninstrumented -fun:g_queue_insert_before_link=uninstrumented -fun:g_queue_insert_sorted=uninstrumented -fun:g_queue_is_empty=uninstrumented -fun:g_queue_link_index=uninstrumented -fun:g_queue_new=uninstrumented -fun:g_queue_peek_head=uninstrumented -fun:g_queue_peek_head_link=uninstrumented -fun:g_queue_peek_nth=uninstrumented -fun:g_queue_peek_nth_link=uninstrumented -fun:g_queue_peek_tail=uninstrumented -fun:g_queue_peek_tail_link=uninstrumented -fun:g_queue_pop_head=uninstrumented -fun:g_queue_pop_head_link=uninstrumented -fun:g_queue_pop_nth=uninstrumented -fun:g_queue_pop_nth_link=uninstrumented -fun:g_queue_pop_tail=uninstrumented -fun:g_queue_pop_tail_link=uninstrumented -fun:g_queue_push_head=uninstrumented -fun:g_queue_push_head_link=uninstrumented -fun:g_queue_push_nth=uninstrumented -fun:g_queue_push_nth_link=uninstrumented -fun:g_queue_push_tail=uninstrumented -fun:g_queue_push_tail_link=uninstrumented -fun:g_queue_remove=uninstrumented -fun:g_queue_remove_all=uninstrumented -fun:g_queue_reverse=uninstrumented -fun:g_queue_sort=uninstrumented -fun:g_queue_unlink=uninstrumented -fun:g_rand_copy=uninstrumented -fun:g_rand_double=uninstrumented -fun:g_rand_double_range=uninstrumented -fun:g_rand_free=uninstrumented -fun:g_rand_int=uninstrumented -fun:g_rand_int_range=uninstrumented -fun:g_rand_new=uninstrumented -fun:g_rand_new_with_seed=uninstrumented -fun:g_rand_new_with_seed_array=uninstrumented -fun:g_rand_set_seed=uninstrumented -fun:g_rand_set_seed_array=uninstrumented -fun:g_random_double=uninstrumented -fun:g_random_double_range=uninstrumented -fun:g_random_int=uninstrumented -fun:g_random_int_range=uninstrumented -fun:g_random_set_seed=uninstrumented -fun:g_rc_box_acquire=uninstrumented -fun:g_rc_box_alloc=uninstrumented -fun:g_rc_box_alloc0=uninstrumented -fun:g_rc_box_alloc_full=uninstrumented -fun:g_rc_box_dup=uninstrumented -fun:g_rc_box_get_size=uninstrumented -fun:g_rc_box_release=uninstrumented -fun:g_rc_box_release_full=uninstrumented -fun:g_realloc=uninstrumented -fun:g_realloc_n=uninstrumented -fun:g_rec_mutex_clear=uninstrumented -fun:g_rec_mutex_init=uninstrumented -fun:g_rec_mutex_lock=uninstrumented -fun:g_rec_mutex_trylock=uninstrumented -fun:g_rec_mutex_unlock=uninstrumented -fun:g_ref_count_compare=uninstrumented -fun:g_ref_count_dec=uninstrumented -fun:g_ref_count_inc=uninstrumented -fun:g_ref_count_init=uninstrumented -fun:g_ref_string_acquire=uninstrumented -fun:g_ref_string_length=uninstrumented -fun:g_ref_string_new=uninstrumented -fun:g_ref_string_new_intern=uninstrumented -fun:g_ref_string_new_len=uninstrumented -fun:g_ref_string_release=uninstrumented -fun:g_regex_check_replacement=uninstrumented -fun:g_regex_error_quark=uninstrumented -fun:g_regex_escape_nul=uninstrumented -fun:g_regex_escape_string=uninstrumented -fun:g_regex_get_capture_count=uninstrumented -fun:g_regex_get_compile_flags=uninstrumented -fun:g_regex_get_has_cr_or_lf=uninstrumented -fun:g_regex_get_match_flags=uninstrumented -fun:g_regex_get_max_backref=uninstrumented -fun:g_regex_get_max_lookbehind=uninstrumented -fun:g_regex_get_pattern=uninstrumented -fun:g_regex_get_string_number=uninstrumented -fun:g_regex_match=uninstrumented -fun:g_regex_match_all=uninstrumented -fun:g_regex_match_all_full=uninstrumented -fun:g_regex_match_full=uninstrumented -fun:g_regex_match_simple=uninstrumented -fun:g_regex_new=uninstrumented -fun:g_regex_ref=uninstrumented -fun:g_regex_replace=uninstrumented -fun:g_regex_replace_eval=uninstrumented -fun:g_regex_replace_literal=uninstrumented -fun:g_regex_split=uninstrumented -fun:g_regex_split_full=uninstrumented -fun:g_regex_split_simple=uninstrumented -fun:g_regex_unref=uninstrumented -fun:g_relation_count=uninstrumented -fun:g_relation_delete=uninstrumented -fun:g_relation_destroy=uninstrumented -fun:g_relation_exists=uninstrumented -fun:g_relation_index=uninstrumented -fun:g_relation_insert=uninstrumented -fun:g_relation_new=uninstrumented -fun:g_relation_print=uninstrumented -fun:g_relation_select=uninstrumented -fun:g_reload_user_special_dirs_cache=uninstrumented -fun:g_remove=uninstrumented -fun:g_rename=uninstrumented -fun:g_return_if_fail_warning=uninstrumented -fun:g_rmdir=uninstrumented -fun:g_rw_lock_clear=uninstrumented -fun:g_rw_lock_init=uninstrumented -fun:g_rw_lock_reader_lock=uninstrumented -fun:g_rw_lock_reader_trylock=uninstrumented -fun:g_rw_lock_reader_unlock=uninstrumented -fun:g_rw_lock_writer_lock=uninstrumented -fun:g_rw_lock_writer_trylock=uninstrumented -fun:g_rw_lock_writer_unlock=uninstrumented -fun:g_scanner_cur_line=uninstrumented -fun:g_scanner_cur_position=uninstrumented -fun:g_scanner_cur_token=uninstrumented -fun:g_scanner_cur_value=uninstrumented -fun:g_scanner_destroy=uninstrumented -fun:g_scanner_eof=uninstrumented -fun:g_scanner_error=uninstrumented -fun:g_scanner_get_next_token=uninstrumented -fun:g_scanner_input_file=uninstrumented -fun:g_scanner_input_text=uninstrumented -fun:g_scanner_lookup_symbol=uninstrumented -fun:g_scanner_new=uninstrumented -fun:g_scanner_peek_next_token=uninstrumented -fun:g_scanner_scope_add_symbol=uninstrumented -fun:g_scanner_scope_foreach_symbol=uninstrumented -fun:g_scanner_scope_lookup_symbol=uninstrumented -fun:g_scanner_scope_remove_symbol=uninstrumented -fun:g_scanner_set_scope=uninstrumented -fun:g_scanner_sync_file_offset=uninstrumented -fun:g_scanner_unexp_token=uninstrumented -fun:g_scanner_warn=uninstrumented -fun:g_sequence_append=uninstrumented -fun:g_sequence_foreach=uninstrumented -fun:g_sequence_foreach_range=uninstrumented -fun:g_sequence_free=uninstrumented -fun:g_sequence_get=uninstrumented -fun:g_sequence_get_begin_iter=uninstrumented -fun:g_sequence_get_end_iter=uninstrumented -fun:g_sequence_get_iter_at_pos=uninstrumented -fun:g_sequence_get_length=uninstrumented -fun:g_sequence_insert_before=uninstrumented -fun:g_sequence_insert_sorted=uninstrumented -fun:g_sequence_insert_sorted_iter=uninstrumented -fun:g_sequence_is_empty=uninstrumented -fun:g_sequence_iter_compare=uninstrumented -fun:g_sequence_iter_get_position=uninstrumented -fun:g_sequence_iter_get_sequence=uninstrumented -fun:g_sequence_iter_is_begin=uninstrumented -fun:g_sequence_iter_is_end=uninstrumented -fun:g_sequence_iter_move=uninstrumented -fun:g_sequence_iter_next=uninstrumented -fun:g_sequence_iter_prev=uninstrumented -fun:g_sequence_lookup=uninstrumented -fun:g_sequence_lookup_iter=uninstrumented -fun:g_sequence_move=uninstrumented -fun:g_sequence_move_range=uninstrumented -fun:g_sequence_new=uninstrumented -fun:g_sequence_prepend=uninstrumented -fun:g_sequence_range_get_midpoint=uninstrumented -fun:g_sequence_remove=uninstrumented -fun:g_sequence_remove_range=uninstrumented -fun:g_sequence_search=uninstrumented -fun:g_sequence_search_iter=uninstrumented -fun:g_sequence_set=uninstrumented -fun:g_sequence_sort=uninstrumented -fun:g_sequence_sort_changed=uninstrumented -fun:g_sequence_sort_changed_iter=uninstrumented -fun:g_sequence_sort_iter=uninstrumented -fun:g_sequence_swap=uninstrumented -fun:g_set_application_name=uninstrumented -fun:g_set_error=uninstrumented -fun:g_set_error_literal=uninstrumented -fun:g_set_prgname=uninstrumented -fun:g_set_print_handler=uninstrumented -fun:g_set_printerr_handler=uninstrumented -fun:g_set_user_dirs=uninstrumented -fun:g_setenv=uninstrumented -fun:g_shell_error_quark=uninstrumented -fun:g_shell_parse_argv=uninstrumented -fun:g_shell_quote=uninstrumented -fun:g_shell_unquote=uninstrumented -fun:g_slice_alloc=uninstrumented -fun:g_slice_alloc0=uninstrumented -fun:g_slice_copy=uninstrumented -fun:g_slice_free1=uninstrumented -fun:g_slice_free_chain_with_offset=uninstrumented -fun:g_slice_get_config=uninstrumented -fun:g_slice_get_config_state=uninstrumented -fun:g_slice_set_config=uninstrumented -fun:g_slist_alloc=uninstrumented -fun:g_slist_append=uninstrumented -fun:g_slist_concat=uninstrumented -fun:g_slist_copy=uninstrumented -fun:g_slist_copy_deep=uninstrumented -fun:g_slist_delete_link=uninstrumented -fun:g_slist_find=uninstrumented -fun:g_slist_find_custom=uninstrumented -fun:g_slist_foreach=uninstrumented -fun:g_slist_free=uninstrumented -fun:g_slist_free_1=uninstrumented -fun:g_slist_free_full=uninstrumented -fun:g_slist_index=uninstrumented -fun:g_slist_insert=uninstrumented -fun:g_slist_insert_before=uninstrumented -fun:g_slist_insert_sorted=uninstrumented -fun:g_slist_insert_sorted_with_data=uninstrumented -fun:g_slist_last=uninstrumented -fun:g_slist_length=uninstrumented -fun:g_slist_nth=uninstrumented -fun:g_slist_nth_data=uninstrumented -fun:g_slist_pop_allocator=uninstrumented -fun:g_slist_position=uninstrumented -fun:g_slist_prepend=uninstrumented -fun:g_slist_push_allocator=uninstrumented -fun:g_slist_remove=uninstrumented -fun:g_slist_remove_all=uninstrumented -fun:g_slist_remove_link=uninstrumented -fun:g_slist_reverse=uninstrumented -fun:g_slist_sort=uninstrumented -fun:g_slist_sort_with_data=uninstrumented -fun:g_snprintf=uninstrumented -fun:g_source_add_child_source=uninstrumented -fun:g_source_add_poll=uninstrumented -fun:g_source_add_unix_fd=uninstrumented -fun:g_source_attach=uninstrumented -fun:g_source_destroy=uninstrumented -fun:g_source_get_can_recurse=uninstrumented -fun:g_source_get_context=uninstrumented -fun:g_source_get_current_time=uninstrumented -fun:g_source_get_id=uninstrumented -fun:g_source_get_name=uninstrumented -fun:g_source_get_priority=uninstrumented -fun:g_source_get_ready_time=uninstrumented -fun:g_source_get_time=uninstrumented -fun:g_source_is_destroyed=uninstrumented -fun:g_source_modify_unix_fd=uninstrumented -fun:g_source_new=uninstrumented -fun:g_source_query_unix_fd=uninstrumented -fun:g_source_ref=uninstrumented -fun:g_source_remove=uninstrumented -fun:g_source_remove_by_funcs_user_data=uninstrumented -fun:g_source_remove_by_user_data=uninstrumented -fun:g_source_remove_child_source=uninstrumented -fun:g_source_remove_poll=uninstrumented -fun:g_source_remove_unix_fd=uninstrumented -fun:g_source_set_callback=uninstrumented -fun:g_source_set_callback_indirect=uninstrumented -fun:g_source_set_can_recurse=uninstrumented -fun:g_source_set_dispose_function=uninstrumented -fun:g_source_set_funcs=uninstrumented -fun:g_source_set_name=uninstrumented -fun:g_source_set_name_by_id=uninstrumented -fun:g_source_set_priority=uninstrumented -fun:g_source_set_ready_time=uninstrumented -fun:g_source_unref=uninstrumented -fun:g_spaced_primes_closest=uninstrumented -fun:g_spawn_async=uninstrumented -fun:g_spawn_async_with_fds=uninstrumented -fun:g_spawn_async_with_pipes=uninstrumented -fun:g_spawn_check_exit_status=uninstrumented -fun:g_spawn_close_pid=uninstrumented -fun:g_spawn_command_line_async=uninstrumented -fun:g_spawn_command_line_sync=uninstrumented -fun:g_spawn_error_quark=uninstrumented -fun:g_spawn_exit_error_quark=uninstrumented -fun:g_spawn_sync=uninstrumented -fun:g_sprintf=uninstrumented -fun:g_stat=uninstrumented -fun:g_static_mutex_free=uninstrumented -fun:g_static_mutex_get_mutex_impl=uninstrumented -fun:g_static_mutex_init=uninstrumented -fun:g_static_private_free=uninstrumented -fun:g_static_private_get=uninstrumented -fun:g_static_private_init=uninstrumented -fun:g_static_private_set=uninstrumented -fun:g_static_rec_mutex_free=uninstrumented -fun:g_static_rec_mutex_init=uninstrumented -fun:g_static_rec_mutex_lock=uninstrumented -fun:g_static_rec_mutex_lock_full=uninstrumented -fun:g_static_rec_mutex_trylock=uninstrumented -fun:g_static_rec_mutex_unlock=uninstrumented -fun:g_static_rec_mutex_unlock_full=uninstrumented -fun:g_static_rw_lock_free=uninstrumented -fun:g_static_rw_lock_init=uninstrumented -fun:g_static_rw_lock_reader_lock=uninstrumented -fun:g_static_rw_lock_reader_trylock=uninstrumented -fun:g_static_rw_lock_reader_unlock=uninstrumented -fun:g_static_rw_lock_writer_lock=uninstrumented -fun:g_static_rw_lock_writer_trylock=uninstrumented -fun:g_static_rw_lock_writer_unlock=uninstrumented -fun:g_stpcpy=uninstrumented -fun:g_str_equal=uninstrumented -fun:g_str_has_prefix=uninstrumented -fun:g_str_has_suffix=uninstrumented -fun:g_str_hash=uninstrumented -fun:g_str_is_ascii=uninstrumented -fun:g_str_match_string=uninstrumented -fun:g_str_to_ascii=uninstrumented -fun:g_str_tokenize_and_fold=uninstrumented -fun:g_strcanon=uninstrumented -fun:g_strcasecmp=uninstrumented -fun:g_strchomp=uninstrumented -fun:g_strchug=uninstrumented -fun:g_strcmp0=uninstrumented -fun:g_strcompress=uninstrumented -fun:g_strconcat=uninstrumented -fun:g_strdelimit=uninstrumented -fun:g_strdown=uninstrumented -fun:g_strdup=uninstrumented -fun:g_strdup_printf=uninstrumented -fun:g_strdup_vprintf=uninstrumented -fun:g_strdupv=uninstrumented -fun:g_strerror=uninstrumented -fun:g_strescape=uninstrumented -fun:g_strfreev=uninstrumented -fun:g_string_append=uninstrumented -fun:g_string_append_c=uninstrumented -fun:g_string_append_len=uninstrumented -fun:g_string_append_printf=uninstrumented -fun:g_string_append_unichar=uninstrumented -fun:g_string_append_uri_escaped=uninstrumented -fun:g_string_append_vprintf=uninstrumented -fun:g_string_ascii_down=uninstrumented -fun:g_string_ascii_up=uninstrumented -fun:g_string_assign=uninstrumented -fun:g_string_chunk_clear=uninstrumented -fun:g_string_chunk_free=uninstrumented -fun:g_string_chunk_insert=uninstrumented -fun:g_string_chunk_insert_const=uninstrumented -fun:g_string_chunk_insert_len=uninstrumented -fun:g_string_chunk_new=uninstrumented -fun:g_string_down=uninstrumented -fun:g_string_equal=uninstrumented -fun:g_string_erase=uninstrumented -fun:g_string_free=uninstrumented -fun:g_string_free_to_bytes=uninstrumented -fun:g_string_hash=uninstrumented -fun:g_string_insert=uninstrumented -fun:g_string_insert_c=uninstrumented -fun:g_string_insert_len=uninstrumented -fun:g_string_insert_unichar=uninstrumented -fun:g_string_new=uninstrumented -fun:g_string_new_len=uninstrumented -fun:g_string_overwrite=uninstrumented -fun:g_string_overwrite_len=uninstrumented -fun:g_string_prepend=uninstrumented -fun:g_string_prepend_c=uninstrumented -fun:g_string_prepend_len=uninstrumented -fun:g_string_prepend_unichar=uninstrumented -fun:g_string_printf=uninstrumented -fun:g_string_set_size=uninstrumented -fun:g_string_sized_new=uninstrumented -fun:g_string_truncate=uninstrumented -fun:g_string_up=uninstrumented -fun:g_string_vprintf=uninstrumented -fun:g_strip_context=uninstrumented -fun:g_strjoin=uninstrumented -fun:g_strjoinv=uninstrumented -fun:g_strlcat=uninstrumented -fun:g_strlcpy=uninstrumented -fun:g_strncasecmp=uninstrumented -fun:g_strndup=uninstrumented -fun:g_strnfill=uninstrumented -fun:g_strreverse=uninstrumented -fun:g_strrstr=uninstrumented -fun:g_strrstr_len=uninstrumented -fun:g_strsignal=uninstrumented -fun:g_strsplit=uninstrumented -fun:g_strsplit_set=uninstrumented -fun:g_strstr_len=uninstrumented -fun:g_strtod=uninstrumented -fun:g_strup=uninstrumented -fun:g_strv_contains=uninstrumented -fun:g_strv_equal=uninstrumented -fun:g_strv_length=uninstrumented -fun:g_system_thread_exit=uninstrumented -fun:g_system_thread_free=uninstrumented -fun:g_system_thread_get_scheduler_settings=uninstrumented -fun:g_system_thread_new=uninstrumented -fun:g_system_thread_set_name=uninstrumented -fun:g_system_thread_wait=uninstrumented -fun:g_test_add_data_func=uninstrumented -fun:g_test_add_data_func_full=uninstrumented -fun:g_test_add_func=uninstrumented -fun:g_test_add_vtable=uninstrumented -fun:g_test_assert_expected_messages_internal=uninstrumented -fun:g_test_bug=uninstrumented -fun:g_test_bug_base=uninstrumented -fun:g_test_build_filename=uninstrumented -fun:g_test_create_case=uninstrumented -fun:g_test_create_suite=uninstrumented -fun:g_test_expect_message=uninstrumented -fun:g_test_fail=uninstrumented -fun:g_test_failed=uninstrumented -fun:g_test_get_dir=uninstrumented -fun:g_test_get_filename=uninstrumented -fun:g_test_get_root=uninstrumented -fun:g_test_incomplete=uninstrumented -fun:g_test_init=uninstrumented -fun:g_test_log_buffer_free=uninstrumented -fun:g_test_log_buffer_new=uninstrumented -fun:g_test_log_buffer_pop=uninstrumented -fun:g_test_log_buffer_push=uninstrumented -fun:g_test_log_msg_free=uninstrumented -fun:g_test_log_set_fatal_handler=uninstrumented -fun:g_test_log_type_name=uninstrumented -fun:g_test_maximized_result=uninstrumented -fun:g_test_message=uninstrumented -fun:g_test_minimized_result=uninstrumented -fun:g_test_queue_destroy=uninstrumented -fun:g_test_queue_free=uninstrumented -fun:g_test_rand_double=uninstrumented -fun:g_test_rand_double_range=uninstrumented -fun:g_test_rand_int=uninstrumented -fun:g_test_rand_int_range=uninstrumented -fun:g_test_run=uninstrumented -fun:g_test_run_suite=uninstrumented -fun:g_test_set_nonfatal_assertions=uninstrumented -fun:g_test_skip=uninstrumented -fun:g_test_subprocess=uninstrumented -fun:g_test_suite_add=uninstrumented -fun:g_test_suite_add_suite=uninstrumented -fun:g_test_summary=uninstrumented -fun:g_test_timer_elapsed=uninstrumented -fun:g_test_timer_last=uninstrumented -fun:g_test_timer_start=uninstrumented -fun:g_test_trap_assertions=uninstrumented -fun:g_test_trap_fork=uninstrumented -fun:g_test_trap_has_passed=uninstrumented -fun:g_test_trap_reached_timeout=uninstrumented -fun:g_test_trap_subprocess=uninstrumented -fun:g_thread_create=uninstrumented -fun:g_thread_create_full=uninstrumented -fun:g_thread_error_quark=uninstrumented -fun:g_thread_exit=uninstrumented -fun:g_thread_foreach=uninstrumented -fun:g_thread_get_initialized=uninstrumented -fun:g_thread_get_scheduler_settings=uninstrumented -fun:g_thread_init_glib=uninstrumented -fun:g_thread_join=uninstrumented -fun:g_thread_n_created=uninstrumented -fun:g_thread_new=uninstrumented -fun:g_thread_new_internal=uninstrumented -fun:g_thread_pool_free=uninstrumented -fun:g_thread_pool_get_max_idle_time=uninstrumented -fun:g_thread_pool_get_max_threads=uninstrumented -fun:g_thread_pool_get_max_unused_threads=uninstrumented -fun:g_thread_pool_get_num_threads=uninstrumented -fun:g_thread_pool_get_num_unused_threads=uninstrumented -fun:g_thread_pool_move_to_front=uninstrumented -fun:g_thread_pool_new=uninstrumented -fun:g_thread_pool_push=uninstrumented -fun:g_thread_pool_set_max_idle_time=uninstrumented -fun:g_thread_pool_set_max_threads=uninstrumented -fun:g_thread_pool_set_max_unused_threads=uninstrumented -fun:g_thread_pool_set_sort_function=uninstrumented -fun:g_thread_pool_stop_unused_threads=uninstrumented -fun:g_thread_pool_unprocessed=uninstrumented -fun:g_thread_proxy=uninstrumented -fun:g_thread_ref=uninstrumented -fun:g_thread_self=uninstrumented -fun:g_thread_set_priority=uninstrumented -fun:g_thread_try_new=uninstrumented -fun:g_thread_unref=uninstrumented -fun:g_thread_yield=uninstrumented -fun:g_time_val_add=uninstrumented -fun:g_time_val_from_iso8601=uninstrumented -fun:g_time_val_to_iso8601=uninstrumented -fun:g_time_zone_adjust_time=uninstrumented -fun:g_time_zone_find_interval=uninstrumented -fun:g_time_zone_get_abbreviation=uninstrumented -fun:g_time_zone_get_identifier=uninstrumented -fun:g_time_zone_get_offset=uninstrumented -fun:g_time_zone_is_dst=uninstrumented -fun:g_time_zone_new=uninstrumented -fun:g_time_zone_new_local=uninstrumented -fun:g_time_zone_new_offset=uninstrumented -fun:g_time_zone_new_utc=uninstrumented -fun:g_time_zone_ref=uninstrumented -fun:g_time_zone_unref=uninstrumented -fun:g_timeout_add=uninstrumented -fun:g_timeout_add_full=uninstrumented -fun:g_timeout_add_seconds=uninstrumented -fun:g_timeout_add_seconds_full=uninstrumented -fun:g_timeout_source_new=uninstrumented -fun:g_timeout_source_new_seconds=uninstrumented -fun:g_timer_continue=uninstrumented -fun:g_timer_destroy=uninstrumented -fun:g_timer_elapsed=uninstrumented -fun:g_timer_is_active=uninstrumented -fun:g_timer_new=uninstrumented -fun:g_timer_reset=uninstrumented -fun:g_timer_start=uninstrumented -fun:g_timer_stop=uninstrumented -fun:g_trash_stack_height=uninstrumented -fun:g_trash_stack_peek=uninstrumented -fun:g_trash_stack_pop=uninstrumented -fun:g_trash_stack_push=uninstrumented -fun:g_tree_destroy=uninstrumented -fun:g_tree_foreach=uninstrumented -fun:g_tree_height=uninstrumented -fun:g_tree_insert=uninstrumented -fun:g_tree_lookup=uninstrumented -fun:g_tree_lookup_extended=uninstrumented -fun:g_tree_new=uninstrumented -fun:g_tree_new_full=uninstrumented -fun:g_tree_new_with_data=uninstrumented -fun:g_tree_nnodes=uninstrumented -fun:g_tree_ref=uninstrumented -fun:g_tree_remove=uninstrumented -fun:g_tree_replace=uninstrumented -fun:g_tree_search=uninstrumented -fun:g_tree_steal=uninstrumented -fun:g_tree_traverse=uninstrumented -fun:g_tree_unref=uninstrumented -fun:g_try_malloc=uninstrumented -fun:g_try_malloc0=uninstrumented -fun:g_try_malloc0_n=uninstrumented -fun:g_try_malloc_n=uninstrumented -fun:g_try_realloc=uninstrumented -fun:g_try_realloc_n=uninstrumented -fun:g_tuples_destroy=uninstrumented -fun:g_tuples_index=uninstrumented -fun:g_ucs4_to_utf16=uninstrumented -fun:g_ucs4_to_utf8=uninstrumented -fun:g_unichar_break_type=uninstrumented -fun:g_unichar_combining_class=uninstrumented -fun:g_unichar_compose=uninstrumented -fun:g_unichar_decompose=uninstrumented -fun:g_unichar_digit_value=uninstrumented -fun:g_unichar_fully_decompose=uninstrumented -fun:g_unichar_get_mirror_char=uninstrumented -fun:g_unichar_get_script=uninstrumented -fun:g_unichar_isalnum=uninstrumented -fun:g_unichar_isalpha=uninstrumented -fun:g_unichar_iscntrl=uninstrumented -fun:g_unichar_isdefined=uninstrumented -fun:g_unichar_isdigit=uninstrumented -fun:g_unichar_isgraph=uninstrumented -fun:g_unichar_islower=uninstrumented -fun:g_unichar_ismark=uninstrumented -fun:g_unichar_isprint=uninstrumented -fun:g_unichar_ispunct=uninstrumented -fun:g_unichar_isspace=uninstrumented -fun:g_unichar_istitle=uninstrumented -fun:g_unichar_isupper=uninstrumented -fun:g_unichar_iswide=uninstrumented -fun:g_unichar_iswide_cjk=uninstrumented -fun:g_unichar_isxdigit=uninstrumented -fun:g_unichar_iszerowidth=uninstrumented -fun:g_unichar_to_utf8=uninstrumented -fun:g_unichar_tolower=uninstrumented -fun:g_unichar_totitle=uninstrumented -fun:g_unichar_toupper=uninstrumented -fun:g_unichar_type=uninstrumented -fun:g_unichar_validate=uninstrumented -fun:g_unichar_xdigit_value=uninstrumented -fun:g_unicode_canonical_decomposition=uninstrumented -fun:g_unicode_canonical_ordering=uninstrumented -fun:g_unicode_script_from_iso15924=uninstrumented -fun:g_unicode_script_to_iso15924=uninstrumented -fun:g_unix_error_quark=uninstrumented -fun:g_unix_fd_add=uninstrumented -fun:g_unix_fd_add_full=uninstrumented -fun:g_unix_fd_source_new=uninstrumented -fun:g_unix_get_passwd_entry=uninstrumented -fun:g_unix_open_pipe=uninstrumented -fun:g_unix_set_fd_nonblocking=uninstrumented -fun:g_unix_signal_add=uninstrumented -fun:g_unix_signal_add_full=uninstrumented -fun:g_unix_signal_source_new=uninstrumented -fun:g_unlink=uninstrumented -fun:g_unsetenv=uninstrumented -fun:g_uri_escape_string=uninstrumented -fun:g_uri_list_extract_uris=uninstrumented -fun:g_uri_parse_scheme=uninstrumented -fun:g_uri_unescape_segment=uninstrumented -fun:g_uri_unescape_string=uninstrumented -fun:g_usleep=uninstrumented -fun:g_utf16_to_ucs4=uninstrumented -fun:g_utf16_to_utf8=uninstrumented -fun:g_utf8_casefold=uninstrumented -fun:g_utf8_collate=uninstrumented -fun:g_utf8_collate_key=uninstrumented -fun:g_utf8_collate_key_for_filename=uninstrumented -fun:g_utf8_find_next_char=uninstrumented -fun:g_utf8_find_prev_char=uninstrumented -fun:g_utf8_get_char=uninstrumented -fun:g_utf8_get_char_validated=uninstrumented -fun:g_utf8_make_valid=uninstrumented -fun:g_utf8_normalize=uninstrumented -fun:g_utf8_offset_to_pointer=uninstrumented -fun:g_utf8_pointer_to_offset=uninstrumented -fun:g_utf8_prev_char=uninstrumented -fun:g_utf8_strchr=uninstrumented -fun:g_utf8_strdown=uninstrumented -fun:g_utf8_strlen=uninstrumented -fun:g_utf8_strncpy=uninstrumented -fun:g_utf8_strrchr=uninstrumented -fun:g_utf8_strreverse=uninstrumented -fun:g_utf8_strup=uninstrumented -fun:g_utf8_substring=uninstrumented -fun:g_utf8_to_ucs4=uninstrumented -fun:g_utf8_to_ucs4_fast=uninstrumented -fun:g_utf8_to_utf16=uninstrumented -fun:g_utf8_validate=uninstrumented -fun:g_utf8_validate_len=uninstrumented -fun:g_utime=uninstrumented -fun:g_uuid_string_is_valid=uninstrumented -fun:g_uuid_string_random=uninstrumented -fun:g_variant_builder_add=uninstrumented -fun:g_variant_builder_add_parsed=uninstrumented -fun:g_variant_builder_add_value=uninstrumented -fun:g_variant_builder_clear=uninstrumented -fun:g_variant_builder_close=uninstrumented -fun:g_variant_builder_end=uninstrumented -fun:g_variant_builder_init=uninstrumented -fun:g_variant_builder_new=uninstrumented -fun:g_variant_builder_open=uninstrumented -fun:g_variant_builder_ref=uninstrumented -fun:g_variant_builder_unref=uninstrumented -fun:g_variant_byteswap=uninstrumented -fun:g_variant_check_format_string=uninstrumented -fun:g_variant_classify=uninstrumented -fun:g_variant_compare=uninstrumented -fun:g_variant_dict_clear=uninstrumented -fun:g_variant_dict_contains=uninstrumented -fun:g_variant_dict_end=uninstrumented -fun:g_variant_dict_init=uninstrumented -fun:g_variant_dict_insert=uninstrumented -fun:g_variant_dict_insert_value=uninstrumented -fun:g_variant_dict_lookup=uninstrumented -fun:g_variant_dict_lookup_value=uninstrumented -fun:g_variant_dict_new=uninstrumented -fun:g_variant_dict_ref=uninstrumented -fun:g_variant_dict_remove=uninstrumented -fun:g_variant_dict_unref=uninstrumented -fun:g_variant_dup_bytestring=uninstrumented -fun:g_variant_dup_bytestring_array=uninstrumented -fun:g_variant_dup_objv=uninstrumented -fun:g_variant_dup_string=uninstrumented -fun:g_variant_dup_strv=uninstrumented -fun:g_variant_equal=uninstrumented -fun:g_variant_format_string_scan=uninstrumented -fun:g_variant_format_string_scan_type=uninstrumented -fun:g_variant_get=uninstrumented -fun:g_variant_get_boolean=uninstrumented -fun:g_variant_get_byte=uninstrumented -fun:g_variant_get_bytestring=uninstrumented -fun:g_variant_get_bytestring_array=uninstrumented -fun:g_variant_get_child=uninstrumented -fun:g_variant_get_child_value=uninstrumented -fun:g_variant_get_data=uninstrumented -fun:g_variant_get_data_as_bytes=uninstrumented -fun:g_variant_get_depth=uninstrumented -fun:g_variant_get_double=uninstrumented -fun:g_variant_get_fixed_array=uninstrumented -fun:g_variant_get_handle=uninstrumented -fun:g_variant_get_int16=uninstrumented -fun:g_variant_get_int32=uninstrumented -fun:g_variant_get_int64=uninstrumented -fun:g_variant_get_maybe=uninstrumented -fun:g_variant_get_normal_form=uninstrumented -fun:g_variant_get_objv=uninstrumented -fun:g_variant_get_size=uninstrumented -fun:g_variant_get_string=uninstrumented -fun:g_variant_get_strv=uninstrumented -fun:g_variant_get_type=uninstrumented -fun:g_variant_get_type_info=uninstrumented -fun:g_variant_get_type_string=uninstrumented -fun:g_variant_get_uint16=uninstrumented -fun:g_variant_get_uint32=uninstrumented -fun:g_variant_get_uint64=uninstrumented -fun:g_variant_get_va=uninstrumented -fun:g_variant_get_variant=uninstrumented -fun:g_variant_hash=uninstrumented -fun:g_variant_is_container=uninstrumented -fun:g_variant_is_floating=uninstrumented -fun:g_variant_is_normal_form=uninstrumented -fun:g_variant_is_object_path=uninstrumented -fun:g_variant_is_of_type=uninstrumented -fun:g_variant_is_signature=uninstrumented -fun:g_variant_is_trusted=uninstrumented -fun:g_variant_iter_copy=uninstrumented -fun:g_variant_iter_free=uninstrumented -fun:g_variant_iter_init=uninstrumented -fun:g_variant_iter_loop=uninstrumented -fun:g_variant_iter_n_children=uninstrumented -fun:g_variant_iter_new=uninstrumented -fun:g_variant_iter_next=uninstrumented -fun:g_variant_iter_next_value=uninstrumented -fun:g_variant_lookup=uninstrumented -fun:g_variant_lookup_value=uninstrumented -fun:g_variant_n_children=uninstrumented -fun:g_variant_new=uninstrumented -fun:g_variant_new_array=uninstrumented -fun:g_variant_new_boolean=uninstrumented -fun:g_variant_new_byte=uninstrumented -fun:g_variant_new_bytestring=uninstrumented -fun:g_variant_new_bytestring_array=uninstrumented -fun:g_variant_new_dict_entry=uninstrumented -fun:g_variant_new_double=uninstrumented -fun:g_variant_new_fixed_array=uninstrumented -fun:g_variant_new_from_bytes=uninstrumented -fun:g_variant_new_from_children=uninstrumented -fun:g_variant_new_from_data=uninstrumented -fun:g_variant_new_handle=uninstrumented -fun:g_variant_new_int16=uninstrumented -fun:g_variant_new_int32=uninstrumented -fun:g_variant_new_int64=uninstrumented -fun:g_variant_new_maybe=uninstrumented -fun:g_variant_new_object_path=uninstrumented -fun:g_variant_new_objv=uninstrumented -fun:g_variant_new_parsed=uninstrumented -fun:g_variant_new_parsed_va=uninstrumented -fun:g_variant_new_printf=uninstrumented -fun:g_variant_new_signature=uninstrumented -fun:g_variant_new_string=uninstrumented -fun:g_variant_new_strv=uninstrumented -fun:g_variant_new_take_string=uninstrumented -fun:g_variant_new_tuple=uninstrumented -fun:g_variant_new_uint16=uninstrumented -fun:g_variant_new_uint32=uninstrumented -fun:g_variant_new_uint64=uninstrumented -fun:g_variant_new_va=uninstrumented -fun:g_variant_new_variant=uninstrumented -fun:g_variant_parse=uninstrumented -fun:g_variant_parse_error_print_context=uninstrumented -fun:g_variant_parse_error_quark=uninstrumented -fun:g_variant_parser_get_error_quark=uninstrumented -fun:g_variant_print=uninstrumented -fun:g_variant_print_string=uninstrumented -fun:g_variant_ref=uninstrumented -fun:g_variant_ref_sink=uninstrumented -fun:g_variant_serialised_byteswap=uninstrumented -fun:g_variant_serialised_check=uninstrumented -fun:g_variant_serialised_get_child=uninstrumented -fun:g_variant_serialised_is_normal=uninstrumented -fun:g_variant_serialised_n_children=uninstrumented -fun:g_variant_serialiser_is_object_path=uninstrumented -fun:g_variant_serialiser_is_signature=uninstrumented -fun:g_variant_serialiser_is_string=uninstrumented -fun:g_variant_serialiser_needed_size=uninstrumented -fun:g_variant_serialiser_serialise=uninstrumented -fun:g_variant_store=uninstrumented -fun:g_variant_take_ref=uninstrumented -fun:g_variant_type_checked_=uninstrumented -fun:g_variant_type_copy=uninstrumented -fun:g_variant_type_dup_string=uninstrumented -fun:g_variant_type_element=uninstrumented -fun:g_variant_type_equal=uninstrumented -fun:g_variant_type_first=uninstrumented -fun:g_variant_type_free=uninstrumented -fun:g_variant_type_get_string_length=uninstrumented -fun:g_variant_type_hash=uninstrumented -fun:g_variant_type_info_assert_no_infos=uninstrumented -fun:g_variant_type_info_element=uninstrumented -fun:g_variant_type_info_get=uninstrumented -fun:g_variant_type_info_get_type_string=uninstrumented -fun:g_variant_type_info_member_info=uninstrumented -fun:g_variant_type_info_n_members=uninstrumented -fun:g_variant_type_info_query=uninstrumented -fun:g_variant_type_info_query_depth=uninstrumented -fun:g_variant_type_info_query_element=uninstrumented -fun:g_variant_type_info_ref=uninstrumented -fun:g_variant_type_info_unref=uninstrumented -fun:g_variant_type_is_array=uninstrumented -fun:g_variant_type_is_basic=uninstrumented -fun:g_variant_type_is_container=uninstrumented -fun:g_variant_type_is_definite=uninstrumented -fun:g_variant_type_is_dict_entry=uninstrumented -fun:g_variant_type_is_maybe=uninstrumented -fun:g_variant_type_is_subtype_of=uninstrumented -fun:g_variant_type_is_tuple=uninstrumented -fun:g_variant_type_is_variant=uninstrumented -fun:g_variant_type_key=uninstrumented -fun:g_variant_type_n_items=uninstrumented -fun:g_variant_type_new=uninstrumented -fun:g_variant_type_new_array=uninstrumented -fun:g_variant_type_new_dict_entry=uninstrumented -fun:g_variant_type_new_maybe=uninstrumented -fun:g_variant_type_new_tuple=uninstrumented -fun:g_variant_type_next=uninstrumented -fun:g_variant_type_peek_string=uninstrumented -fun:g_variant_type_string_get_depth_=uninstrumented -fun:g_variant_type_string_is_valid=uninstrumented -fun:g_variant_type_string_scan=uninstrumented -fun:g_variant_type_value=uninstrumented -fun:g_variant_unref=uninstrumented -fun:g_vasprintf=uninstrumented -fun:g_vfprintf=uninstrumented -fun:g_vprintf=uninstrumented -fun:g_vsnprintf=uninstrumented -fun:g_vsprintf=uninstrumented -fun:g_wakeup_acknowledge=uninstrumented -fun:g_wakeup_free=uninstrumented -fun:g_wakeup_get_pollfd=uninstrumented -fun:g_wakeup_new=uninstrumented -fun:g_wakeup_signal=uninstrumented -fun:g_warn_message=uninstrumented -fun:glib__private__=uninstrumented -fun:glib_check_version=uninstrumented -fun:glib_gettext=uninstrumented -fun:glib_init=uninstrumented -fun:glib_pgettext=uninstrumented diff --git a/fuzzers/symsan/libfuzz-harness-proxy.c b/fuzzers/symsan/libfuzz-harness-proxy.c deleted file mode 100644 index 86097062f..000000000 --- a/fuzzers/symsan/libfuzz-harness-proxy.c +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2021 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. -#include -#include -#include -#include -#include - -extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); - -int main(int argc, char* argv[]) { - // open file - FILE *f = fopen(argv[1], "rb"); - - // get file size - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - - // read file contents - fseek(f, 0, SEEK_SET); - char *string = (char*)malloc(fsize + 1); - fread(string, 1, fsize, f); - fclose(f); - - // Now call into the harness - int retval = LLVMFuzzerTestOneInput((const uint8_t *)string, fsize); - - free(string); - return retval; -} diff --git a/fuzzers/symsan/pcre.abilist b/fuzzers/symsan/pcre.abilist deleted file mode 100644 index a73b8fb99..000000000 --- a/fuzzers/symsan/pcre.abilist +++ /dev/null @@ -1,38 +0,0 @@ -fun:_pcre_find_bracket=uninstrumented -fun:_pcre_is_newline=uninstrumented -fun:_pcre_jit_compile=uninstrumented -fun:_pcre_jit_exec=uninstrumented -fun:_pcre_jit_free=uninstrumented -fun:_pcre_jit_get_size=uninstrumented -fun:_pcre_jit_get_target=uninstrumented -fun:_pcre_ord2utf=uninstrumented -fun:_pcre_valid_utf=uninstrumented -fun:_pcre_was_newline=uninstrumented -fun:_pcre_xclass=uninstrumented -fun:pcre_assign_jit_stack=uninstrumented -fun:pcre_compile=uninstrumented -fun:pcre_compile2=uninstrumented -fun:pcre_config=uninstrumented -fun:pcre_copy_named_substring=uninstrumented -fun:pcre_copy_substring=uninstrumented -fun:pcre_dfa_exec=uninstrumented -fun:pcre_exec=uninstrumented -fun:pcre_free_study=uninstrumented -fun:pcre_free_substring=uninstrumented -fun:pcre_free_substring_list=uninstrumented -fun:pcre_fullinfo=uninstrumented -fun:pcre_get_named_substring=uninstrumented -fun:pcre_get_stringnumber=uninstrumented -fun:pcre_get_stringtable_entries=uninstrumented -fun:pcre_get_substring=uninstrumented -fun:pcre_get_substring_list=uninstrumented -fun:pcre_info=uninstrumented -fun:pcre_jit_exec=uninstrumented -fun:pcre_jit_free_unused_memory=uninstrumented -fun:pcre_jit_stack_alloc=uninstrumented -fun:pcre_jit_stack_free=uninstrumented -fun:pcre_maketables=uninstrumented -fun:pcre_pattern_to_host_byte_order=uninstrumented -fun:pcre_refcount=uninstrumented -fun:pcre_study=uninstrumented -fun:pcre_version=uninstrumented diff --git a/fuzzers/symsan/runner.Dockerfile b/fuzzers/symsan/runner.Dockerfile deleted file mode 100644 index 76159d030..000000000 --- a/fuzzers/symsan/runner.Dockerfile +++ /dev/null @@ -1,43 +0,0 @@ -# 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-runner -FROM gcr.io/fuzzbench/base-image - -RUN apt-get update -RUN apt-get -y install git cmake wget build-essential autoconf libtool python3-pip python3-setuptools apt-transport-https libboost-all-dev lsb-release software-properties-common -RUN apt-get install -y wget libc++abi-dev libc++-dev libunwind-dev - - -RUN wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh && ./llvm.sh 12 -ENV PATH="/out/bin:${PATH}" -ENV PATH="/root/.cargo/bin:${PATH}" -RUN ln -s /out/lib/libz3.so /usr/local/lib/libz3.so -RUN ln -s /out/lib/libtcmalloc.so /usr/local/lib/libtcmalloc.so -RUN ldconfig - - - -ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/out" -ENV AFL_MAP_SIZE=900000 -ENV AFL_QUIET=1 -ENV PATH="$PATH:/out" -ENV AFL_SKIP_CPUFREQ=1 -#ENV AFL_NO_UI=1 -ENV AFL_NO_AFFINITY=1 -ENV AFL_SKIP_CRASHES=1 -#ENV AFL_TESTCACHE_SIZE=2 -ENV AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 -COPY fuz.sh /out/ -COPY fres.sh /out/ diff --git a/fuzzers/symsan/xml.abilist b/fuzzers/symsan/xml.abilist deleted file mode 100644 index eee32b85f..000000000 --- a/fuzzers/symsan/xml.abilist +++ /dev/null @@ -1,1692 +0,0 @@ -fun:UTF8ToHtml=uninstrumented -fun:UTF8Toisolat1=uninstrumented -fun:__docbDefaultSAXHandler=uninstrumented -fun:__htmlDefaultSAXHandler=uninstrumented -fun:__htmlParseContent=uninstrumented -fun:__libxml2_xzclose=uninstrumented -fun:__libxml2_xzcompressed=uninstrumented -fun:__libxml2_xzdopen=uninstrumented -fun:__libxml2_xzopen=uninstrumented -fun:__libxml2_xzread=uninstrumented -fun:__oldXMLWDcompatibility=uninstrumented -fun:__xmlBufferAllocScheme=uninstrumented -fun:__xmlDefaultBufferSize=uninstrumented -fun:__xmlDefaultSAXHandler=uninstrumented -fun:__xmlDefaultSAXLocator=uninstrumented -fun:__xmlDeregisterNodeDefaultValue=uninstrumented -fun:__xmlDoValidityCheckingDefaultValue=uninstrumented -fun:__xmlErrEncoding=uninstrumented -fun:__xmlGenericError=uninstrumented -fun:__xmlGenericErrorContext=uninstrumented -fun:__xmlGetWarningsDefaultValue=uninstrumented -fun:__xmlGlobalInitMutexDestroy=uninstrumented -fun:__xmlGlobalInitMutexLock=uninstrumented -fun:__xmlGlobalInitMutexUnlock=uninstrumented -fun:__xmlIOErr=uninstrumented -fun:__xmlIndentTreeOutput=uninstrumented -fun:__xmlInitializeDict=uninstrumented -fun:__xmlKeepBlanksDefaultValue=uninstrumented -fun:__xmlLastError=uninstrumented -fun:__xmlLineNumbersDefaultValue=uninstrumented -fun:__xmlLoadExtDtdDefaultValue=uninstrumented -fun:__xmlLoaderErr=uninstrumented -fun:__xmlOutputBufferCreateFilename=uninstrumented -fun:__xmlOutputBufferCreateFilenameValue=uninstrumented -fun:__xmlParserDebugEntities=uninstrumented -fun:__xmlParserInputBufferCreateFilename=uninstrumented -fun:__xmlParserInputBufferCreateFilenameValue=uninstrumented -fun:__xmlParserVersion=uninstrumented -fun:__xmlPedanticParserDefaultValue=uninstrumented -fun:__xmlRaiseError=uninstrumented -fun:__xmlRandom=uninstrumented -fun:__xmlRegisterNodeDefaultValue=uninstrumented -fun:__xmlSaveNoEmptyTags=uninstrumented -fun:__xmlSimpleError=uninstrumented -fun:__xmlStructuredError=uninstrumented -fun:__xmlStructuredErrorContext=uninstrumented -fun:__xmlSubstituteEntitiesDefaultValue=uninstrumented -fun:__xmlTreeIndentString=uninstrumented -fun:attribute=uninstrumented -fun:attributeDecl=uninstrumented -fun:cdataBlock=uninstrumented -fun:characters=uninstrumented -fun:checkNamespace=uninstrumented -fun:comment=uninstrumented -fun:docbDefaultSAXHandlerInit=uninstrumented -fun:elementDecl=uninstrumented -fun:endDocument=uninstrumented -fun:endElement=uninstrumented -fun:entityDecl=uninstrumented -fun:externalSubset=uninstrumented -fun:getColumnNumber=uninstrumented -fun:getEntity=uninstrumented -fun:getLineNumber=uninstrumented -fun:getNamespace=uninstrumented -fun:getParameterEntity=uninstrumented -fun:getPublicId=uninstrumented -fun:getSystemId=uninstrumented -fun:globalNamespace=uninstrumented -fun:hasExternalSubset=uninstrumented -fun:hasInternalSubset=uninstrumented -fun:htmlAttrAllowed=uninstrumented -fun:htmlAutoCloseTag=uninstrumented -fun:htmlCreateFileParserCtxt=uninstrumented -fun:htmlCreateMemoryParserCtxt=uninstrumented -fun:htmlCreatePushParserCtxt=uninstrumented -fun:htmlCtxtReadDoc=uninstrumented -fun:htmlCtxtReadFd=uninstrumented -fun:htmlCtxtReadFile=uninstrumented -fun:htmlCtxtReadIO=uninstrumented -fun:htmlCtxtReadMemory=uninstrumented -fun:htmlCtxtReset=uninstrumented -fun:htmlCtxtUseOptions=uninstrumented -fun:htmlDecodeEntities=uninstrumented -fun:htmlDefaultSAXHandlerInit=uninstrumented -fun:htmlDocContentDumpFormatOutput=uninstrumented -fun:htmlDocContentDumpOutput=uninstrumented -fun:htmlDocDump=uninstrumented -fun:htmlDocDumpMemory=uninstrumented -fun:htmlDocDumpMemoryFormat=uninstrumented -fun:htmlElementAllowedHere=uninstrumented -fun:htmlElementStatusHere=uninstrumented -fun:htmlEncodeEntities=uninstrumented -fun:htmlEntityLookup=uninstrumented -fun:htmlEntityValueLookup=uninstrumented -fun:htmlFreeParserCtxt=uninstrumented -fun:htmlGetMetaEncoding=uninstrumented -fun:htmlHandleOmittedElem=uninstrumented -fun:htmlInitAutoClose=uninstrumented -fun:htmlIsAutoClosed=uninstrumented -fun:htmlIsBooleanAttr=uninstrumented -fun:htmlIsScriptAttribute=uninstrumented -fun:htmlNewDoc=uninstrumented -fun:htmlNewDocNoDtD=uninstrumented -fun:htmlNewParserCtxt=uninstrumented -fun:htmlNodeDump=uninstrumented -fun:htmlNodeDumpFile=uninstrumented -fun:htmlNodeDumpFileFormat=uninstrumented -fun:htmlNodeDumpFormatOutput=uninstrumented -fun:htmlNodeDumpOutput=uninstrumented -fun:htmlNodeStatus=uninstrumented -fun:htmlParseCharRef=uninstrumented -fun:htmlParseChunk=uninstrumented -fun:htmlParseDoc=uninstrumented -fun:htmlParseDocument=uninstrumented -fun:htmlParseElement=uninstrumented -fun:htmlParseEntityRef=uninstrumented -fun:htmlParseFile=uninstrumented -fun:htmlReadDoc=uninstrumented -fun:htmlReadFd=uninstrumented -fun:htmlReadFile=uninstrumented -fun:htmlReadIO=uninstrumented -fun:htmlReadMemory=uninstrumented -fun:htmlSAXParseDoc=uninstrumented -fun:htmlSAXParseFile=uninstrumented -fun:htmlSaveFile=uninstrumented -fun:htmlSaveFileEnc=uninstrumented -fun:htmlSaveFileFormat=uninstrumented -fun:htmlSetMetaEncoding=uninstrumented -fun:htmlTagLookup=uninstrumented -fun:ignorableWhitespace=uninstrumented -fun:initGenericErrorDefaultFunc=uninstrumented -fun:initdocbDefaultSAXHandler=uninstrumented -fun:inithtmlDefaultSAXHandler=uninstrumented -fun:initxmlDefaultSAXHandler=uninstrumented -fun:inputPop=uninstrumented -fun:inputPush=uninstrumented -fun:internalSubset=uninstrumented -fun:isStandalone=uninstrumented -fun:isolat1ToUTF8=uninstrumented -fun:libxml_domnode_binary_insertion_sort=uninstrumented -fun:libxml_domnode_tim_sort=uninstrumented -fun:namePop=uninstrumented -fun:namePush=uninstrumented -fun:namespaceDecl=uninstrumented -fun:nodePop=uninstrumented -fun:nodePush=uninstrumented -fun:notationDecl=uninstrumented -fun:processingInstruction=uninstrumented -fun:reference=uninstrumented -fun:resolveEntity=uninstrumented -fun:setDocumentLocator=uninstrumented -fun:setNamespace=uninstrumented -fun:startDocument=uninstrumented -fun:startElement=uninstrumented -fun:unparsedEntityDecl=uninstrumented -fun:valuePop=uninstrumented -fun:valuePush=uninstrumented -fun:xlinkGetDefaultDetect=uninstrumented -fun:xlinkGetDefaultHandler=uninstrumented -fun:xlinkIsLink=uninstrumented -fun:xlinkSetDefaultDetect=uninstrumented -fun:xlinkSetDefaultHandler=uninstrumented -fun:xmlACatalogAdd=uninstrumented -fun:xmlACatalogDump=uninstrumented -fun:xmlACatalogRemove=uninstrumented -fun:xmlACatalogResolve=uninstrumented -fun:xmlACatalogResolvePublic=uninstrumented -fun:xmlACatalogResolveSystem=uninstrumented -fun:xmlACatalogResolveURI=uninstrumented -fun:xmlAddAttributeDecl=uninstrumented -fun:xmlAddChild=uninstrumented -fun:xmlAddChildList=uninstrumented -fun:xmlAddDocEntity=uninstrumented -fun:xmlAddDtdEntity=uninstrumented -fun:xmlAddElementDecl=uninstrumented -fun:xmlAddEncodingAlias=uninstrumented -fun:xmlAddID=uninstrumented -fun:xmlAddNextSibling=uninstrumented -fun:xmlAddNotationDecl=uninstrumented -fun:xmlAddPrevSibling=uninstrumented -fun:xmlAddRef=uninstrumented -fun:xmlAddSibling=uninstrumented -fun:xmlAllocOutputBuffer=uninstrumented -fun:xmlAllocOutputBufferInternal=uninstrumented -fun:xmlAllocParserInputBuffer=uninstrumented -fun:xmlAttrSerializeTxtContent=uninstrumented -fun:xmlAutomataCompile=uninstrumented -fun:xmlAutomataGetInitState=uninstrumented -fun:xmlAutomataIsDeterminist=uninstrumented -fun:xmlAutomataNewAllTrans=uninstrumented -fun:xmlAutomataNewCountTrans=uninstrumented -fun:xmlAutomataNewCountTrans2=uninstrumented -fun:xmlAutomataNewCountedTrans=uninstrumented -fun:xmlAutomataNewCounter=uninstrumented -fun:xmlAutomataNewCounterTrans=uninstrumented -fun:xmlAutomataNewEpsilon=uninstrumented -fun:xmlAutomataNewNegTrans=uninstrumented -fun:xmlAutomataNewOnceTrans=uninstrumented -fun:xmlAutomataNewOnceTrans2=uninstrumented -fun:xmlAutomataNewState=uninstrumented -fun:xmlAutomataNewTransition=uninstrumented -fun:xmlAutomataNewTransition2=uninstrumented -fun:xmlAutomataSetFinalState=uninstrumented -fun:xmlAutomataSetFlags=uninstrumented -fun:xmlBoolToText=uninstrumented -fun:xmlBufAdd=uninstrumented -fun:xmlBufAddHead=uninstrumented -fun:xmlBufAddLen=uninstrumented -fun:xmlBufAttrSerializeTxtContent=uninstrumented -fun:xmlBufAvail=uninstrumented -fun:xmlBufBackToBuffer=uninstrumented -fun:xmlBufCCat=uninstrumented -fun:xmlBufCat=uninstrumented -fun:xmlBufContent=uninstrumented -fun:xmlBufCreate=uninstrumented -fun:xmlBufCreateSize=uninstrumented -fun:xmlBufCreateStatic=uninstrumented -fun:xmlBufDetach=uninstrumented -fun:xmlBufDump=uninstrumented -fun:xmlBufDumpAttributeDecl=uninstrumented -fun:xmlBufDumpElementDecl=uninstrumented -fun:xmlBufDumpEntityDecl=uninstrumented -fun:xmlBufDumpNotationTable=uninstrumented -fun:xmlBufEmpty=uninstrumented -fun:xmlBufEnd=uninstrumented -fun:xmlBufErase=uninstrumented -fun:xmlBufFree=uninstrumented -fun:xmlBufFromBuffer=uninstrumented -fun:xmlBufGetAllocationScheme=uninstrumented -fun:xmlBufGetInputBase=uninstrumented -fun:xmlBufGetNodeContent=uninstrumented -fun:xmlBufGrow=uninstrumented -fun:xmlBufInflate=uninstrumented -fun:xmlBufIsEmpty=uninstrumented -fun:xmlBufLength=uninstrumented -fun:xmlBufMergeBuffer=uninstrumented -fun:xmlBufNodeDump=uninstrumented -fun:xmlBufResetInput=uninstrumented -fun:xmlBufResize=uninstrumented -fun:xmlBufSetAllocationScheme=uninstrumented -fun:xmlBufSetInputBaseCur=uninstrumented -fun:xmlBufShrink=uninstrumented -fun:xmlBufUse=uninstrumented -fun:xmlBufWriteCHAR=uninstrumented -fun:xmlBufWriteChar=uninstrumented -fun:xmlBufWriteQuotedString=uninstrumented -fun:xmlBufferAdd=uninstrumented -fun:xmlBufferAddHead=uninstrumented -fun:xmlBufferCCat=uninstrumented -fun:xmlBufferCat=uninstrumented -fun:xmlBufferContent=uninstrumented -fun:xmlBufferCreate=uninstrumented -fun:xmlBufferCreateSize=uninstrumented -fun:xmlBufferCreateStatic=uninstrumented -fun:xmlBufferDetach=uninstrumented -fun:xmlBufferDump=uninstrumented -fun:xmlBufferEmpty=uninstrumented -fun:xmlBufferFree=uninstrumented -fun:xmlBufferGrow=uninstrumented -fun:xmlBufferLength=uninstrumented -fun:xmlBufferResize=uninstrumented -fun:xmlBufferSetAllocationScheme=uninstrumented -fun:xmlBufferShrink=uninstrumented -fun:xmlBufferWriteCHAR=uninstrumented -fun:xmlBufferWriteChar=uninstrumented -fun:xmlBufferWriteQuotedString=uninstrumented -fun:xmlBuildQName=uninstrumented -fun:xmlBuildRelativeURI=uninstrumented -fun:xmlBuildURI=uninstrumented -fun:xmlByteConsumed=uninstrumented -fun:xmlC14NDocDumpMemory=uninstrumented -fun:xmlC14NDocSave=uninstrumented -fun:xmlC14NDocSaveTo=uninstrumented -fun:xmlC14NExecute=uninstrumented -fun:xmlCanonicPath=uninstrumented -fun:xmlCatalogAdd=uninstrumented -fun:xmlCatalogAddLocal=uninstrumented -fun:xmlCatalogCleanup=uninstrumented -fun:xmlCatalogConvert=uninstrumented -fun:xmlCatalogDump=uninstrumented -fun:xmlCatalogFreeLocal=uninstrumented -fun:xmlCatalogGetDefaults=uninstrumented -fun:xmlCatalogGetPublic=uninstrumented -fun:xmlCatalogGetSystem=uninstrumented -fun:xmlCatalogIsEmpty=uninstrumented -fun:xmlCatalogLocalResolve=uninstrumented -fun:xmlCatalogLocalResolveURI=uninstrumented -fun:xmlCatalogRemove=uninstrumented -fun:xmlCatalogResolve=uninstrumented -fun:xmlCatalogResolvePublic=uninstrumented -fun:xmlCatalogResolveSystem=uninstrumented -fun:xmlCatalogResolveURI=uninstrumented -fun:xmlCatalogSetDebug=uninstrumented -fun:xmlCatalogSetDefaultPrefer=uninstrumented -fun:xmlCatalogSetDefaults=uninstrumented -fun:xmlCharEncCloseFunc=uninstrumented -fun:xmlCharEncFirstLine=uninstrumented -fun:xmlCharEncFirstLineInput=uninstrumented -fun:xmlCharEncFirstLineInt=uninstrumented -fun:xmlCharEncInFunc=uninstrumented -fun:xmlCharEncInput=uninstrumented -fun:xmlCharEncOutFunc=uninstrumented -fun:xmlCharEncOutput=uninstrumented -fun:xmlCharInRange=uninstrumented -fun:xmlCharStrdup=uninstrumented -fun:xmlCharStrndup=uninstrumented -fun:xmlCheckFilename=uninstrumented -fun:xmlCheckHTTPInput=uninstrumented -fun:xmlCheckLanguageID=uninstrumented -fun:xmlCheckUTF8=uninstrumented -fun:xmlCheckVersion=uninstrumented -fun:xmlChildElementCount=uninstrumented -fun:xmlCleanupCharEncodingHandlers=uninstrumented -fun:xmlCleanupEncodingAliases=uninstrumented -fun:xmlCleanupGlobals=uninstrumented -fun:xmlCleanupInputCallbacks=uninstrumented -fun:xmlCleanupMemory=uninstrumented -fun:xmlCleanupOutputCallbacks=uninstrumented -fun:xmlCleanupParser=uninstrumented -fun:xmlCleanupPredefinedEntities=uninstrumented -fun:xmlCleanupThreads=uninstrumented -fun:xmlClearNodeInfoSeq=uninstrumented -fun:xmlClearParserCtxt=uninstrumented -fun:xmlConvertSGMLCatalog=uninstrumented -fun:xmlCopyAttributeTable=uninstrumented -fun:xmlCopyChar=uninstrumented -fun:xmlCopyCharMultiByte=uninstrumented -fun:xmlCopyDoc=uninstrumented -fun:xmlCopyDocElementContent=uninstrumented -fun:xmlCopyDtd=uninstrumented -fun:xmlCopyElementContent=uninstrumented -fun:xmlCopyElementTable=uninstrumented -fun:xmlCopyEntitiesTable=uninstrumented -fun:xmlCopyEnumeration=uninstrumented -fun:xmlCopyError=uninstrumented -fun:xmlCopyNamespace=uninstrumented -fun:xmlCopyNamespaceList=uninstrumented -fun:xmlCopyNode=uninstrumented -fun:xmlCopyNodeList=uninstrumented -fun:xmlCopyNotationTable=uninstrumented -fun:xmlCopyProp=uninstrumented -fun:xmlCopyPropList=uninstrumented -fun:xmlCreateDocParserCtxt=uninstrumented -fun:xmlCreateEntitiesTable=uninstrumented -fun:xmlCreateEntityParserCtxt=uninstrumented -fun:xmlCreateEnumeration=uninstrumented -fun:xmlCreateFileParserCtxt=uninstrumented -fun:xmlCreateIOParserCtxt=uninstrumented -fun:xmlCreateIntSubset=uninstrumented -fun:xmlCreateMemoryParserCtxt=uninstrumented -fun:xmlCreatePushParserCtxt=uninstrumented -fun:xmlCreateURI=uninstrumented -fun:xmlCreateURLParserCtxt=uninstrumented -fun:xmlCtxtGetLastError=uninstrumented -fun:xmlCtxtReadDoc=uninstrumented -fun:xmlCtxtReadFd=uninstrumented -fun:xmlCtxtReadFile=uninstrumented -fun:xmlCtxtReadIO=uninstrumented -fun:xmlCtxtReadMemory=uninstrumented -fun:xmlCtxtReset=uninstrumented -fun:xmlCtxtResetLastError=uninstrumented -fun:xmlCtxtResetPush=uninstrumented -fun:xmlCtxtUseOptions=uninstrumented -fun:xmlCurrentChar=uninstrumented -fun:xmlDOMWrapAdoptNode=uninstrumented -fun:xmlDOMWrapCloneNode=uninstrumented -fun:xmlDOMWrapFreeCtxt=uninstrumented -fun:xmlDOMWrapNewCtxt=uninstrumented -fun:xmlDOMWrapReconcileNamespaces=uninstrumented -fun:xmlDOMWrapRemoveNode=uninstrumented -fun:xmlDebugCheckDocument=uninstrumented -fun:xmlDebugDumpAttr=uninstrumented -fun:xmlDebugDumpAttrList=uninstrumented -fun:xmlDebugDumpDTD=uninstrumented -fun:xmlDebugDumpDocument=uninstrumented -fun:xmlDebugDumpDocumentHead=uninstrumented -fun:xmlDebugDumpEntities=uninstrumented -fun:xmlDebugDumpNode=uninstrumented -fun:xmlDebugDumpNodeList=uninstrumented -fun:xmlDebugDumpOneNode=uninstrumented -fun:xmlDebugDumpString=uninstrumented -fun:xmlDecodeEntities=uninstrumented -fun:xmlDefaultSAXHandlerInit=uninstrumented -fun:xmlDelEncodingAlias=uninstrumented -fun:xmlDeregisterNodeDefault=uninstrumented -fun:xmlDetectCharEncoding=uninstrumented -fun:xmlDictCleanup=uninstrumented -fun:xmlDictCreate=uninstrumented -fun:xmlDictCreateSub=uninstrumented -fun:xmlDictExists=uninstrumented -fun:xmlDictFree=uninstrumented -fun:xmlDictGetUsage=uninstrumented -fun:xmlDictLookup=uninstrumented -fun:xmlDictOwns=uninstrumented -fun:xmlDictQLookup=uninstrumented -fun:xmlDictReference=uninstrumented -fun:xmlDictSetLimit=uninstrumented -fun:xmlDictSize=uninstrumented -fun:xmlDocCopyNode=uninstrumented -fun:xmlDocCopyNodeList=uninstrumented -fun:xmlDocDump=uninstrumented -fun:xmlDocDumpFormatMemory=uninstrumented -fun:xmlDocDumpFormatMemoryEnc=uninstrumented -fun:xmlDocDumpMemory=uninstrumented -fun:xmlDocDumpMemoryEnc=uninstrumented -fun:xmlDocFormatDump=uninstrumented -fun:xmlDocGetRootElement=uninstrumented -fun:xmlDocSetRootElement=uninstrumented -fun:xmlDumpAttributeDecl=uninstrumented -fun:xmlDumpAttributeTable=uninstrumented -fun:xmlDumpElementDecl=uninstrumented -fun:xmlDumpElementTable=uninstrumented -fun:xmlDumpEntitiesTable=uninstrumented -fun:xmlDumpEntityDecl=uninstrumented -fun:xmlDumpNotationDecl=uninstrumented -fun:xmlDumpNotationTable=uninstrumented -fun:xmlElemDump=uninstrumented -fun:xmlEncodeAttributeEntities=uninstrumented -fun:xmlEncodeEntities=uninstrumented -fun:xmlEncodeEntitiesReentrant=uninstrumented -fun:xmlEncodeSpecialChars=uninstrumented -fun:xmlErrMemory=uninstrumented -fun:xmlEscapeFormatString=uninstrumented -fun:xmlFileClose=uninstrumented -fun:xmlFileMatch=uninstrumented -fun:xmlFileOpen=uninstrumented -fun:xmlFileRead=uninstrumented -fun:xmlFindCharEncodingHandler=uninstrumented -fun:xmlFirstElementChild=uninstrumented -fun:xmlFreeAttributeTable=uninstrumented -fun:xmlFreeAutomata=uninstrumented -fun:xmlFreeCatalog=uninstrumented -fun:xmlFreeDoc=uninstrumented -fun:xmlFreeDocElementContent=uninstrumented -fun:xmlFreeDtd=uninstrumented -fun:xmlFreeElementContent=uninstrumented -fun:xmlFreeElementTable=uninstrumented -fun:xmlFreeEntitiesTable=uninstrumented -fun:xmlFreeEnumeration=uninstrumented -fun:xmlFreeIDTable=uninstrumented -fun:xmlFreeInputStream=uninstrumented -fun:xmlFreeMutex=uninstrumented -fun:xmlFreeNode=uninstrumented -fun:xmlFreeNodeList=uninstrumented -fun:xmlFreeNotationTable=uninstrumented -fun:xmlFreeNs=uninstrumented -fun:xmlFreeNsList=uninstrumented -fun:xmlFreeParserCtxt=uninstrumented -fun:xmlFreeParserInputBuffer=uninstrumented -fun:xmlFreePattern=uninstrumented -fun:xmlFreePatternList=uninstrumented -fun:xmlFreeProp=uninstrumented -fun:xmlFreePropList=uninstrumented -fun:xmlFreeRMutex=uninstrumented -fun:xmlFreeRefTable=uninstrumented -fun:xmlFreeStreamCtxt=uninstrumented -fun:xmlFreeTextReader=uninstrumented -fun:xmlFreeTextWriter=uninstrumented -fun:xmlFreeURI=uninstrumented -fun:xmlFreeValidCtxt=uninstrumented -fun:xmlGcMemGet=uninstrumented -fun:xmlGcMemSetup=uninstrumented -fun:xmlGenericErrorDefaultFunc=uninstrumented -fun:xmlGetBufferAllocationScheme=uninstrumented -fun:xmlGetCharEncodingHandler=uninstrumented -fun:xmlGetCharEncodingName=uninstrumented -fun:xmlGetCompressMode=uninstrumented -fun:xmlGetDocCompressMode=uninstrumented -fun:xmlGetDocEntity=uninstrumented -fun:xmlGetDtdAttrDesc=uninstrumented -fun:xmlGetDtdElementDesc=uninstrumented -fun:xmlGetDtdEntity=uninstrumented -fun:xmlGetDtdNotationDesc=uninstrumented -fun:xmlGetDtdQAttrDesc=uninstrumented -fun:xmlGetDtdQElementDesc=uninstrumented -fun:xmlGetEncodingAlias=uninstrumented -fun:xmlGetExternalEntityLoader=uninstrumented -fun:xmlGetFeature=uninstrumented -fun:xmlGetFeaturesList=uninstrumented -fun:xmlGetGlobalState=uninstrumented -fun:xmlGetID=uninstrumented -fun:xmlGetIntSubset=uninstrumented -fun:xmlGetLastChild=uninstrumented -fun:xmlGetLastError=uninstrumented -fun:xmlGetLineNo=uninstrumented -fun:xmlGetNoNsProp=uninstrumented -fun:xmlGetNodePath=uninstrumented -fun:xmlGetNsList=uninstrumented -fun:xmlGetNsProp=uninstrumented -fun:xmlGetParameterEntity=uninstrumented -fun:xmlGetPredefinedEntity=uninstrumented -fun:xmlGetProp=uninstrumented -fun:xmlGetRefs=uninstrumented -fun:xmlGetThreadId=uninstrumented -fun:xmlGetUTF8Char=uninstrumented -fun:xmlHandleEntity=uninstrumented -fun:xmlHasFeature=uninstrumented -fun:xmlHasNsProp=uninstrumented -fun:xmlHasProp=uninstrumented -fun:xmlHashAddEntry=uninstrumented -fun:xmlHashAddEntry2=uninstrumented -fun:xmlHashAddEntry3=uninstrumented -fun:xmlHashCopy=uninstrumented -fun:xmlHashCreate=uninstrumented -fun:xmlHashCreateDict=uninstrumented -fun:xmlHashDefaultDeallocator=uninstrumented -fun:xmlHashFree=uninstrumented -fun:xmlHashLookup=uninstrumented -fun:xmlHashLookup2=uninstrumented -fun:xmlHashLookup3=uninstrumented -fun:xmlHashQLookup=uninstrumented -fun:xmlHashQLookup2=uninstrumented -fun:xmlHashQLookup3=uninstrumented -fun:xmlHashRemoveEntry=uninstrumented -fun:xmlHashRemoveEntry2=uninstrumented -fun:xmlHashRemoveEntry3=uninstrumented -fun:xmlHashScan=uninstrumented -fun:xmlHashScan3=uninstrumented -fun:xmlHashScanFull=uninstrumented -fun:xmlHashScanFull3=uninstrumented -fun:xmlHashSize=uninstrumented -fun:xmlHashUpdateEntry=uninstrumented -fun:xmlHashUpdateEntry2=uninstrumented -fun:xmlHashUpdateEntry3=uninstrumented -fun:xmlIOFTPClose=uninstrumented -fun:xmlIOFTPMatch=uninstrumented -fun:xmlIOFTPOpen=uninstrumented -fun:xmlIOFTPRead=uninstrumented -fun:xmlIOHTTPClose=uninstrumented -fun:xmlIOHTTPMatch=uninstrumented -fun:xmlIOHTTPOpen=uninstrumented -fun:xmlIOHTTPOpenW=uninstrumented -fun:xmlIOHTTPRead=uninstrumented -fun:xmlIOParseDTD=uninstrumented -fun:xmlInitCharEncodingHandlers=uninstrumented -fun:xmlInitGlobals=uninstrumented -fun:xmlInitMemory=uninstrumented -fun:xmlInitNodeInfoSeq=uninstrumented -fun:xmlInitParser=uninstrumented -fun:xmlInitParserCtxt=uninstrumented -fun:xmlInitThreads=uninstrumented -fun:xmlInitializeCatalog=uninstrumented -fun:xmlInitializeDict=uninstrumented -fun:xmlInitializeGlobalState=uninstrumented -fun:xmlInitializePredefinedEntities=uninstrumented -fun:xmlInputReadCallbackNop=uninstrumented -fun:xmlIsBaseChar=uninstrumented -fun:xmlIsBlank=uninstrumented -fun:xmlIsBlankNode=uninstrumented -fun:xmlIsChar=uninstrumented -fun:xmlIsCombining=uninstrumented -fun:xmlIsDigit=uninstrumented -fun:xmlIsExtender=uninstrumented -fun:xmlIsID=uninstrumented -fun:xmlIsIdeographic=uninstrumented -fun:xmlIsLetter=uninstrumented -fun:xmlIsMainThread=uninstrumented -fun:xmlIsMixedElement=uninstrumented -fun:xmlIsPubidChar=uninstrumented -fun:xmlIsRef=uninstrumented -fun:xmlIsXHTML=uninstrumented -fun:xmlKeepBlanksDefault=uninstrumented -fun:xmlLastElementChild=uninstrumented -fun:xmlLineNumbersDefault=uninstrumented -fun:xmlLinkGetData=uninstrumented -fun:xmlListAppend=uninstrumented -fun:xmlListClear=uninstrumented -fun:xmlListCopy=uninstrumented -fun:xmlListCreate=uninstrumented -fun:xmlListDelete=uninstrumented -fun:xmlListDup=uninstrumented -fun:xmlListEmpty=uninstrumented -fun:xmlListEnd=uninstrumented -fun:xmlListFront=uninstrumented -fun:xmlListInsert=uninstrumented -fun:xmlListMerge=uninstrumented -fun:xmlListPopBack=uninstrumented -fun:xmlListPopFront=uninstrumented -fun:xmlListPushBack=uninstrumented -fun:xmlListPushFront=uninstrumented -fun:xmlListRemoveAll=uninstrumented -fun:xmlListRemoveFirst=uninstrumented -fun:xmlListRemoveLast=uninstrumented -fun:xmlListReverse=uninstrumented -fun:xmlListReverseSearch=uninstrumented -fun:xmlListReverseWalk=uninstrumented -fun:xmlListSearch=uninstrumented -fun:xmlListSize=uninstrumented -fun:xmlListSort=uninstrumented -fun:xmlListWalk=uninstrumented -fun:xmlLoadACatalog=uninstrumented -fun:xmlLoadCatalog=uninstrumented -fun:xmlLoadCatalogs=uninstrumented -fun:xmlLoadExternalEntity=uninstrumented -fun:xmlLoadSGMLSuperCatalog=uninstrumented -fun:xmlLockLibrary=uninstrumented -fun:xmlLsCountNode=uninstrumented -fun:xmlLsOneNode=uninstrumented -fun:xmlMallocAtomicLoc=uninstrumented -fun:xmlMallocBreakpoint=uninstrumented -fun:xmlMallocLoc=uninstrumented -fun:xmlMemBlocks=uninstrumented -fun:xmlMemDisplay=uninstrumented -fun:xmlMemDisplayLast=uninstrumented -fun:xmlMemFree=uninstrumented -fun:xmlMemGet=uninstrumented -fun:xmlMemMalloc=uninstrumented -fun:xmlMemRealloc=uninstrumented -fun:xmlMemSetup=uninstrumented -fun:xmlMemShow=uninstrumented -fun:xmlMemStrdupLoc=uninstrumented -fun:xmlMemUsed=uninstrumented -fun:xmlMemoryDump=uninstrumented -fun:xmlMemoryStrdup=uninstrumented -fun:xmlModuleClose=uninstrumented -fun:xmlModuleFree=uninstrumented -fun:xmlModuleOpen=uninstrumented -fun:xmlModuleSymbol=uninstrumented -fun:xmlMutexLock=uninstrumented -fun:xmlMutexUnlock=uninstrumented -fun:xmlNamespaceParseNCName=uninstrumented -fun:xmlNamespaceParseNSDef=uninstrumented -fun:xmlNamespaceParseQName=uninstrumented -fun:xmlNanoFTPCheckResponse=uninstrumented -fun:xmlNanoFTPCleanup=uninstrumented -fun:xmlNanoFTPClose=uninstrumented -fun:xmlNanoFTPCloseConnection=uninstrumented -fun:xmlNanoFTPConnect=uninstrumented -fun:xmlNanoFTPConnectTo=uninstrumented -fun:xmlNanoFTPCwd=uninstrumented -fun:xmlNanoFTPDele=uninstrumented -fun:xmlNanoFTPFreeCtxt=uninstrumented -fun:xmlNanoFTPGet=uninstrumented -fun:xmlNanoFTPGetConnection=uninstrumented -fun:xmlNanoFTPGetResponse=uninstrumented -fun:xmlNanoFTPGetSocket=uninstrumented -fun:xmlNanoFTPInit=uninstrumented -fun:xmlNanoFTPList=uninstrumented -fun:xmlNanoFTPNewCtxt=uninstrumented -fun:xmlNanoFTPOpen=uninstrumented -fun:xmlNanoFTPProxy=uninstrumented -fun:xmlNanoFTPQuit=uninstrumented -fun:xmlNanoFTPRead=uninstrumented -fun:xmlNanoFTPScanProxy=uninstrumented -fun:xmlNanoFTPUpdateURL=uninstrumented -fun:xmlNanoHTTPAuthHeader=uninstrumented -fun:xmlNanoHTTPCleanup=uninstrumented -fun:xmlNanoHTTPClose=uninstrumented -fun:xmlNanoHTTPContentLength=uninstrumented -fun:xmlNanoHTTPEncoding=uninstrumented -fun:xmlNanoHTTPFetch=uninstrumented -fun:xmlNanoHTTPInit=uninstrumented -fun:xmlNanoHTTPMethod=uninstrumented -fun:xmlNanoHTTPMethodRedir=uninstrumented -fun:xmlNanoHTTPMimeType=uninstrumented -fun:xmlNanoHTTPOpen=uninstrumented -fun:xmlNanoHTTPOpenRedir=uninstrumented -fun:xmlNanoHTTPRead=uninstrumented -fun:xmlNanoHTTPRedir=uninstrumented -fun:xmlNanoHTTPReturnCode=uninstrumented -fun:xmlNanoHTTPSave=uninstrumented -fun:xmlNanoHTTPScanProxy=uninstrumented -fun:xmlNewAutomata=uninstrumented -fun:xmlNewCDataBlock=uninstrumented -fun:xmlNewCatalog=uninstrumented -fun:xmlNewCharEncodingHandler=uninstrumented -fun:xmlNewCharRef=uninstrumented -fun:xmlNewChild=uninstrumented -fun:xmlNewComment=uninstrumented -fun:xmlNewDoc=uninstrumented -fun:xmlNewDocComment=uninstrumented -fun:xmlNewDocElementContent=uninstrumented -fun:xmlNewDocFragment=uninstrumented -fun:xmlNewDocNode=uninstrumented -fun:xmlNewDocNodeEatName=uninstrumented -fun:xmlNewDocPI=uninstrumented -fun:xmlNewDocProp=uninstrumented -fun:xmlNewDocRawNode=uninstrumented -fun:xmlNewDocText=uninstrumented -fun:xmlNewDocTextLen=uninstrumented -fun:xmlNewDtd=uninstrumented -fun:xmlNewElementContent=uninstrumented -fun:xmlNewEntity=uninstrumented -fun:xmlNewEntityInputStream=uninstrumented -fun:xmlNewGlobalNs=uninstrumented -fun:xmlNewIOInputStream=uninstrumented -fun:xmlNewInputFromFile=uninstrumented -fun:xmlNewInputStream=uninstrumented -fun:xmlNewMutex=uninstrumented -fun:xmlNewNode=uninstrumented -fun:xmlNewNodeEatName=uninstrumented -fun:xmlNewNs=uninstrumented -fun:xmlNewNsProp=uninstrumented -fun:xmlNewNsPropEatName=uninstrumented -fun:xmlNewPI=uninstrumented -fun:xmlNewParserCtxt=uninstrumented -fun:xmlNewProp=uninstrumented -fun:xmlNewRMutex=uninstrumented -fun:xmlNewReference=uninstrumented -fun:xmlNewStringInputStream=uninstrumented -fun:xmlNewText=uninstrumented -fun:xmlNewTextChild=uninstrumented -fun:xmlNewTextLen=uninstrumented -fun:xmlNewTextReader=uninstrumented -fun:xmlNewTextReaderFilename=uninstrumented -fun:xmlNewTextWriter=uninstrumented -fun:xmlNewTextWriterDoc=uninstrumented -fun:xmlNewTextWriterFilename=uninstrumented -fun:xmlNewTextWriterMemory=uninstrumented -fun:xmlNewTextWriterPushParser=uninstrumented -fun:xmlNewTextWriterTree=uninstrumented -fun:xmlNewValidCtxt=uninstrumented -fun:xmlNextChar=uninstrumented -fun:xmlNextElementSibling=uninstrumented -fun:xmlNoNetExternalEntityLoader=uninstrumented -fun:xmlNodeAddContent=uninstrumented -fun:xmlNodeAddContentLen=uninstrumented -fun:xmlNodeBufGetContent=uninstrumented -fun:xmlNodeDump=uninstrumented -fun:xmlNodeDumpOutput=uninstrumented -fun:xmlNodeGetBase=uninstrumented -fun:xmlNodeGetContent=uninstrumented -fun:xmlNodeGetLang=uninstrumented -fun:xmlNodeGetSpacePreserve=uninstrumented -fun:xmlNodeIsText=uninstrumented -fun:xmlNodeListGetRawString=uninstrumented -fun:xmlNodeListGetString=uninstrumented -fun:xmlNodeSetBase=uninstrumented -fun:xmlNodeSetContent=uninstrumented -fun:xmlNodeSetContentLen=uninstrumented -fun:xmlNodeSetLang=uninstrumented -fun:xmlNodeSetName=uninstrumented -fun:xmlNodeSetSpacePreserve=uninstrumented -fun:xmlNormalizeURIPath=uninstrumented -fun:xmlNormalizeWindowsPath=uninstrumented -fun:xmlNsListDumpOutput=uninstrumented -fun:xmlOutputBufferClose=uninstrumented -fun:xmlOutputBufferCreateBuffer=uninstrumented -fun:xmlOutputBufferCreateFd=uninstrumented -fun:xmlOutputBufferCreateFile=uninstrumented -fun:xmlOutputBufferCreateFilename=uninstrumented -fun:xmlOutputBufferCreateFilenameDefault=uninstrumented -fun:xmlOutputBufferCreateIO=uninstrumented -fun:xmlOutputBufferFlush=uninstrumented -fun:xmlOutputBufferGetContent=uninstrumented -fun:xmlOutputBufferGetSize=uninstrumented -fun:xmlOutputBufferWrite=uninstrumented -fun:xmlOutputBufferWriteEscape=uninstrumented -fun:xmlOutputBufferWriteString=uninstrumented -fun:xmlParseAttValue=uninstrumented -fun:xmlParseAttribute=uninstrumented -fun:xmlParseAttributeListDecl=uninstrumented -fun:xmlParseAttributeType=uninstrumented -fun:xmlParseBalancedChunkMemory=uninstrumented -fun:xmlParseBalancedChunkMemoryRecover=uninstrumented -fun:xmlParseCDSect=uninstrumented -fun:xmlParseCatalogFile=uninstrumented -fun:xmlParseCharData=uninstrumented -fun:xmlParseCharEncoding=uninstrumented -fun:xmlParseCharRef=uninstrumented -fun:xmlParseChunk=uninstrumented -fun:xmlParseComment=uninstrumented -fun:xmlParseContent=uninstrumented -fun:xmlParseCtxtExternalEntity=uninstrumented -fun:xmlParseDTD=uninstrumented -fun:xmlParseDefaultDecl=uninstrumented -fun:xmlParseDoc=uninstrumented -fun:xmlParseDocTypeDecl=uninstrumented -fun:xmlParseDocument=uninstrumented -fun:xmlParseElement=uninstrumented -fun:xmlParseElementChildrenContentDecl=uninstrumented -fun:xmlParseElementContentDecl=uninstrumented -fun:xmlParseElementDecl=uninstrumented -fun:xmlParseElementMixedContentDecl=uninstrumented -fun:xmlParseEncName=uninstrumented -fun:xmlParseEncodingDecl=uninstrumented -fun:xmlParseEndTag=uninstrumented -fun:xmlParseEntity=uninstrumented -fun:xmlParseEntityDecl=uninstrumented -fun:xmlParseEntityRef=uninstrumented -fun:xmlParseEntityValue=uninstrumented -fun:xmlParseEnumeratedType=uninstrumented -fun:xmlParseEnumerationType=uninstrumented -fun:xmlParseExtParsedEnt=uninstrumented -fun:xmlParseExternalEntity=uninstrumented -fun:xmlParseExternalID=uninstrumented -fun:xmlParseExternalSubset=uninstrumented -fun:xmlParseFile=uninstrumented -fun:xmlParseInNodeContext=uninstrumented -fun:xmlParseMarkupDecl=uninstrumented -fun:xmlParseMemory=uninstrumented -fun:xmlParseMisc=uninstrumented -fun:xmlParseName=uninstrumented -fun:xmlParseNamespace=uninstrumented -fun:xmlParseNmtoken=uninstrumented -fun:xmlParseNotationDecl=uninstrumented -fun:xmlParseNotationType=uninstrumented -fun:xmlParsePEReference=uninstrumented -fun:xmlParsePI=uninstrumented -fun:xmlParsePITarget=uninstrumented -fun:xmlParsePubidLiteral=uninstrumented -fun:xmlParseQuotedString=uninstrumented -fun:xmlParseReference=uninstrumented -fun:xmlParseSDDecl=uninstrumented -fun:xmlParseStartTag=uninstrumented -fun:xmlParseSystemLiteral=uninstrumented -fun:xmlParseTextDecl=uninstrumented -fun:xmlParseURI=uninstrumented -fun:xmlParseURIRaw=uninstrumented -fun:xmlParseURIReference=uninstrumented -fun:xmlParseVersionInfo=uninstrumented -fun:xmlParseVersionNum=uninstrumented -fun:xmlParseXMLDecl=uninstrumented -fun:xmlParserAddNodeInfo=uninstrumented -fun:xmlParserError=uninstrumented -fun:xmlParserFindNodeInfo=uninstrumented -fun:xmlParserFindNodeInfoIndex=uninstrumented -fun:xmlParserGetDirectory=uninstrumented -fun:xmlParserHandlePEReference=uninstrumented -fun:xmlParserHandleReference=uninstrumented -fun:xmlParserInputBufferCreateFd=uninstrumented -fun:xmlParserInputBufferCreateFile=uninstrumented -fun:xmlParserInputBufferCreateFilename=uninstrumented -fun:xmlParserInputBufferCreateFilenameDefault=uninstrumented -fun:xmlParserInputBufferCreateIO=uninstrumented -fun:xmlParserInputBufferCreateMem=uninstrumented -fun:xmlParserInputBufferCreateStatic=uninstrumented -fun:xmlParserInputBufferGrow=uninstrumented -fun:xmlParserInputBufferPush=uninstrumented -fun:xmlParserInputBufferRead=uninstrumented -fun:xmlParserInputGrow=uninstrumented -fun:xmlParserInputRead=uninstrumented -fun:xmlParserInputShrink=uninstrumented -fun:xmlParserPrintFileContext=uninstrumented -fun:xmlParserPrintFileInfo=uninstrumented -fun:xmlParserValidityError=uninstrumented -fun:xmlParserValidityWarning=uninstrumented -fun:xmlParserWarning=uninstrumented -fun:xmlPathToURI=uninstrumented -fun:xmlPatternFromRoot=uninstrumented -fun:xmlPatternGetStreamCtxt=uninstrumented -fun:xmlPatternMatch=uninstrumented -fun:xmlPatternMaxDepth=uninstrumented -fun:xmlPatternMinDepth=uninstrumented -fun:xmlPatternStreamable=uninstrumented -fun:xmlPatterncompile=uninstrumented -fun:xmlPedanticParserDefault=uninstrumented -fun:xmlPopInput=uninstrumented -fun:xmlPopInputCallbacks=uninstrumented -fun:xmlPreviousElementSibling=uninstrumented -fun:xmlPrintURI=uninstrumented -fun:xmlPushInput=uninstrumented -fun:xmlRMutexLock=uninstrumented -fun:xmlRMutexUnlock=uninstrumented -fun:xmlReadDoc=uninstrumented -fun:xmlReadFd=uninstrumented -fun:xmlReadFile=uninstrumented -fun:xmlReadIO=uninstrumented -fun:xmlReadMemory=uninstrumented -fun:xmlReaderForDoc=uninstrumented -fun:xmlReaderForFd=uninstrumented -fun:xmlReaderForFile=uninstrumented -fun:xmlReaderForIO=uninstrumented -fun:xmlReaderForMemory=uninstrumented -fun:xmlReaderNewDoc=uninstrumented -fun:xmlReaderNewFd=uninstrumented -fun:xmlReaderNewFile=uninstrumented -fun:xmlReaderNewIO=uninstrumented -fun:xmlReaderNewMemory=uninstrumented -fun:xmlReaderNewWalker=uninstrumented -fun:xmlReaderWalker=uninstrumented -fun:xmlReallocLoc=uninstrumented -fun:xmlReconciliateNs=uninstrumented -fun:xmlRecoverDoc=uninstrumented -fun:xmlRecoverFile=uninstrumented -fun:xmlRecoverMemory=uninstrumented -fun:xmlRegExecErrInfo=uninstrumented -fun:xmlRegExecNextValues=uninstrumented -fun:xmlRegExecPushString=uninstrumented -fun:xmlRegExecPushString2=uninstrumented -fun:xmlRegFreeExecCtxt=uninstrumented -fun:xmlRegFreeRegexp=uninstrumented -fun:xmlRegNewExecCtxt=uninstrumented -fun:xmlRegexpCompile=uninstrumented -fun:xmlRegexpExec=uninstrumented -fun:xmlRegexpIsDeterminist=uninstrumented -fun:xmlRegexpPrint=uninstrumented -fun:xmlRegisterCharEncodingHandler=uninstrumented -fun:xmlRegisterDefaultInputCallbacks=uninstrumented -fun:xmlRegisterDefaultOutputCallbacks=uninstrumented -fun:xmlRegisterHTTPPostCallbacks=uninstrumented -fun:xmlRegisterInputCallbacks=uninstrumented -fun:xmlRegisterNodeDefault=uninstrumented -fun:xmlRegisterOutputCallbacks=uninstrumented -fun:xmlRelaxNGCleanupTypes=uninstrumented -fun:xmlRelaxNGDump=uninstrumented -fun:xmlRelaxNGDumpTree=uninstrumented -fun:xmlRelaxNGFree=uninstrumented -fun:xmlRelaxNGFreeParserCtxt=uninstrumented -fun:xmlRelaxNGFreeValidCtxt=uninstrumented -fun:xmlRelaxNGGetParserErrors=uninstrumented -fun:xmlRelaxNGGetValidErrors=uninstrumented -fun:xmlRelaxNGInitTypes=uninstrumented -fun:xmlRelaxNGNewDocParserCtxt=uninstrumented -fun:xmlRelaxNGNewMemParserCtxt=uninstrumented -fun:xmlRelaxNGNewParserCtxt=uninstrumented -fun:xmlRelaxNGNewValidCtxt=uninstrumented -fun:xmlRelaxNGParse=uninstrumented -fun:xmlRelaxNGSetParserErrors=uninstrumented -fun:xmlRelaxNGSetParserStructuredErrors=uninstrumented -fun:xmlRelaxNGSetValidErrors=uninstrumented -fun:xmlRelaxNGSetValidStructuredErrors=uninstrumented -fun:xmlRelaxNGValidateDoc=uninstrumented -fun:xmlRelaxNGValidateFullElement=uninstrumented -fun:xmlRelaxNGValidatePopElement=uninstrumented -fun:xmlRelaxNGValidatePushCData=uninstrumented -fun:xmlRelaxNGValidatePushElement=uninstrumented -fun:xmlRelaxParserSetFlag=uninstrumented -fun:xmlRemoveID=uninstrumented -fun:xmlRemoveProp=uninstrumented -fun:xmlRemoveRef=uninstrumented -fun:xmlReplaceNode=uninstrumented -fun:xmlResetError=uninstrumented -fun:xmlResetLastError=uninstrumented -fun:xmlSAX2AttributeDecl=uninstrumented -fun:xmlSAX2CDataBlock=uninstrumented -fun:xmlSAX2Characters=uninstrumented -fun:xmlSAX2Comment=uninstrumented -fun:xmlSAX2ElementDecl=uninstrumented -fun:xmlSAX2EndDocument=uninstrumented -fun:xmlSAX2EndElement=uninstrumented -fun:xmlSAX2EndElementNs=uninstrumented -fun:xmlSAX2EntityDecl=uninstrumented -fun:xmlSAX2ExternalSubset=uninstrumented -fun:xmlSAX2GetColumnNumber=uninstrumented -fun:xmlSAX2GetEntity=uninstrumented -fun:xmlSAX2GetLineNumber=uninstrumented -fun:xmlSAX2GetParameterEntity=uninstrumented -fun:xmlSAX2GetPublicId=uninstrumented -fun:xmlSAX2GetSystemId=uninstrumented -fun:xmlSAX2HasExternalSubset=uninstrumented -fun:xmlSAX2HasInternalSubset=uninstrumented -fun:xmlSAX2IgnorableWhitespace=uninstrumented -fun:xmlSAX2InitDefaultSAXHandler=uninstrumented -fun:xmlSAX2InitDocbDefaultSAXHandler=uninstrumented -fun:xmlSAX2InitHtmlDefaultSAXHandler=uninstrumented -fun:xmlSAX2InternalSubset=uninstrumented -fun:xmlSAX2IsStandalone=uninstrumented -fun:xmlSAX2NotationDecl=uninstrumented -fun:xmlSAX2ProcessingInstruction=uninstrumented -fun:xmlSAX2Reference=uninstrumented -fun:xmlSAX2ResolveEntity=uninstrumented -fun:xmlSAX2SetDocumentLocator=uninstrumented -fun:xmlSAX2StartDocument=uninstrumented -fun:xmlSAX2StartElement=uninstrumented -fun:xmlSAX2StartElementNs=uninstrumented -fun:xmlSAX2UnparsedEntityDecl=uninstrumented -fun:xmlSAXDefaultVersion=uninstrumented -fun:xmlSAXParseDTD=uninstrumented -fun:xmlSAXParseDoc=uninstrumented -fun:xmlSAXParseEntity=uninstrumented -fun:xmlSAXParseFile=uninstrumented -fun:xmlSAXParseFileWithData=uninstrumented -fun:xmlSAXParseMemory=uninstrumented -fun:xmlSAXParseMemoryWithData=uninstrumented -fun:xmlSAXUserParseFile=uninstrumented -fun:xmlSAXUserParseMemory=uninstrumented -fun:xmlSAXVersion=uninstrumented -fun:xmlSaveClose=uninstrumented -fun:xmlSaveDoc=uninstrumented -fun:xmlSaveFile=uninstrumented -fun:xmlSaveFileEnc=uninstrumented -fun:xmlSaveFileTo=uninstrumented -fun:xmlSaveFlush=uninstrumented -fun:xmlSaveFormatFile=uninstrumented -fun:xmlSaveFormatFileEnc=uninstrumented -fun:xmlSaveFormatFileTo=uninstrumented -fun:xmlSaveSetAttrEscape=uninstrumented -fun:xmlSaveSetEscape=uninstrumented -fun:xmlSaveToBuffer=uninstrumented -fun:xmlSaveToFd=uninstrumented -fun:xmlSaveToFilename=uninstrumented -fun:xmlSaveToIO=uninstrumented -fun:xmlSaveTree=uninstrumented -fun:xmlSaveUri=uninstrumented -fun:xmlScanName=uninstrumented -fun:xmlSchemaCheckFacet=uninstrumented -fun:xmlSchemaCleanupTypes=uninstrumented -fun:xmlSchemaCollapseString=uninstrumented -fun:xmlSchemaCompareValues=uninstrumented -fun:xmlSchemaCompareValuesWhtsp=uninstrumented -fun:xmlSchemaCopyValue=uninstrumented -fun:xmlSchemaDump=uninstrumented -fun:xmlSchemaFree=uninstrumented -fun:xmlSchemaFreeFacet=uninstrumented -fun:xmlSchemaFreeParserCtxt=uninstrumented -fun:xmlSchemaFreeType=uninstrumented -fun:xmlSchemaFreeValidCtxt=uninstrumented -fun:xmlSchemaFreeValue=uninstrumented -fun:xmlSchemaFreeWildcard=uninstrumented -fun:xmlSchemaGetBuiltInListSimpleTypeItemType=uninstrumented -fun:xmlSchemaGetBuiltInType=uninstrumented -fun:xmlSchemaGetCanonValue=uninstrumented -fun:xmlSchemaGetCanonValueWhtsp=uninstrumented -fun:xmlSchemaGetFacetValueAsULong=uninstrumented -fun:xmlSchemaGetParserErrors=uninstrumented -fun:xmlSchemaGetPredefinedType=uninstrumented -fun:xmlSchemaGetValType=uninstrumented -fun:xmlSchemaGetValidErrors=uninstrumented -fun:xmlSchemaInitTypes=uninstrumented -fun:xmlSchemaIsBuiltInTypeFacet=uninstrumented -fun:xmlSchemaIsValid=uninstrumented -fun:xmlSchemaNewDocParserCtxt=uninstrumented -fun:xmlSchemaNewFacet=uninstrumented -fun:xmlSchemaNewMemParserCtxt=uninstrumented -fun:xmlSchemaNewNOTATIONValue=uninstrumented -fun:xmlSchemaNewParserCtxt=uninstrumented -fun:xmlSchemaNewQNameValue=uninstrumented -fun:xmlSchemaNewStringValue=uninstrumented -fun:xmlSchemaNewValidCtxt=uninstrumented -fun:xmlSchemaParse=uninstrumented -fun:xmlSchemaSAXPlug=uninstrumented -fun:xmlSchemaSAXUnplug=uninstrumented -fun:xmlSchemaSetParserErrors=uninstrumented -fun:xmlSchemaSetParserStructuredErrors=uninstrumented -fun:xmlSchemaSetValidErrors=uninstrumented -fun:xmlSchemaSetValidOptions=uninstrumented -fun:xmlSchemaSetValidStructuredErrors=uninstrumented -fun:xmlSchemaValPredefTypeNode=uninstrumented -fun:xmlSchemaValPredefTypeNodeNoNorm=uninstrumented -fun:xmlSchemaValidCtxtGetOptions=uninstrumented -fun:xmlSchemaValidCtxtGetParserCtxt=uninstrumented -fun:xmlSchemaValidateDoc=uninstrumented -fun:xmlSchemaValidateFacet=uninstrumented -fun:xmlSchemaValidateFacetWhtsp=uninstrumented -fun:xmlSchemaValidateFile=uninstrumented -fun:xmlSchemaValidateLengthFacet=uninstrumented -fun:xmlSchemaValidateLengthFacetWhtsp=uninstrumented -fun:xmlSchemaValidateListSimpleTypeFacet=uninstrumented -fun:xmlSchemaValidateOneElement=uninstrumented -fun:xmlSchemaValidatePredefinedType=uninstrumented -fun:xmlSchemaValidateSetFilename=uninstrumented -fun:xmlSchemaValidateSetLocator=uninstrumented -fun:xmlSchemaValidateStream=uninstrumented -fun:xmlSchemaValueAppend=uninstrumented -fun:xmlSchemaValueGetAsBoolean=uninstrumented -fun:xmlSchemaValueGetAsString=uninstrumented -fun:xmlSchemaValueGetNext=uninstrumented -fun:xmlSchemaWhiteSpaceReplace=uninstrumented -fun:xmlSchematronFree=uninstrumented -fun:xmlSchematronFreeParserCtxt=uninstrumented -fun:xmlSchematronFreeValidCtxt=uninstrumented -fun:xmlSchematronNewDocParserCtxt=uninstrumented -fun:xmlSchematronNewMemParserCtxt=uninstrumented -fun:xmlSchematronNewParserCtxt=uninstrumented -fun:xmlSchematronNewValidCtxt=uninstrumented -fun:xmlSchematronParse=uninstrumented -fun:xmlSchematronSetValidStructuredErrors=uninstrumented -fun:xmlSchematronValidateDoc=uninstrumented -fun:xmlSearchNs=uninstrumented -fun:xmlSearchNsByHref=uninstrumented -fun:xmlSetBufferAllocationScheme=uninstrumented -fun:xmlSetCompressMode=uninstrumented -fun:xmlSetDocCompressMode=uninstrumented -fun:xmlSetEntityReferenceFunc=uninstrumented -fun:xmlSetExternalEntityLoader=uninstrumented -fun:xmlSetFeature=uninstrumented -fun:xmlSetGenericErrorFunc=uninstrumented -fun:xmlSetListDoc=uninstrumented -fun:xmlSetNs=uninstrumented -fun:xmlSetNsProp=uninstrumented -fun:xmlSetProp=uninstrumented -fun:xmlSetStructuredErrorFunc=uninstrumented -fun:xmlSetTreeDoc=uninstrumented -fun:xmlSetupParserForBuffer=uninstrumented -fun:xmlShell=uninstrumented -fun:xmlShellBase=uninstrumented -fun:xmlShellCat=uninstrumented -fun:xmlShellDir=uninstrumented -fun:xmlShellDu=uninstrumented -fun:xmlShellList=uninstrumented -fun:xmlShellLoad=uninstrumented -fun:xmlShellPrintNode=uninstrumented -fun:xmlShellPrintXPathError=uninstrumented -fun:xmlShellPrintXPathResult=uninstrumented -fun:xmlShellPwd=uninstrumented -fun:xmlShellSave=uninstrumented -fun:xmlShellValidate=uninstrumented -fun:xmlShellWrite=uninstrumented -fun:xmlSkipBlankChars=uninstrumented -fun:xmlSnprintfElementContent=uninstrumented -fun:xmlSplitQName=uninstrumented -fun:xmlSplitQName2=uninstrumented -fun:xmlSplitQName3=uninstrumented -fun:xmlSprintfElementContent=uninstrumented -fun:xmlStopParser=uninstrumented -fun:xmlStrEqual=uninstrumented -fun:xmlStrPrintf=uninstrumented -fun:xmlStrQEqual=uninstrumented -fun:xmlStrVPrintf=uninstrumented -fun:xmlStrcasecmp=uninstrumented -fun:xmlStrcasestr=uninstrumented -fun:xmlStrcat=uninstrumented -fun:xmlStrchr=uninstrumented -fun:xmlStrcmp=uninstrumented -fun:xmlStrdup=uninstrumented -fun:xmlStreamPop=uninstrumented -fun:xmlStreamPush=uninstrumented -fun:xmlStreamPushAttr=uninstrumented -fun:xmlStreamPushNode=uninstrumented -fun:xmlStreamWantsAnyNode=uninstrumented -fun:xmlStringCurrentChar=uninstrumented -fun:xmlStringDecodeEntities=uninstrumented -fun:xmlStringGetNodeList=uninstrumented -fun:xmlStringLenDecodeEntities=uninstrumented -fun:xmlStringLenGetNodeList=uninstrumented -fun:xmlStrlen=uninstrumented -fun:xmlStrncasecmp=uninstrumented -fun:xmlStrncat=uninstrumented -fun:xmlStrncatNew=uninstrumented -fun:xmlStrncmp=uninstrumented -fun:xmlStrndup=uninstrumented -fun:xmlStrstr=uninstrumented -fun:xmlStrsub=uninstrumented -fun:xmlSubstituteEntitiesDefault=uninstrumented -fun:xmlSwitchEncoding=uninstrumented -fun:xmlSwitchInputEncoding=uninstrumented -fun:xmlSwitchToEncoding=uninstrumented -fun:xmlTextConcat=uninstrumented -fun:xmlTextMerge=uninstrumented -fun:xmlTextReaderAttributeCount=uninstrumented -fun:xmlTextReaderBaseUri=uninstrumented -fun:xmlTextReaderByteConsumed=uninstrumented -fun:xmlTextReaderClose=uninstrumented -fun:xmlTextReaderConstBaseUri=uninstrumented -fun:xmlTextReaderConstEncoding=uninstrumented -fun:xmlTextReaderConstLocalName=uninstrumented -fun:xmlTextReaderConstName=uninstrumented -fun:xmlTextReaderConstNamespaceUri=uninstrumented -fun:xmlTextReaderConstPrefix=uninstrumented -fun:xmlTextReaderConstString=uninstrumented -fun:xmlTextReaderConstValue=uninstrumented -fun:xmlTextReaderConstXmlLang=uninstrumented -fun:xmlTextReaderConstXmlVersion=uninstrumented -fun:xmlTextReaderCurrentDoc=uninstrumented -fun:xmlTextReaderCurrentNode=uninstrumented -fun:xmlTextReaderDepth=uninstrumented -fun:xmlTextReaderExpand=uninstrumented -fun:xmlTextReaderGetAttribute=uninstrumented -fun:xmlTextReaderGetAttributeNo=uninstrumented -fun:xmlTextReaderGetAttributeNs=uninstrumented -fun:xmlTextReaderGetErrorHandler=uninstrumented -fun:xmlTextReaderGetParserColumnNumber=uninstrumented -fun:xmlTextReaderGetParserLineNumber=uninstrumented -fun:xmlTextReaderGetParserProp=uninstrumented -fun:xmlTextReaderGetRemainder=uninstrumented -fun:xmlTextReaderHasAttributes=uninstrumented -fun:xmlTextReaderHasValue=uninstrumented -fun:xmlTextReaderIsDefault=uninstrumented -fun:xmlTextReaderIsEmptyElement=uninstrumented -fun:xmlTextReaderIsNamespaceDecl=uninstrumented -fun:xmlTextReaderIsValid=uninstrumented -fun:xmlTextReaderLocalName=uninstrumented -fun:xmlTextReaderLocatorBaseURI=uninstrumented -fun:xmlTextReaderLocatorLineNumber=uninstrumented -fun:xmlTextReaderLookupNamespace=uninstrumented -fun:xmlTextReaderMoveToAttribute=uninstrumented -fun:xmlTextReaderMoveToAttributeNo=uninstrumented -fun:xmlTextReaderMoveToAttributeNs=uninstrumented -fun:xmlTextReaderMoveToElement=uninstrumented -fun:xmlTextReaderMoveToFirstAttribute=uninstrumented -fun:xmlTextReaderMoveToNextAttribute=uninstrumented -fun:xmlTextReaderName=uninstrumented -fun:xmlTextReaderNamespaceUri=uninstrumented -fun:xmlTextReaderNext=uninstrumented -fun:xmlTextReaderNextSibling=uninstrumented -fun:xmlTextReaderNodeType=uninstrumented -fun:xmlTextReaderNormalization=uninstrumented -fun:xmlTextReaderPrefix=uninstrumented -fun:xmlTextReaderPreserve=uninstrumented -fun:xmlTextReaderPreservePattern=uninstrumented -fun:xmlTextReaderQuoteChar=uninstrumented -fun:xmlTextReaderRead=uninstrumented -fun:xmlTextReaderReadAttributeValue=uninstrumented -fun:xmlTextReaderReadInnerXml=uninstrumented -fun:xmlTextReaderReadOuterXml=uninstrumented -fun:xmlTextReaderReadState=uninstrumented -fun:xmlTextReaderReadString=uninstrumented -fun:xmlTextReaderRelaxNGSetSchema=uninstrumented -fun:xmlTextReaderRelaxNGValidate=uninstrumented -fun:xmlTextReaderRelaxNGValidateCtxt=uninstrumented -fun:xmlTextReaderSchemaValidate=uninstrumented -fun:xmlTextReaderSchemaValidateCtxt=uninstrumented -fun:xmlTextReaderSetErrorHandler=uninstrumented -fun:xmlTextReaderSetParserProp=uninstrumented -fun:xmlTextReaderSetSchema=uninstrumented -fun:xmlTextReaderSetStructuredErrorHandler=uninstrumented -fun:xmlTextReaderSetup=uninstrumented -fun:xmlTextReaderStandalone=uninstrumented -fun:xmlTextReaderValue=uninstrumented -fun:xmlTextReaderXmlLang=uninstrumented -fun:xmlTextWriterEndAttribute=uninstrumented -fun:xmlTextWriterEndCDATA=uninstrumented -fun:xmlTextWriterEndComment=uninstrumented -fun:xmlTextWriterEndDTD=uninstrumented -fun:xmlTextWriterEndDTDAttlist=uninstrumented -fun:xmlTextWriterEndDTDElement=uninstrumented -fun:xmlTextWriterEndDTDEntity=uninstrumented -fun:xmlTextWriterEndDocument=uninstrumented -fun:xmlTextWriterEndElement=uninstrumented -fun:xmlTextWriterEndPI=uninstrumented -fun:xmlTextWriterFlush=uninstrumented -fun:xmlTextWriterFullEndElement=uninstrumented -fun:xmlTextWriterSetIndent=uninstrumented -fun:xmlTextWriterSetIndentString=uninstrumented -fun:xmlTextWriterSetQuoteChar=uninstrumented -fun:xmlTextWriterStartAttribute=uninstrumented -fun:xmlTextWriterStartAttributeNS=uninstrumented -fun:xmlTextWriterStartCDATA=uninstrumented -fun:xmlTextWriterStartComment=uninstrumented -fun:xmlTextWriterStartDTD=uninstrumented -fun:xmlTextWriterStartDTDAttlist=uninstrumented -fun:xmlTextWriterStartDTDElement=uninstrumented -fun:xmlTextWriterStartDTDEntity=uninstrumented -fun:xmlTextWriterStartDocument=uninstrumented -fun:xmlTextWriterStartElement=uninstrumented -fun:xmlTextWriterStartElementNS=uninstrumented -fun:xmlTextWriterStartPI=uninstrumented -fun:xmlTextWriterWriteAttribute=uninstrumented -fun:xmlTextWriterWriteAttributeNS=uninstrumented -fun:xmlTextWriterWriteBase64=uninstrumented -fun:xmlTextWriterWriteBinHex=uninstrumented -fun:xmlTextWriterWriteCDATA=uninstrumented -fun:xmlTextWriterWriteComment=uninstrumented -fun:xmlTextWriterWriteDTD=uninstrumented -fun:xmlTextWriterWriteDTDAttlist=uninstrumented -fun:xmlTextWriterWriteDTDElement=uninstrumented -fun:xmlTextWriterWriteDTDEntity=uninstrumented -fun:xmlTextWriterWriteDTDExternalEntity=uninstrumented -fun:xmlTextWriterWriteDTDExternalEntityContents=uninstrumented -fun:xmlTextWriterWriteDTDInternalEntity=uninstrumented -fun:xmlTextWriterWriteDTDNotation=uninstrumented -fun:xmlTextWriterWriteElement=uninstrumented -fun:xmlTextWriterWriteElementNS=uninstrumented -fun:xmlTextWriterWriteFormatAttribute=uninstrumented -fun:xmlTextWriterWriteFormatAttributeNS=uninstrumented -fun:xmlTextWriterWriteFormatCDATA=uninstrumented -fun:xmlTextWriterWriteFormatComment=uninstrumented -fun:xmlTextWriterWriteFormatDTD=uninstrumented -fun:xmlTextWriterWriteFormatDTDAttlist=uninstrumented -fun:xmlTextWriterWriteFormatDTDElement=uninstrumented -fun:xmlTextWriterWriteFormatDTDInternalEntity=uninstrumented -fun:xmlTextWriterWriteFormatElement=uninstrumented -fun:xmlTextWriterWriteFormatElementNS=uninstrumented -fun:xmlTextWriterWriteFormatPI=uninstrumented -fun:xmlTextWriterWriteFormatRaw=uninstrumented -fun:xmlTextWriterWriteFormatString=uninstrumented -fun:xmlTextWriterWritePI=uninstrumented -fun:xmlTextWriterWriteRaw=uninstrumented -fun:xmlTextWriterWriteRawLen=uninstrumented -fun:xmlTextWriterWriteString=uninstrumented -fun:xmlTextWriterWriteVFormatAttribute=uninstrumented -fun:xmlTextWriterWriteVFormatAttributeNS=uninstrumented -fun:xmlTextWriterWriteVFormatCDATA=uninstrumented -fun:xmlTextWriterWriteVFormatComment=uninstrumented -fun:xmlTextWriterWriteVFormatDTD=uninstrumented -fun:xmlTextWriterWriteVFormatDTDAttlist=uninstrumented -fun:xmlTextWriterWriteVFormatDTDElement=uninstrumented -fun:xmlTextWriterWriteVFormatDTDInternalEntity=uninstrumented -fun:xmlTextWriterWriteVFormatElement=uninstrumented -fun:xmlTextWriterWriteVFormatElementNS=uninstrumented -fun:xmlTextWriterWriteVFormatPI=uninstrumented -fun:xmlTextWriterWriteVFormatRaw=uninstrumented -fun:xmlTextWriterWriteVFormatString=uninstrumented -fun:xmlThrDefBufferAllocScheme=uninstrumented -fun:xmlThrDefDefaultBufferSize=uninstrumented -fun:xmlThrDefDeregisterNodeDefault=uninstrumented -fun:xmlThrDefDoValidityCheckingDefaultValue=uninstrumented -fun:xmlThrDefGetWarningsDefaultValue=uninstrumented -fun:xmlThrDefIndentTreeOutput=uninstrumented -fun:xmlThrDefKeepBlanksDefaultValue=uninstrumented -fun:xmlThrDefLineNumbersDefaultValue=uninstrumented -fun:xmlThrDefLoadExtDtdDefaultValue=uninstrumented -fun:xmlThrDefOutputBufferCreateFilenameDefault=uninstrumented -fun:xmlThrDefParserDebugEntities=uninstrumented -fun:xmlThrDefParserInputBufferCreateFilenameDefault=uninstrumented -fun:xmlThrDefPedanticParserDefaultValue=uninstrumented -fun:xmlThrDefRegisterNodeDefault=uninstrumented -fun:xmlThrDefSaveNoEmptyTags=uninstrumented -fun:xmlThrDefSetGenericErrorFunc=uninstrumented -fun:xmlThrDefSetStructuredErrorFunc=uninstrumented -fun:xmlThrDefSubstituteEntitiesDefaultValue=uninstrumented -fun:xmlThrDefTreeIndentString=uninstrumented -fun:xmlUCSIsAegeanNumbers=uninstrumented -fun:xmlUCSIsAlphabeticPresentationForms=uninstrumented -fun:xmlUCSIsArabic=uninstrumented -fun:xmlUCSIsArabicPresentationFormsA=uninstrumented -fun:xmlUCSIsArabicPresentationFormsB=uninstrumented -fun:xmlUCSIsArmenian=uninstrumented -fun:xmlUCSIsArrows=uninstrumented -fun:xmlUCSIsBasicLatin=uninstrumented -fun:xmlUCSIsBengali=uninstrumented -fun:xmlUCSIsBlock=uninstrumented -fun:xmlUCSIsBlockElements=uninstrumented -fun:xmlUCSIsBopomofo=uninstrumented -fun:xmlUCSIsBopomofoExtended=uninstrumented -fun:xmlUCSIsBoxDrawing=uninstrumented -fun:xmlUCSIsBraillePatterns=uninstrumented -fun:xmlUCSIsBuhid=uninstrumented -fun:xmlUCSIsByzantineMusicalSymbols=uninstrumented -fun:xmlUCSIsCJKCompatibility=uninstrumented -fun:xmlUCSIsCJKCompatibilityForms=uninstrumented -fun:xmlUCSIsCJKCompatibilityIdeographs=uninstrumented -fun:xmlUCSIsCJKCompatibilityIdeographsSupplement=uninstrumented -fun:xmlUCSIsCJKRadicalsSupplement=uninstrumented -fun:xmlUCSIsCJKSymbolsandPunctuation=uninstrumented -fun:xmlUCSIsCJKUnifiedIdeographs=uninstrumented -fun:xmlUCSIsCJKUnifiedIdeographsExtensionA=uninstrumented -fun:xmlUCSIsCJKUnifiedIdeographsExtensionB=uninstrumented -fun:xmlUCSIsCat=uninstrumented -fun:xmlUCSIsCatC=uninstrumented -fun:xmlUCSIsCatCc=uninstrumented -fun:xmlUCSIsCatCf=uninstrumented -fun:xmlUCSIsCatCo=uninstrumented -fun:xmlUCSIsCatCs=uninstrumented -fun:xmlUCSIsCatL=uninstrumented -fun:xmlUCSIsCatLl=uninstrumented -fun:xmlUCSIsCatLm=uninstrumented -fun:xmlUCSIsCatLo=uninstrumented -fun:xmlUCSIsCatLt=uninstrumented -fun:xmlUCSIsCatLu=uninstrumented -fun:xmlUCSIsCatM=uninstrumented -fun:xmlUCSIsCatMc=uninstrumented -fun:xmlUCSIsCatMe=uninstrumented -fun:xmlUCSIsCatMn=uninstrumented -fun:xmlUCSIsCatN=uninstrumented -fun:xmlUCSIsCatNd=uninstrumented -fun:xmlUCSIsCatNl=uninstrumented -fun:xmlUCSIsCatNo=uninstrumented -fun:xmlUCSIsCatP=uninstrumented -fun:xmlUCSIsCatPc=uninstrumented -fun:xmlUCSIsCatPd=uninstrumented -fun:xmlUCSIsCatPe=uninstrumented -fun:xmlUCSIsCatPf=uninstrumented -fun:xmlUCSIsCatPi=uninstrumented -fun:xmlUCSIsCatPo=uninstrumented -fun:xmlUCSIsCatPs=uninstrumented -fun:xmlUCSIsCatS=uninstrumented -fun:xmlUCSIsCatSc=uninstrumented -fun:xmlUCSIsCatSk=uninstrumented -fun:xmlUCSIsCatSm=uninstrumented -fun:xmlUCSIsCatSo=uninstrumented -fun:xmlUCSIsCatZ=uninstrumented -fun:xmlUCSIsCatZl=uninstrumented -fun:xmlUCSIsCatZp=uninstrumented -fun:xmlUCSIsCatZs=uninstrumented -fun:xmlUCSIsCherokee=uninstrumented -fun:xmlUCSIsCombiningDiacriticalMarks=uninstrumented -fun:xmlUCSIsCombiningDiacriticalMarksforSymbols=uninstrumented -fun:xmlUCSIsCombiningHalfMarks=uninstrumented -fun:xmlUCSIsCombiningMarksforSymbols=uninstrumented -fun:xmlUCSIsControlPictures=uninstrumented -fun:xmlUCSIsCurrencySymbols=uninstrumented -fun:xmlUCSIsCypriotSyllabary=uninstrumented -fun:xmlUCSIsCyrillic=uninstrumented -fun:xmlUCSIsCyrillicSupplement=uninstrumented -fun:xmlUCSIsDeseret=uninstrumented -fun:xmlUCSIsDevanagari=uninstrumented -fun:xmlUCSIsDingbats=uninstrumented -fun:xmlUCSIsEnclosedAlphanumerics=uninstrumented -fun:xmlUCSIsEnclosedCJKLettersandMonths=uninstrumented -fun:xmlUCSIsEthiopic=uninstrumented -fun:xmlUCSIsGeneralPunctuation=uninstrumented -fun:xmlUCSIsGeometricShapes=uninstrumented -fun:xmlUCSIsGeorgian=uninstrumented -fun:xmlUCSIsGothic=uninstrumented -fun:xmlUCSIsGreek=uninstrumented -fun:xmlUCSIsGreekExtended=uninstrumented -fun:xmlUCSIsGreekandCoptic=uninstrumented -fun:xmlUCSIsGujarati=uninstrumented -fun:xmlUCSIsGurmukhi=uninstrumented -fun:xmlUCSIsHalfwidthandFullwidthForms=uninstrumented -fun:xmlUCSIsHangulCompatibilityJamo=uninstrumented -fun:xmlUCSIsHangulJamo=uninstrumented -fun:xmlUCSIsHangulSyllables=uninstrumented -fun:xmlUCSIsHanunoo=uninstrumented -fun:xmlUCSIsHebrew=uninstrumented -fun:xmlUCSIsHighPrivateUseSurrogates=uninstrumented -fun:xmlUCSIsHighSurrogates=uninstrumented -fun:xmlUCSIsHiragana=uninstrumented -fun:xmlUCSIsIPAExtensions=uninstrumented -fun:xmlUCSIsIdeographicDescriptionCharacters=uninstrumented -fun:xmlUCSIsKanbun=uninstrumented -fun:xmlUCSIsKangxiRadicals=uninstrumented -fun:xmlUCSIsKannada=uninstrumented -fun:xmlUCSIsKatakana=uninstrumented -fun:xmlUCSIsKatakanaPhoneticExtensions=uninstrumented -fun:xmlUCSIsKhmer=uninstrumented -fun:xmlUCSIsKhmerSymbols=uninstrumented -fun:xmlUCSIsLao=uninstrumented -fun:xmlUCSIsLatin1Supplement=uninstrumented -fun:xmlUCSIsLatinExtendedA=uninstrumented -fun:xmlUCSIsLatinExtendedAdditional=uninstrumented -fun:xmlUCSIsLatinExtendedB=uninstrumented -fun:xmlUCSIsLetterlikeSymbols=uninstrumented -fun:xmlUCSIsLimbu=uninstrumented -fun:xmlUCSIsLinearBIdeograms=uninstrumented -fun:xmlUCSIsLinearBSyllabary=uninstrumented -fun:xmlUCSIsLowSurrogates=uninstrumented -fun:xmlUCSIsMalayalam=uninstrumented -fun:xmlUCSIsMathematicalAlphanumericSymbols=uninstrumented -fun:xmlUCSIsMathematicalOperators=uninstrumented -fun:xmlUCSIsMiscellaneousMathematicalSymbolsA=uninstrumented -fun:xmlUCSIsMiscellaneousMathematicalSymbolsB=uninstrumented -fun:xmlUCSIsMiscellaneousSymbols=uninstrumented -fun:xmlUCSIsMiscellaneousSymbolsandArrows=uninstrumented -fun:xmlUCSIsMiscellaneousTechnical=uninstrumented -fun:xmlUCSIsMongolian=uninstrumented -fun:xmlUCSIsMusicalSymbols=uninstrumented -fun:xmlUCSIsMyanmar=uninstrumented -fun:xmlUCSIsNumberForms=uninstrumented -fun:xmlUCSIsOgham=uninstrumented -fun:xmlUCSIsOldItalic=uninstrumented -fun:xmlUCSIsOpticalCharacterRecognition=uninstrumented -fun:xmlUCSIsOriya=uninstrumented -fun:xmlUCSIsOsmanya=uninstrumented -fun:xmlUCSIsPhoneticExtensions=uninstrumented -fun:xmlUCSIsPrivateUse=uninstrumented -fun:xmlUCSIsPrivateUseArea=uninstrumented -fun:xmlUCSIsRunic=uninstrumented -fun:xmlUCSIsShavian=uninstrumented -fun:xmlUCSIsSinhala=uninstrumented -fun:xmlUCSIsSmallFormVariants=uninstrumented -fun:xmlUCSIsSpacingModifierLetters=uninstrumented -fun:xmlUCSIsSpecials=uninstrumented -fun:xmlUCSIsSuperscriptsandSubscripts=uninstrumented -fun:xmlUCSIsSupplementalArrowsA=uninstrumented -fun:xmlUCSIsSupplementalArrowsB=uninstrumented -fun:xmlUCSIsSupplementalMathematicalOperators=uninstrumented -fun:xmlUCSIsSupplementaryPrivateUseAreaA=uninstrumented -fun:xmlUCSIsSupplementaryPrivateUseAreaB=uninstrumented -fun:xmlUCSIsSyriac=uninstrumented -fun:xmlUCSIsTagalog=uninstrumented -fun:xmlUCSIsTagbanwa=uninstrumented -fun:xmlUCSIsTags=uninstrumented -fun:xmlUCSIsTaiLe=uninstrumented -fun:xmlUCSIsTaiXuanJingSymbols=uninstrumented -fun:xmlUCSIsTamil=uninstrumented -fun:xmlUCSIsTelugu=uninstrumented -fun:xmlUCSIsThaana=uninstrumented -fun:xmlUCSIsThai=uninstrumented -fun:xmlUCSIsTibetan=uninstrumented -fun:xmlUCSIsUgaritic=uninstrumented -fun:xmlUCSIsUnifiedCanadianAboriginalSyllabics=uninstrumented -fun:xmlUCSIsVariationSelectors=uninstrumented -fun:xmlUCSIsVariationSelectorsSupplement=uninstrumented -fun:xmlUCSIsYiRadicals=uninstrumented -fun:xmlUCSIsYiSyllables=uninstrumented -fun:xmlUCSIsYijingHexagramSymbols=uninstrumented -fun:xmlURIEscape=uninstrumented -fun:xmlURIEscapeStr=uninstrumented -fun:xmlURIUnescapeString=uninstrumented -fun:xmlUTF8Charcmp=uninstrumented -fun:xmlUTF8Size=uninstrumented -fun:xmlUTF8Strlen=uninstrumented -fun:xmlUTF8Strloc=uninstrumented -fun:xmlUTF8Strndup=uninstrumented -fun:xmlUTF8Strpos=uninstrumented -fun:xmlUTF8Strsize=uninstrumented -fun:xmlUTF8Strsub=uninstrumented -fun:xmlUnlinkNode=uninstrumented -fun:xmlUnlockLibrary=uninstrumented -fun:xmlUnsetNsProp=uninstrumented -fun:xmlUnsetProp=uninstrumented -fun:xmlUpgradeOldNs=uninstrumented -fun:xmlValidBuildContentModel=uninstrumented -fun:xmlValidCtxtNormalizeAttributeValue=uninstrumented -fun:xmlValidGetPotentialChildren=uninstrumented -fun:xmlValidGetValidElements=uninstrumented -fun:xmlValidNormalizeAttributeValue=uninstrumented -fun:xmlValidateAttributeDecl=uninstrumented -fun:xmlValidateAttributeValue=uninstrumented -fun:xmlValidateDocument=uninstrumented -fun:xmlValidateDocumentFinal=uninstrumented -fun:xmlValidateDtd=uninstrumented -fun:xmlValidateDtdFinal=uninstrumented -fun:xmlValidateElement=uninstrumented -fun:xmlValidateElementDecl=uninstrumented -fun:xmlValidateNCName=uninstrumented -fun:xmlValidateNMToken=uninstrumented -fun:xmlValidateName=uninstrumented -fun:xmlValidateNameValue=uninstrumented -fun:xmlValidateNamesValue=uninstrumented -fun:xmlValidateNmtokenValue=uninstrumented -fun:xmlValidateNmtokensValue=uninstrumented -fun:xmlValidateNotationDecl=uninstrumented -fun:xmlValidateNotationUse=uninstrumented -fun:xmlValidateOneAttribute=uninstrumented -fun:xmlValidateOneElement=uninstrumented -fun:xmlValidateOneNamespace=uninstrumented -fun:xmlValidatePopElement=uninstrumented -fun:xmlValidatePushCData=uninstrumented -fun:xmlValidatePushElement=uninstrumented -fun:xmlValidateQName=uninstrumented -fun:xmlValidateRoot=uninstrumented -fun:xmlXIncludeFreeContext=uninstrumented -fun:xmlXIncludeNewContext=uninstrumented -fun:xmlXIncludeProcess=uninstrumented -fun:xmlXIncludeProcessFlags=uninstrumented -fun:xmlXIncludeProcessFlagsData=uninstrumented -fun:xmlXIncludeProcessNode=uninstrumented -fun:xmlXIncludeProcessTree=uninstrumented -fun:xmlXIncludeProcessTreeFlags=uninstrumented -fun:xmlXIncludeProcessTreeFlagsData=uninstrumented -fun:xmlXIncludeSetFlags=uninstrumented -fun:xmlXPathAddValues=uninstrumented -fun:xmlXPathBooleanFunction=uninstrumented -fun:xmlXPathCastBooleanToNumber=uninstrumented -fun:xmlXPathCastBooleanToString=uninstrumented -fun:xmlXPathCastNodeSetToBoolean=uninstrumented -fun:xmlXPathCastNodeSetToNumber=uninstrumented -fun:xmlXPathCastNodeSetToString=uninstrumented -fun:xmlXPathCastNodeToNumber=uninstrumented -fun:xmlXPathCastNodeToString=uninstrumented -fun:xmlXPathCastNumberToBoolean=uninstrumented -fun:xmlXPathCastNumberToString=uninstrumented -fun:xmlXPathCastStringToBoolean=uninstrumented -fun:xmlXPathCastStringToNumber=uninstrumented -fun:xmlXPathCastToBoolean=uninstrumented -fun:xmlXPathCastToNumber=uninstrumented -fun:xmlXPathCastToString=uninstrumented -fun:xmlXPathCeilingFunction=uninstrumented -fun:xmlXPathCmpNodes=uninstrumented -fun:xmlXPathCompareValues=uninstrumented -fun:xmlXPathCompile=uninstrumented -fun:xmlXPathCompiledEval=uninstrumented -fun:xmlXPathCompiledEvalToBoolean=uninstrumented -fun:xmlXPathConcatFunction=uninstrumented -fun:xmlXPathContainsFunction=uninstrumented -fun:xmlXPathContextSetCache=uninstrumented -fun:xmlXPathConvertBoolean=uninstrumented -fun:xmlXPathConvertNumber=uninstrumented -fun:xmlXPathConvertString=uninstrumented -fun:xmlXPathCountFunction=uninstrumented -fun:xmlXPathCtxtCompile=uninstrumented -fun:xmlXPathDebugDumpCompExpr=uninstrumented -fun:xmlXPathDebugDumpObject=uninstrumented -fun:xmlXPathDifference=uninstrumented -fun:xmlXPathDistinct=uninstrumented -fun:xmlXPathDistinctSorted=uninstrumented -fun:xmlXPathDivValues=uninstrumented -fun:xmlXPathEqualValues=uninstrumented -fun:xmlXPathErr=uninstrumented -fun:xmlXPathEval=uninstrumented -fun:xmlXPathEvalExpr=uninstrumented -fun:xmlXPathEvalExpression=uninstrumented -fun:xmlXPathEvalPredicate=uninstrumented -fun:xmlXPathEvaluatePredicateResult=uninstrumented -fun:xmlXPathFalseFunction=uninstrumented -fun:xmlXPathFloorFunction=uninstrumented -fun:xmlXPathFreeCompExpr=uninstrumented -fun:xmlXPathFreeContext=uninstrumented -fun:xmlXPathFreeNodeSet=uninstrumented -fun:xmlXPathFreeNodeSetList=uninstrumented -fun:xmlXPathFreeObject=uninstrumented -fun:xmlXPathFreeParserContext=uninstrumented -fun:xmlXPathFunctionLookup=uninstrumented -fun:xmlXPathFunctionLookupNS=uninstrumented -fun:xmlXPathHasSameNodes=uninstrumented -fun:xmlXPathIdFunction=uninstrumented -fun:xmlXPathInit=uninstrumented -fun:xmlXPathIntersection=uninstrumented -fun:xmlXPathIsInf=uninstrumented -fun:xmlXPathIsNaN=uninstrumented -fun:xmlXPathIsNodeType=uninstrumented -fun:xmlXPathLangFunction=uninstrumented -fun:xmlXPathLastFunction=uninstrumented -fun:xmlXPathLeading=uninstrumented -fun:xmlXPathLeadingSorted=uninstrumented -fun:xmlXPathLocalNameFunction=uninstrumented -fun:xmlXPathModValues=uninstrumented -fun:xmlXPathMultValues=uninstrumented -fun:xmlXPathNamespaceURIFunction=uninstrumented -fun:xmlXPathNewBoolean=uninstrumented -fun:xmlXPathNewCString=uninstrumented -fun:xmlXPathNewContext=uninstrumented -fun:xmlXPathNewFloat=uninstrumented -fun:xmlXPathNewNodeSet=uninstrumented -fun:xmlXPathNewNodeSetList=uninstrumented -fun:xmlXPathNewParserContext=uninstrumented -fun:xmlXPathNewString=uninstrumented -fun:xmlXPathNewValueTree=uninstrumented -fun:xmlXPathNextAncestor=uninstrumented -fun:xmlXPathNextAncestorOrSelf=uninstrumented -fun:xmlXPathNextAttribute=uninstrumented -fun:xmlXPathNextChild=uninstrumented -fun:xmlXPathNextDescendant=uninstrumented -fun:xmlXPathNextDescendantOrSelf=uninstrumented -fun:xmlXPathNextFollowing=uninstrumented -fun:xmlXPathNextFollowingSibling=uninstrumented -fun:xmlXPathNextNamespace=uninstrumented -fun:xmlXPathNextParent=uninstrumented -fun:xmlXPathNextPreceding=uninstrumented -fun:xmlXPathNextPrecedingSibling=uninstrumented -fun:xmlXPathNextSelf=uninstrumented -fun:xmlXPathNodeEval=uninstrumented -fun:xmlXPathNodeLeading=uninstrumented -fun:xmlXPathNodeLeadingSorted=uninstrumented -fun:xmlXPathNodeSetAdd=uninstrumented -fun:xmlXPathNodeSetAddNs=uninstrumented -fun:xmlXPathNodeSetAddUnique=uninstrumented -fun:xmlXPathNodeSetContains=uninstrumented -fun:xmlXPathNodeSetCreate=uninstrumented -fun:xmlXPathNodeSetDel=uninstrumented -fun:xmlXPathNodeSetFreeNs=uninstrumented -fun:xmlXPathNodeSetMerge=uninstrumented -fun:xmlXPathNodeSetRemove=uninstrumented -fun:xmlXPathNodeSetSort=uninstrumented -fun:xmlXPathNodeTrailing=uninstrumented -fun:xmlXPathNodeTrailingSorted=uninstrumented -fun:xmlXPathNormalizeFunction=uninstrumented -fun:xmlXPathNotEqualValues=uninstrumented -fun:xmlXPathNotFunction=uninstrumented -fun:xmlXPathNsLookup=uninstrumented -fun:xmlXPathNumberFunction=uninstrumented -fun:xmlXPathObjectCopy=uninstrumented -fun:xmlXPathOrderDocElems=uninstrumented -fun:xmlXPathParseNCName=uninstrumented -fun:xmlXPathParseName=uninstrumented -fun:xmlXPathPopBoolean=uninstrumented -fun:xmlXPathPopExternal=uninstrumented -fun:xmlXPathPopNodeSet=uninstrumented -fun:xmlXPathPopNumber=uninstrumented -fun:xmlXPathPopString=uninstrumented -fun:xmlXPathPositionFunction=uninstrumented -fun:xmlXPathRegisterAllFunctions=uninstrumented -fun:xmlXPathRegisterFunc=uninstrumented -fun:xmlXPathRegisterFuncLookup=uninstrumented -fun:xmlXPathRegisterFuncNS=uninstrumented -fun:xmlXPathRegisterNs=uninstrumented -fun:xmlXPathRegisterVariable=uninstrumented -fun:xmlXPathRegisterVariableLookup=uninstrumented -fun:xmlXPathRegisterVariableNS=uninstrumented -fun:xmlXPathRegisteredFuncsCleanup=uninstrumented -fun:xmlXPathRegisteredNsCleanup=uninstrumented -fun:xmlXPathRegisteredVariablesCleanup=uninstrumented -fun:xmlXPathRoot=uninstrumented -fun:xmlXPathRoundFunction=uninstrumented -fun:xmlXPathSetContextNode=uninstrumented -fun:xmlXPathStartsWithFunction=uninstrumented -fun:xmlXPathStringEvalNumber=uninstrumented -fun:xmlXPathStringFunction=uninstrumented -fun:xmlXPathStringLengthFunction=uninstrumented -fun:xmlXPathSubValues=uninstrumented -fun:xmlXPathSubstringAfterFunction=uninstrumented -fun:xmlXPathSubstringBeforeFunction=uninstrumented -fun:xmlXPathSubstringFunction=uninstrumented -fun:xmlXPathSumFunction=uninstrumented -fun:xmlXPathTrailing=uninstrumented -fun:xmlXPathTrailingSorted=uninstrumented -fun:xmlXPathTranslateFunction=uninstrumented -fun:xmlXPathTrueFunction=uninstrumented -fun:xmlXPathValueFlipSign=uninstrumented -fun:xmlXPathVariableLookup=uninstrumented -fun:xmlXPathVariableLookupNS=uninstrumented -fun:xmlXPathWrapCString=uninstrumented -fun:xmlXPathWrapExternal=uninstrumented -fun:xmlXPathWrapNodeSet=uninstrumented -fun:xmlXPathWrapString=uninstrumented -fun:xmlXPatherror=uninstrumented -fun:xmlXPtrAdvanceNode=uninstrumented -fun:xmlXPtrBuildNodeList=uninstrumented -fun:xmlXPtrEval=uninstrumented -fun:xmlXPtrEvalRangePredicate=uninstrumented -fun:xmlXPtrFreeLocationSet=uninstrumented -fun:xmlXPtrLocationSetAdd=uninstrumented -fun:xmlXPtrLocationSetCreate=uninstrumented -fun:xmlXPtrLocationSetDel=uninstrumented -fun:xmlXPtrLocationSetMerge=uninstrumented -fun:xmlXPtrLocationSetRemove=uninstrumented -fun:xmlXPtrNewCollapsedRange=uninstrumented -fun:xmlXPtrNewContext=uninstrumented -fun:xmlXPtrNewLocationSetNodeSet=uninstrumented -fun:xmlXPtrNewLocationSetNodes=uninstrumented -fun:xmlXPtrNewRange=uninstrumented -fun:xmlXPtrNewRangeNodeObject=uninstrumented -fun:xmlXPtrNewRangeNodePoint=uninstrumented -fun:xmlXPtrNewRangeNodes=uninstrumented -fun:xmlXPtrNewRangePointNode=uninstrumented -fun:xmlXPtrNewRangePoints=uninstrumented -fun:xmlXPtrRangeToFunction=uninstrumented -fun:xmlXPtrWrapLocationSet=uninstrumented diff --git a/service/gcbrun_experiment.py b/service/gcbrun_experiment.py index bbebcf1b9..c0f0d2228 100644 --- a/service/gcbrun_experiment.py +++ b/service/gcbrun_experiment.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# +# ################################################################################ """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