diff --git a/fuzzers/aflplusplus/fuzzer.py b/fuzzers/aflplusplus/fuzzer.py index 7016da75e..8fe240500 100755 --- a/fuzzers/aflplusplus/fuzzer.py +++ b/fuzzers/aflplusplus/fuzzer.py @@ -241,7 +241,7 @@ def fuzz(input_corpus, target_binary, flags=tuple(), skip=False, - no_cmplog=False): # pylint: disable=too-many-arguments + no_cmplog=True): # pylint: disable=too-many-arguments """Run fuzzer.""" # Calculate CmpLog binary path from the instrumented target binary. target_binary_directory = os.path.dirname(target_binary) @@ -262,8 +262,8 @@ 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 False: - flags += ['-c', cmplog_target_binary] + # 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' diff --git a/fuzzers/path_afl/builder.Dockerfile b/fuzzers/path_afl/builder.Dockerfile new file mode 100644 index 000000000..ad2072a7e --- /dev/null +++ b/fuzzers/path_afl/builder.Dockerfile @@ -0,0 +1,128 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 sudo make build-essential git wget tree vim gdb zstd libzstd-dev libjbig-dev libselinux-dev bash + +SHELL ["/bin/bash", "-c"] + +RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - + +RUN echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main" >> /etc/apt/sources.list +RUN echo "deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal main" >> /etc/apt/sources.list +RUN echo "# 17" >> /etc/apt/sources.list +RUN echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-17 main" >> /etc/apt/sources.list +RUN echo "deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-17 main" >> /etc/apt/sources.list + +RUN apt-get update && apt-get install -y clang-17 lld-17 llvm-17-dev \ + libc++-17-dev libc++abi-17-dev gcc-10 gcc-10-plugin-dev libstdc++-10-dev \ + libssl-dev cargo autopoint + +RUN update-alternatives \ + --install /usr/lib/llvm llvm /usr/lib/llvm-17 1000 \ + --slave /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-17 \ + --slave /usr/bin/llvm-ar llvm-ar /usr/bin/llvm-ar-17 \ + --slave /usr/bin/llvm-as llvm-as /usr/bin/llvm-as-17 \ + --slave /usr/bin/llvm-bcanalyzer llvm-bcanalyzer /usr/bin/llvm-bcanalyzer-17 \ + --slave /usr/bin/llvm-c-test llvm-c-test /usr/bin/llvm-c-test-17 \ + --slave /usr/bin/llvm-cov llvm-cov /usr/bin/llvm-cov-17 \ + --slave /usr/bin/llvm-diff llvm-diff /usr/bin/llvm-diff-17 \ + --slave /usr/bin/llvm-dis llvm-dis /usr/bin/llvm-dis-17 \ + --slave /usr/bin/llvm-dwarfdump llvm-dwarfdump /usr/bin/llvm-dwarfdump-17 \ + --slave /usr/bin/llvm-extract llvm-extract /usr/bin/llvm-extract-17 \ + --slave /usr/bin/llvm-link llvm-link /usr/bin/llvm-link-17 \ + --slave /usr/bin/llvm-mc llvm-mc /usr/bin/llvm-mc-17 \ + --slave /usr/bin/llvm-nm llvm-nm /usr/bin/llvm-nm-17 \ + --slave /usr/bin/llvm-objdump llvm-objdump /usr/bin/llvm-objdump-17 \ + --slave /usr/bin/llvm-ranlib llvm-ranlib /usr/bin/llvm-ranlib-17 \ + --slave /usr/bin/llvm-readobj llvm-readobj /usr/bin/llvm-readobj-17 \ + --slave /usr/bin/llvm-rtdyld llvm-rtdyld /usr/bin/llvm-rtdyld-17 \ + --slave /usr/bin/llvm-size llvm-size /usr/bin/llvm-size-17 \ + --slave /usr/bin/llvm-stress llvm-stress /usr/bin/llvm-stress-17 \ + --slave /usr/bin/llvm-symbolizer llvm-symbolizer /usr/bin/llvm-symbolizer-17 \ + --slave /usr/bin/llvm-tblgen llvm-tblgen /usr/bin/llvm-tblgen-17 + +RUN update-alternatives \ + --install /usr/bin/clang clang /usr/bin/clang-17 1000 \ + --slave /usr/bin/clang++ clang++ /usr/bin/clang++-17 \ + --slave /usr/bin/clang-cpp clang-cpp /usr/bin/clang-cpp-17 \ + --slave /usr/bin/ld.lld lld /usr/bin/ld.lld-17 + +# Uninstall old Rust +RUN if which rustup; then rustup self uninstall -y; fi + +# Install latest Rust +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > /rustup.sh && \ + sh /rustup.sh -y + +ENV PATH="/root/.cargo/bin:${PATH}" + +RUN rm -rf /usr/local/bin/clang /usr/local/bin/clang++ /usr/local/bin/llvm* +RUN rm -rf /usr/local/lib/clang +RUN rm -rf /usr/local/include/clang +RUN rm -rf /usr/local/share/clang + +# RUN rm /usr/local/bin/clang /usr/local/bin/clang++ /usr/local/bin/clang-cpp +# ENV PATH="/usr/bin:/usr/local/bin:$PATH" + +# RUN ls /usr/lib/llvm-17/include/llvm && exit 1 + +# RUN clang --version | grep "clang version 17" || { echo "Clang version is not 17"; exit 1; } + +RUN git clone -b fx-no-tail-opt1 https://github.com/fEst1ck/path-cov.git /path-cov + +RUN cd /path-cov && \ + git checkout ae6df67fee70abcada256f9519932237143ff8b6 && \ + cargo build --release + +RUN git clone -b fixversion https://github.com/path-cov-fuzzer/newpathAFLplusplus.git /path-afl + +# RUN clang++-17 -v -E -x c++ - < /dev/null && eixt 1 + +RUN cd /path-afl && \ + which clang-17 && \ + which clang && \ + clang --version && \ + clang++ -stdlib=libstdc++ -c hashcompare.cpp && \ + ar rcs libhashcompare.a hashcompare.o && \ + cp /path-cov/target/release/libpath_reduction.so . + +# RUN which llvm-config-17 || { echo "llvm-config-17 not found"; exit 1; } + +RUN cd /path-afl && \ + export CC=clang && \ + export CXX=clang++ && \ + export AFL_NO_X86=1 && \ + unset CFLAGS CXXFLAGS && \ + PYTHON_INCLUDE=/ && \ + LLVM_CONFIG=llvm-config-17 LD_LIBRARY_PATH="/path-afl" CFLAGS="-I/path-afl/fuzzing_support" LDFLAGS="-L/path-afl -lcrypto -lhashcompare -lstdc++ -lpath_reduction" make +# RUN export CC=clang && \ +# export CXX=clang++ && \ +# export AFL_NO_X86=1 && \ +# export PYTHON_INCLUDE=/ && \ +# LLVM_CONFIG=llvm-config-17 LD_LIBRARY_PATH="/path-afl" CFLAGS="-I/path-afl/fuzzing_support" LDFLAGS="-L/path-afl -lcrypto -lhashcompare -lstdc++ -lpath_reduction" make -e -C utils/aflpp_driver || exit 1 + +RUN apt install g++ + +# Build without Python support as we don't need it. +# Set AFL_NO_X86 to skip flaky tests. +RUN cd /path-afl && cp utils/aflpp_driver/libAFLDriver.a / + +RUN cp /usr/lib/x86_64-linux-gnu/libpython3.8.so.1.0 / + +RUN cp /usr/lib/llvm-17/lib/libc++.so.1 / +RUN cp /usr/lib/llvm-17/lib/libc++abi.so.1 / + diff --git a/fuzzers/path_afl/fuzzer.py b/fuzzers/path_afl/fuzzer.py new file mode 100644 index 000000000..49489f7e7 --- /dev/null +++ b/fuzzers/path_afl/fuzzer.py @@ -0,0 +1,154 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 pathAFL fuzzer.""" + +import os +import shutil +import subprocess + +from fuzzers import utils + + +def prepare_build_environment(): + """Set environment variables used to build targets for pathAFL-based + fuzzers.""" + os.environ["LD_LIBRARY_PATH"] = "/path-afl" + os.environ["CC"] = "/path-afl/afl-clang-fast" + os.environ["CXX"] = "/path-afl/afl-clang-fast++" + current_directory = os.getcwd() + os.environ["BBIDFILE"] = os.path.join(current_directory, "bbid.txt") + os.environ["CALLMAPFILE"] = os.path.join(current_directory, "callmap.txt") + os.environ["CFGFILE"] = os.path.join(current_directory, "cfg.txt") + os.environ["FUZZER"] = "/path-afl" + os.environ["AFL_LLVM_CALLER"] = "1" + os.environ["FUZZER_LIB"] = "/libAFLDriver.a" + + +def build(): + """Build benchmark.""" + prepare_build_environment() + + utils.build_benchmark() + + subprocess.run( + 'cat cfg.txt | grep "BasicBlock: " | wc -l > bbnum.txt', + shell=True, + check=True, + ) + print(f"/out/{os.getenv('FUZZ_TARGET')}") + result = subprocess.run( + [ + "bash", + "/path-afl/fuzzing_support/filterCFGandCallmap.sh", + f"/out/{os.getenv('FUZZ_TARGET')}", + ], + check=False, + capture_output=True, + text=True, + ) + print(result.stdout) + print(result.stderr) + subprocess.run( + "cat cfg_filtered.txt | grep \"Function: \" | nl -v 0 | " + "awk '{print $1, $3, $4, $5, $6, $7, $8, $9}' > function_list.txt", + shell=True, + check=True, + ) + subprocess.run( + "g++ -I/path-afl/fuzzing_support " + "/path-afl/fuzzing_support/convert.cpp -o convert", + shell=True, + check=True, + ) + subprocess.run("./convert", shell=True, check=True) + + print("[post_build] Copying afl-fuzz to $OUT directory") + + # Copy out the afl-fuzz binary as a build artifact. + shutil.copy("/path-afl/libpath_reduction.so", os.environ["OUT"]) + shutil.copy("/path-afl/afl-fuzz", os.environ["OUT"]) + shutil.copy("./top.bin", os.environ["OUT"]) + shutil.copy("/libpython3.8.so.1.0", os.environ["OUT"]) + src = "/usr/lib/llvm-17/lib" + dst = os.environ["OUT"] + shutil.copytree(src, dst, dirs_exist_ok=True) + + +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" + os.environ["CFG_BIN_FILE"] = "./top.bin" + os.environ["LD_LIBRARY_PATH"] = ( + f'./lib:{os.getcwd()}:{os.environ["LD_LIBRARY_PATH"]}') + + # 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. + 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. + ] + 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) + + os.environ["K"] = "42" + + run_afl_fuzz(input_corpus, output_corpus, target_binary) diff --git a/fuzzers/path_afl/runner.Dockerfile b/fuzzers/path_afl/runner.Dockerfile new file mode 100644 index 000000000..2b5dd351d --- /dev/null +++ b/fuzzers/path_afl/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 + +RUN apt-get update +RUN apt-get install -y python3.8 + +# 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 \ No newline at end of file diff --git a/service/gcbrun_experiment.py b/service/gcbrun_experiment.py index bbebcf1b9..5958aa60e 100644 --- a/service/gcbrun_experiment.py +++ b/service/gcbrun_experiment.py @@ -16,6 +16,8 @@ """Entrypoint for gcbrun into run_experiment. This script will get the command from the last PR comment containing "/gcbrun" and pass it to run_experiment.py which will run an experiment.""" +# a dummy comment! +# another dummy comment! import logging import os