-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
luzer: reserve and handoff ctrs to lf
Until now, luzer had not used at all coverage information for interpreted code. Hook-based instrumentation collected data, but it were never passed to libfuzzer to drew features from. Memory always were allocated in a fixed default kMax... size. This commit includes a fix to properly pass counters to libfuzzer, two systems to approximate optimal amount of 8-bit counters: one based on testing, pre-run phase, and one based on active bytecode size. Changes to signatures of counter functions help fix bugs with sign arithmetic. Also, a minor fix to signal handling and parameter name changes to evade name shadowing of global variables. Fixes #12
- Loading branch information
Showing
8 changed files
with
294 additions
and
41 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
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
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
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
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,91 @@ | ||
/* | ||
* SPDX-License-Identifier: ISC | ||
* | ||
*/ | ||
#include <vector> | ||
#include <string> | ||
#include <cstdint> | ||
/** | ||
* Okay, we all know this is bad, but unless we want to include third-party | ||
* headers or libs to do crossplatform IO (damn Windows cannot into readdir) | ||
* we better use whatever libfuzzer... shyly gives to us with no guarantees. | ||
* Remember - those things do not have ATTRIBUTE_INTERFACE in LF's codebase. | ||
* Bu-u-u-ut libfuzzer is pretty much in maintenance mode so I think it's | ||
* safe. | ||
* What's worse than using non-public-API is using C++. But this project already | ||
* uses clang++ with 'fuzzed_data_provider.cc'. Hey, libfuzzer IS written in C++. | ||
*/ | ||
|
||
extern "C" { | ||
#include "macros.h" | ||
|
||
int map_over_dir_contents(char const *dirpath, int (*user_cb)(uint8_t const *data, size_t length)); | ||
} | ||
|
||
/** | ||
* See links for source of this | ||
* https://github.com/llvm/llvm-project/blob/493cc71d72c471c841b490f30dd8f26f3a0d89de/compiler-rt/lib/fuzzer/FuzzerIO.cpp#L101 | ||
* https://github.com/llvm/llvm-project/blob/493cc71d72c471c841b490f30dd8f26f3a0d89de/compiler-rt/lib/fuzzer/FuzzerDefs.h#L41 | ||
*/ | ||
namespace fuzzer { | ||
#if __clang_major__ <= 13 | ||
template<typename T> | ||
class fuzzer_allocator: public std::allocator<T> { | ||
public: | ||
fuzzer_allocator() = default; | ||
|
||
template<class U> | ||
fuzzer_allocator(const fuzzer_allocator<U>&) {} | ||
|
||
template<class Other> | ||
struct rebind { typedef fuzzer_allocator<Other> other; }; | ||
}; | ||
|
||
template<typename T> | ||
using Vector = std::vector<T, fuzzer_allocator<T>>; | ||
#else // __clang_major__ <= 13 | ||
template<typename T> | ||
using Vector = std::vector<T>; | ||
#endif | ||
|
||
typedef Vector<uint8_t> Unit; | ||
|
||
void ReadDirToVectorOfUnits( | ||
const char *Path, | ||
Vector<Unit> *V, | ||
long *Epoch, | ||
size_t MaxSize, | ||
bool ExitOnError, | ||
Vector<std::string> *VPaths = 0 | ||
); | ||
|
||
bool IsDirectory(const std::string &Path); | ||
} | ||
|
||
NO_SANITIZE int | ||
map_over_dir_contents(char const *dirpath, int (*user_cb)(uint8_t const * data, size_t length)) | ||
{ | ||
if (nullptr == user_cb || nullptr == dirpath) { | ||
return -1; | ||
} | ||
|
||
if (!fuzzer::IsDirectory(dirpath)) { | ||
return -2; | ||
} | ||
|
||
fuzzer::Vector<fuzzer::Unit> seed_corpus; | ||
|
||
fuzzer::ReadDirToVectorOfUnits( | ||
dirpath, | ||
&seed_corpus, | ||
/*Epoch = */nullptr, | ||
/*MaxSize = */SIZE_MAX, | ||
/*ExitOnError = */false, | ||
/*VPaths = */nullptr | ||
); | ||
|
||
for (auto unit : seed_corpus) { | ||
user_cb(unit.data(), unit.size()); | ||
} | ||
return 0; | ||
} |
Oops, something went wrong.