-
Notifications
You must be signed in to change notification settings - Fork 275
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
243 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 <queue> | ||
#include <sstream> | ||
#include <thread> | ||
+#include <sys/stat.h> | ||
+#include <iostream> | ||
|
||
namespace fuzzer { | ||
|
||
@@ -70,6 +72,8 @@ struct FuzzJob { | ||
std::string SeedListPath; | ||
std::string CFPath; | ||
size_t JobId; | ||
+ bool Executing = false; | ||
+ Vector<std::string> 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<uint32_t> 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<std::thread> 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++)); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |