-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
luzer: reserve and handoff ctrs to lf #16
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,15 +22,15 @@ void __sanitizer_cov_pcs_init(uint8_t* pcs_beg, uint8_t* pcs_end); | |
} /* extern "C" */ | ||
#endif | ||
|
||
static const int kDefaultNumCounters = 1 << 20; | ||
static const size_t kDefaultNumCounters = 1 << 20; | ||
|
||
// Number of counters requested by Lua instrumentation. | ||
int counter_index = 0; | ||
size_t counter_index = 0; | ||
// Number of counters given to Libfuzzer. | ||
Comment on lines
-28
to
29
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would split this commit to a number of commits:
|
||
int counter_index_registered = 0; | ||
size_t counter_index_registered = 0; | ||
// Maximum number of counters and pctable entries that may be reserved and also | ||
// the number that are allocated. | ||
int max_counters = 0; | ||
size_t max_counters = 0; | ||
// Counter Allocations. These are allocated once, before __sanitize_... are | ||
// called and can only be deallocated by test_only_reset_counters. | ||
unsigned char* counters = NULL; | ||
|
@@ -51,32 +51,34 @@ test_only_reset_counters(void) { | |
counter_index_registered = 0; | ||
} | ||
|
||
NO_SANITIZE int | ||
reserve_counters(int counters) { | ||
NO_SANITIZE size_t | ||
reserve_counters(size_t amount) { | ||
int ret = counter_index; | ||
counter_index += counters; | ||
counter_index += amount; | ||
return ret; | ||
} | ||
|
||
NO_SANITIZE int | ||
NO_SANITIZE size_t | ||
reserve_counter(void) | ||
{ | ||
return counter_index++; | ||
} | ||
|
||
NO_SANITIZE void | ||
increment_counter(int counter_index) | ||
increment_counter(size_t index) | ||
{ | ||
if (counters != NULL && pctable != NULL) { | ||
// `counters` is an allocation of length `max_counters`. If we reserve more | ||
// than the allocated number of counters, we'll wrap around and overload | ||
// old counters, trading away fuzzing quality for limits on memory usage. | ||
counters[counter_index % max_counters]++; | ||
if (counters != NULL) { | ||
// Global array `counters` is an allocation of length `max_counters`. | ||
// But we use only registered amount of them. | ||
// If we reserve more than the allocated number of counters, we'll wrap | ||
// around and overload old counters, trading away fuzzing quality | ||
// for limits on memory usage. | ||
counters[index % counter_index_registered]++; | ||
} | ||
} | ||
|
||
NO_SANITIZE void | ||
set_max_counters(int max) | ||
set_max_counters(size_t max) | ||
{ | ||
if (counters != NULL && pctable != NULL) { | ||
fprintf(stderr, "Internal error: attempt to set max number of counters after " | ||
|
@@ -89,7 +91,7 @@ set_max_counters(int max) | |
max_counters = max; | ||
} | ||
|
||
NO_SANITIZE int | ||
NO_SANITIZE size_t | ||
get_max_counters(void) | ||
{ | ||
return max_counters; | ||
|
@@ -122,7 +124,7 @@ allocate_counters_and_pcs(void) { | |
} | ||
} | ||
|
||
const int next_index = MIN(counter_index, max_counters); | ||
const size_t next_index = MIN(counter_index, max_counters); | ||
if (counter_index_registered >= next_index) { | ||
// There are no counters to pass. Perhaps because we've reserved more than | ||
// max_counters, or because no counters have been reserved since this was | ||
|
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++. | ||
Comment on lines
+15
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like the approach. Please rewrite to C. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would you be okay with C-binding-to-a-mangled-Cpp-symbol-of-libfuzzer or do you mean "write new, non-libfuzzer IO code in C without using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I would prefer a plain C variant, but C-binding-to-a-mangled-Cpp-symbol-of-libfuzzer would be okay too. |
||
*/ | ||
|
||
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 | ||
Comment on lines
+81
to
+84
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dead code There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How so? They are not optional arguments, and this function call is the most important thing in this file. Do you mean inline-commented argument names? This is for readability. Should I remove them? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sorry, overlooked a real code due to non-usual comment style.
I would rewrite it to: fuzzer::ReadDirToVectorOfUnits(
dirpath,
&seed_corpus,
/*Epoch */
nullptr,
/*MaxSize */
SIZE_MAX,
/*ExitOnError */
false,
/*VPaths */
nullptr
}; to avoid confusion. /*
* void ReadDirToVectorOfUnits(const char *Path, std::vector<Unit> *V,
* long *Epoch, size_t MaxSize, bool ExitOnError);
*/ |
||
); | ||
|
||
for (auto unit : seed_corpus) { | ||
user_cb(unit.data(), unit.size()); | ||
} | ||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One commit - one changelog entry, please