Skip to content

Commit bf29d77

Browse files
author
R. Elliott Childre
committed
Update libfuzzer code to compiler-rt 18
Update the LLVM compiler-rt C++ code to the top of the 18.x branch The summary of the changes from compiler-rt 15 (the last time this code was updated) are: 1. Improvements to Ctrl+C detection and closing out of a fuzzing session 2. Loop optimizations, in preventing copy operations 3. Dynamic pagesize detection 4. Setting Worker thread names (on Linux) 5. Use of a bitset data structure to track rarity of features "improves fuzzer throughput rather dramatically (close to 2x) in early exploratory phases" The LLVM commits which make up the changes in this commit come from the squash of the following LLVM commits: ```sh git log --format=reference origin/release/15.x..release/18.x -- compiler-rt/lib/fuzzer/ ``` ``` 3747cde5e84f ([Fuzzer] Enable custom libc++ for Android (#70407), 2023-11-02) 747e0d9f0aad ([compiler-rt] Use std::clamp (NFC), 2023-10-22) bede46f57eec ([Fuzzer] Optimize UpdateFeatureFrequency (#65288), 2023-09-07) d3440304b110 ([Fuzzer] Update build.sh to fix build errors (#65496), 2023-09-07) dd3aa26fc8e9 (Revert "[Fuzzer] SetThreadName implementation for Windows", 2023-08-28) 151e33c768a6 ([NFC][fuzzer] Cleanup SetThreadName after D156317, 2023-08-28) 45eb6026d979 ([fuzzer] Try to fix windows build after D156317, 2023-08-28) e0e8695a608f (Revert "[fuzzer] Try to fix windows build after D156317", 2023-08-28) d364597f8a47 ([fuzzer] Try to fix windows build after D156317, 2023-08-28) cf76ddcbeb10 ([Fuzzer] SetThreadName implementation for Windows, 2023-08-28) 52526065bc80 ([NFC][compiler-rt] Add missing space in libfuzzer -help docs, 2023-07-28) cb924ddca514 (Revert "[Fuzzer] SetThreadName implementation for Windows", 2023-07-28) 885275bff215 ([Fuzzer] SetThreadName implementation for Windows, 2023-07-27) f4aa7b5b8d90 (Revert "[Fuzzer] SetThreadName implementation for Windows", 2023-07-27) e3f935c7f80c ([Fuzzer] SetThreadName implementation for Windows, 2023-07-27) b2a253855f4e ([Fuzzer] Assign names to workers, 2023-07-26) 9c2f792dceb6 ([fuzzer] Enable loongarch64, 2023-07-18) 42564f97e8ca ([fuzzer][fuchsia] Support RISC-V, 2023-06-15) facf22b8b07b ([fuzzer] Platfom specific version of PageSize, 2023-05-25) baa1488c1693 ([fuzzer] Don't hard-code page size in FuzzerUtil.h, 2023-05-25) cb9f2de2e802 (Revert "[fuzzer] Don't hard-code page size in FuzzerUtil.h", 2023-05-25) a2b677e81537 ([fuzzer] Don't hard-code page size in FuzzerUtil.h, 2023-05-25) f98ee40f4b5d ([NFC][Py Reformat] Reformat python files in the rest of the dirs, 2023-05-17) cdfcf1aa38a4 ([libfuzzer] avoid unneccessary auto-copy, 2023-04-26) 8a986abe98ff ([fuzzer] Fix -Wunreachable-code-aggressive warning in FuzzerDriver.cpp, 2023-04-11) f2c9d24e8c8d ([compiler-rt] [test] [fuzzer] Don't pass msvc/clang-cl specific flags to mingw tools, 2023-03-31) 90b4d1bcb201 ([fuzzer] Use puts() rather than printf() in CopyFileToErr(), 2023-03-15) c2df1d8a6d1c ([libfuzzer] add test of cov file-id in control file, 2023-03-22) d02ff3d57831 (Revert "[fuzzer] Use puts() rather than printf() in CopyFileToErr()", 2023-03-17) 03aa02adb03c ([fuzzer] Use puts() rather than printf() in CopyFileToErr(), 2023-03-15) 0b327814d86c ([libfuzzer] Fix build error due to out-of-line definition of 'Fuzzer' does not match any declaration in 'fuzzer::Fuzzer' (NFC), 2023-03-10) 513d9b9f3d67 ([libfuzzer] avoid unneccessary copy, 2023-03-09) e09b3be411b0 ([fuzzer] Make sure we never delete Fuzzer, 2023-03-07) 67f5b05cdcdc (Add test for Flags.data_flow_trace, 2023-03-07) 91985c2ee3b3 (Use the right printf format specifiers, 2023-03-07) 6c485409de52 (Adding missing colon, 2023-01-19) beb3fa2d2efb (Revert "Reland "[compiler-rt][test] Heed COMPILER_RT_DEBUG when compiling unittests"", 2022-12-13) 255c3e3dcb06 (Reland "[compiler-rt][test] Heed COMPILER_RT_DEBUG when compiling unittests", 2022-12-13) 68f4ceaf9b4e (Revert "[compiler-rt][test] Heed COMPILER_RT_DEBUG when compiling unittests", 2022-10-05) 93b1256e38f6 ([compiler-rt][test] Heed COMPILER_RT_DEBUG when compiling unittests, 2022-10-05) 98c2754abd8f ([Libfuzzer] Include signal.h for SIGINT, 2022-09-04) aa0e9046c16b (Libfuzzer fix for Ctrl + c not working with -fork and -ignore_crashes=1, 2022-08-15) ```
1 parent 9b8c0a7 commit bf29d77

24 files changed

+226
-104
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Released YYYY-MM-DD.
99

1010
### Changed
1111

12-
* TODO (or remove section if none)
12+
* Updated to `libFuzzer` commit `3747cde5e84f` (`release/18.x`).
1313

1414
### Deprecated
1515

libfuzzer/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ CHECK_CXX_SOURCE_COMPILES("
5959

6060
set(LIBFUZZER_CFLAGS ${COMPILER_RT_COMMON_CFLAGS})
6161

62-
if(OS_NAME MATCHES "Linux|Fuchsia" AND
62+
if(OS_NAME MATCHES "Android|Linux|Fuchsia" AND
6363
COMPILER_RT_LIBCXX_PATH AND
6464
COMPILER_RT_LIBCXXABI_PATH)
6565
list(APPEND LIBFUZZER_CFLAGS -D_LIBCPP_ABI_VERSION=Fuzzer)
@@ -135,7 +135,7 @@ add_compiler_rt_runtime(clang_rt.fuzzer_interceptors
135135
CFLAGS ${LIBFUZZER_CFLAGS}
136136
PARENT_TARGET fuzzer)
137137

138-
if(OS_NAME MATCHES "Linux|Fuchsia" AND
138+
if(OS_NAME MATCHES "Android|Linux|Fuchsia" AND
139139
COMPILER_RT_LIBCXX_PATH AND
140140
COMPILER_RT_LIBCXXABI_PATH)
141141
macro(partially_link_libcxx name dir arch)

libfuzzer/FuzzerCommand.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <sstream>
2020
#include <string>
2121
#include <vector>
22+
#include <thread>
2223

2324
namespace fuzzer {
2425

@@ -139,7 +140,7 @@ class Command final {
139140
// be the equivalent command line.
140141
std::string toString() const {
141142
std::stringstream SS;
142-
for (auto arg : getArguments())
143+
for (const auto &arg : getArguments())
143144
SS << arg << " ";
144145
if (hasOutputFile())
145146
SS << ">" << getOutputFile() << " ";

libfuzzer/FuzzerCorpus.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "FuzzerSHA1.h"
1919
#include "FuzzerTracePC.h"
2020
#include <algorithm>
21+
#include <bitset>
2122
#include <chrono>
2223
#include <numeric>
2324
#include <random>
@@ -77,7 +78,7 @@ struct InputInfo {
7778
SumIncidence = 0.0;
7879

7980
// Apply add-one smoothing to locally discovered features.
80-
for (auto F : FeatureFreqs) {
81+
for (const auto &F : FeatureFreqs) {
8182
double LocalIncidence = F.second + 1;
8283
Energy -= LocalIncidence * log(LocalIncidence);
8384
SumIncidence += LocalIncidence;
@@ -382,6 +383,7 @@ class InputCorpus {
382383
}
383384

384385
// Remove most abundant rare feature.
386+
IsRareFeature[Delete] = false;
385387
RareFeatures[Delete] = RareFeatures.back();
386388
RareFeatures.pop_back();
387389

@@ -397,6 +399,7 @@ class InputCorpus {
397399

398400
// Add rare feature, handle collisions, and update energy.
399401
RareFeatures.push_back(Idx);
402+
IsRareFeature[Idx] = true;
400403
GlobalFeatureFreqs[Idx] = 0;
401404
for (auto II : Inputs) {
402405
II->DeleteFeatureFreq(Idx);
@@ -450,9 +453,7 @@ class InputCorpus {
450453
uint16_t Freq = GlobalFeatureFreqs[Idx32]++;
451454

452455
// Skip if abundant.
453-
if (Freq > FreqOfMostAbundantRareFeature ||
454-
std::find(RareFeatures.begin(), RareFeatures.end(), Idx32) ==
455-
RareFeatures.end())
456+
if (Freq > FreqOfMostAbundantRareFeature || !IsRareFeature[Idx32])
456457
return;
457458

458459
// Update global frequencies.
@@ -581,6 +582,7 @@ class InputCorpus {
581582
uint16_t FreqOfMostAbundantRareFeature = 0;
582583
uint16_t GlobalFeatureFreqs[kFeatureSetSize] = {};
583584
std::vector<uint32_t> RareFeatures;
585+
std::bitset<kFeatureSetSize> IsRareFeature;
584586

585587
std::string OutputCorpus;
586588
};

libfuzzer/FuzzerDataFlowTrace.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ bool BlockCoverage::AppendCoverage(std::istream &IN) {
8888
// * a function with a less frequently executed code gets bigger weight.
8989
std::vector<double> BlockCoverage::FunctionWeights(size_t NumFunctions) const {
9090
std::vector<double> Res(NumFunctions);
91-
for (auto It : Functions) {
91+
for (const auto &It : Functions) {
9292
auto FunctionID = It.first;
9393
auto Counters = It.second;
9494
assert(FunctionID < NumFunctions);

libfuzzer/FuzzerDriver.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,12 @@ static int RunInMultipleProcesses(const std::vector<std::string> &Args,
293293
std::vector<std::thread> V;
294294
std::thread Pulse(PulseThread);
295295
Pulse.detach();
296-
for (unsigned i = 0; i < NumWorkers; i++)
297-
V.push_back(std::thread(WorkerThread, std::ref(Cmd), &Counter, NumJobs,
298-
&HasErrors));
296+
V.resize(NumWorkers);
297+
for (unsigned i = 0; i < NumWorkers; i++) {
298+
V[i] = std::thread(WorkerThread, std::ref(Cmd), &Counter, NumJobs,
299+
&HasErrors);
300+
SetThreadName(V[i], "FuzzerWorker");
301+
}
299302
for (auto &T : V)
300303
T.join();
301304
return HasErrors ? 1 : 0;
@@ -463,7 +466,7 @@ int MinimizeCrashInput(const std::vector<std::string> &Args,
463466
CurrentFilePath = Flags.exact_artifact_path;
464467
WriteToFile(U, CurrentFilePath);
465468
}
466-
Printf("CRASH_MIN: failed to minimize beyond %s (%d bytes), exiting\n",
469+
Printf("CRASH_MIN: failed to minimize beyond %s (%zu bytes), exiting\n",
467470
CurrentFilePath.c_str(), U.size());
468471
break;
469472
}
@@ -501,7 +504,6 @@ int MinimizeCrashInputInternalStep(Fuzzer *F, InputCorpus *Corpus) {
501504
F->MinimizeCrashLoop(U);
502505
Printf("INFO: Done MinimizeCrashInputInternalStep, no crashes found\n");
503506
exit(0);
504-
return 0;
505507
}
506508

507509
void Merge(Fuzzer *F, FuzzingOptions &Options,
@@ -535,7 +537,7 @@ void Merge(Fuzzer *F, FuzzingOptions &Options,
535537

536538
int AnalyzeDictionary(Fuzzer *F, const std::vector<Unit> &Dict,
537539
UnitVector &Corpus) {
538-
Printf("Started dictionary minimization (up to %d tests)\n",
540+
Printf("Started dictionary minimization (up to %zu tests)\n",
539541
Dict.size() * Corpus.size() * 2);
540542

541543
// Scores and usage count for each dictionary unit.
@@ -779,7 +781,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
779781
if (!Options.FocusFunction.empty())
780782
Options.Entropic = false; // FocusFunction overrides entropic scheduling.
781783
if (Options.Entropic)
782-
Printf("INFO: Running with entropic power schedule (0x%X, %d).\n",
784+
Printf("INFO: Running with entropic power schedule (0x%zX, %zu).\n",
783785
Options.EntropicFeatureFrequencyThreshold,
784786
Options.EntropicNumberOfRarestFeatures);
785787
struct EntropicOptions Entropic;
@@ -797,7 +799,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
797799
if (Flags.verbosity)
798800
Printf("INFO: Seed: %u\n", Seed);
799801

800-
if (Flags.collect_data_flow && !Flags.fork &&
802+
if (Flags.collect_data_flow && Flags.data_flow_trace && !Flags.fork &&
801803
!(Flags.merge || Flags.set_cover_merge)) {
802804
if (RunIndividualFiles)
803805
return CollectDataFlow(Flags.collect_data_flow, Flags.data_flow_trace,
@@ -860,7 +862,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
860862
RunOneTest(F, Path.c_str(), Options.MaxLen);
861863
auto StopTime = system_clock::now();
862864
auto MS = duration_cast<milliseconds>(StopTime - StartTime).count();
863-
Printf("Executed %s in %zd ms\n", Path.c_str(), (long)MS);
865+
Printf("Executed %s in %ld ms\n", Path.c_str(), (long)MS);
864866
}
865867
Printf("***\n"
866868
"*** NOTE: fuzzing was not performed, you have only\n"

libfuzzer/FuzzerFlags.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ FUZZER_FLAG_INT(purge_allocator_interval, 1, "Purge allocator caches and "
167167
"purge_allocator_interval=-1 to disable this functionality.")
168168
FUZZER_FLAG_INT(trace_malloc, 0, "If >= 1 will print all mallocs/frees. "
169169
"If >= 2 will also print stack traces.")
170-
FUZZER_FLAG_INT(rss_limit_mb, 2048, "If non-zero, the fuzzer will exit upon"
170+
FUZZER_FLAG_INT(rss_limit_mb, 2048, "If non-zero, the fuzzer will exit upon "
171171
"reaching this limit of RSS memory usage.")
172172
FUZZER_FLAG_INT(malloc_limit_mb, 0, "If non-zero, the fuzzer will exit "
173173
"if the target tries to allocate this number of Mb with one malloc call. "

libfuzzer/FuzzerFork.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ struct GlobalEnv {
220220
}
221221
}
222222
// if (!FilesToAdd.empty() || Job->ExitCode != 0)
223-
Printf("#%zd: cov: %zd ft: %zd corp: %zd exec/s %zd "
223+
Printf("#%zd: cov: %zd ft: %zd corp: %zd exec/s: %zd "
224224
"oom/timeout/crash: %zd/%zd/%zd time: %zds job: %zd dft_time: %d\n",
225225
NumRuns, Cov.size(), Features.size(), Files.size(),
226226
Stats.average_exec_per_sec, NumOOMs, NumTimeouts, NumCrashes,

libfuzzer/FuzzerIO.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ std::string FileToString(const std::string &Path) {
6565
}
6666

6767
void CopyFileToErr(const std::string &Path) {
68-
Printf("%s", FileToString(Path).c_str());
68+
Puts(FileToString(Path).c_str());
6969
}
7070

7171
void WriteToFile(const Unit &U, const std::string &Path) {
@@ -151,6 +151,11 @@ void CloseStdout() {
151151
DiscardOutput(1);
152152
}
153153

154+
void Puts(const char *Str) {
155+
fputs(Str, OutputFile);
156+
fflush(OutputFile);
157+
}
158+
154159
void Printf(const char *Fmt, ...) {
155160
va_list ap;
156161
va_start(ap, Fmt);

libfuzzer/FuzzerIO.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ void CloseStdout();
5858
FILE *GetOutputFile();
5959
void SetOutputFile(FILE *NewOutputFile);
6060

61+
void Puts(const char *Str);
6162
void Printf(const char *Fmt, ...);
6263
void VPrintf(bool Verbose, const char *Fmt, ...);
6364

0 commit comments

Comments
 (0)