Skip to content

Commit

Permalink
Configurable maximum sample size
Browse files Browse the repository at this point in the history
  • Loading branch information
ifratric committed Dec 1, 2021
1 parent 4781bdf commit 6e49460
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 18 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ The following command line arguments are supported:

`-deterministic_only` - Prioritize deterministic mutations. Note: even with this flag, the fuzzer is still going to use nondeterministic mutations, but only after all deterministic mutations have been exhausted. It might be useful when running with a `-server` to have a single clinent instance perform deterministic mutations.

`-max_sample_size` - The maximum sample size to use. All input samples larger than `max_sample_size` get trimmed and mutators can't produce new samples which exceed that sie. Defaults to 1000000. Warning: When using shared memory sample delivery, `max_sample_size` must match the maximum sample size expected by the target, e.g. like in the test target [here](https://github.com/googleprojectzero/Jackalope/blob/3301a9ac6c6f1483f2d565d372015302e85e6ae2/test.cpp#L33).

`-keep_samples_in_memory` - Whether to always keep all samples in memory. Defaults to true. Recommended unless the corpus is too large to fit in memory.

`-track_ranges` - Enable the read range tracking feature. More information [here](https://github.com/googleprojectzero/Jackalope/blob/main/README_ranges.md).
Expand Down
10 changes: 6 additions & 4 deletions fuzzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ void Fuzzer::ParseOptions(int argc, char **argv) {
keep_samples_in_memory = GetBinaryOption("-keep_samples_in_memory", argc, argv, true);

track_ranges = GetBinaryOption("-track_ranges", argc, argv, false);

Sample::max_size = (size_t)GetIntOption("-max_sample_size", argc, argv, DEFAULT_MAX_SAMPLE_SIZE);
}

void Fuzzer::SetupDirectories() {
Expand Down Expand Up @@ -613,9 +615,9 @@ void Fuzzer::SynchronizeAndGetJob(ThreadContext* tc, FuzzerJob* job) {
printf("Running input sample %s\n", filename.c_str());
job->sample = new Sample();
job->sample->Load(filename.c_str());
if (job->sample->size > MAX_SAMPLE_SIZE) {
if (job->sample->size > Sample::max_size) {
WARN("Input sample larger than maximum sample size. Will be trimmed");
job->sample->Trim(MAX_SAMPLE_SIZE);
job->sample->Trim(Sample::max_size);
}
samples_pending++;
}
Expand Down Expand Up @@ -678,7 +680,7 @@ void Fuzzer::FuzzJob(ThreadContext* tc, FuzzerJob* job) {
while (1) {
Sample mutated_sample = *entry->sample;
if (!tc->mutator->Mutate(&mutated_sample, tc->prng, tc->all_samples_local)) break;
if (mutated_sample.size > MAX_SAMPLE_SIZE) {
if (mutated_sample.size > Sample::max_size) {
continue;
}

Expand Down Expand Up @@ -925,7 +927,7 @@ SampleDelivery *Fuzzer::CreateSampleDelivery(int argc, char **argv, ThreadContex
#endif
ReplaceTargetCmdArg(tc, "@@", shm_name.c_str());

SHMSampleDelivery* sampleDelivery = new SHMSampleDelivery((char*)shm_name.c_str(), MAX_SAMPLE_SIZE + 4);
SHMSampleDelivery* sampleDelivery = new SHMSampleDelivery((char*)shm_name.c_str(), Sample::max_size + 4);
sampleDelivery->Init(argc, argv);
return sampleDelivery;
} else {
Expand Down
26 changes: 13 additions & 13 deletions mutator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,10 @@ bool BlockFlipMutator::Mutate(Sample *inout_sample, PRNG *prng, std::vector<Samp
bool AppendMutator::Mutate(Sample *inout_sample, PRNG *prng, std::vector<Sample *> &all_samples) {
// printf("In AppendMutator::Mutate\n");
size_t old_size = inout_sample->size;
if (old_size >= MAX_SAMPLE_SIZE) return true;
if (old_size >= Sample::max_size) return true;
size_t append = prng->Rand(min_append, max_append);
if ((old_size + append) > MAX_SAMPLE_SIZE) {
append = MAX_SAMPLE_SIZE - old_size;
if ((old_size + append) > Sample::max_size) {
append = Sample::max_size - old_size;
}
if (append <= 0) return true;
size_t new_size = old_size + append;
Expand All @@ -114,10 +114,10 @@ bool AppendMutator::Mutate(Sample *inout_sample, PRNG *prng, std::vector<Sample
bool BlockInsertMutator::Mutate(Sample *inout_sample, PRNG *prng, std::vector<Sample *> &all_samples) {
// printf("In BlockInsertMutator::Mutate\n");
size_t old_size = inout_sample->size;
if (old_size >= MAX_SAMPLE_SIZE) return true;
if (old_size >= Sample::max_size) return true;
size_t to_insert = prng->Rand(min_insert, max_insert);
if ((old_size + to_insert) > MAX_SAMPLE_SIZE) {
to_insert = MAX_SAMPLE_SIZE - old_size;
if ((old_size + to_insert) > Sample::max_size) {
to_insert = Sample::max_size - old_size;
}
size_t where = prng->Rand(0, (int)old_size);
size_t new_size = old_size + to_insert;
Expand All @@ -141,12 +141,12 @@ bool BlockInsertMutator::Mutate(Sample *inout_sample, PRNG *prng, std::vector<Sa

bool BlockDuplicateMutator::Mutate(Sample *inout_sample, PRNG *prng, std::vector<Sample *> &all_samples) {
// printf("In BlockDuplicateMutator::Mutate\n");
if (inout_sample->size >= MAX_SAMPLE_SIZE) return true;
if (inout_sample->size >= Sample::max_size) return true;
size_t blockpos, blocksize;
if (!GetRandBlock(inout_sample->size, min_block_size, max_block_size, &blockpos, &blocksize, prng)) return true;
int64_t blockcount = prng->Rand(min_duplicate_cnt, max_duplicate_cnt);
if ((inout_sample->size + blockcount * blocksize) > MAX_SAMPLE_SIZE)
blockcount = (MAX_SAMPLE_SIZE - (int64_t)inout_sample->size) / blocksize;
if ((inout_sample->size + blockcount * blocksize) > Sample::max_size)
blockcount = (Sample::max_size - (int64_t)inout_sample->size) / blocksize;
if (blockcount <= 0) return true;
char *newbytes;
newbytes = (char *)malloc(inout_sample->size + blockcount * blocksize);
Expand Down Expand Up @@ -260,7 +260,7 @@ bool SpliceMutator::Mutate(Sample *inout_sample, PRNG *prng, std::vector<Sample
free(inout_sample->bytes);
inout_sample->bytes = new_bytes;
inout_sample->size = new_sample_size;
if (inout_sample->size > MAX_SAMPLE_SIZE) inout_sample->Trim(MAX_SAMPLE_SIZE);
if (inout_sample->size > Sample::max_size) inout_sample->Trim(Sample::max_size);
return true;
}
} else if(points != 2) {
Expand All @@ -280,9 +280,9 @@ bool SpliceMutator::Mutate(Sample *inout_sample, PRNG *prng, std::vector<Sample
memcpy(new_bytes, inout_sample->bytes, blockstart1);
memcpy(new_bytes + blockstart1, other_sample->bytes + blockstart2, blocksize2);
memcpy(new_bytes + blockstart1 + blocksize2, inout_sample->bytes + blockstart3, blocksize3);
if(new_sample_size > MAX_SAMPLE_SIZE) {
new_sample_size = MAX_SAMPLE_SIZE;
new_bytes = (char *)realloc(new_bytes, MAX_SAMPLE_SIZE);
if(new_sample_size > Sample::max_size) {
new_sample_size = Sample::max_size;
new_bytes = (char *)realloc(new_bytes, Sample::max_size);
}
free(inout_sample->bytes);
inout_sample->bytes = new_bytes;
Expand Down
2 changes: 2 additions & 0 deletions sample.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ limitations under the License.
#include "sample.h"
#include "mutex.h"

size_t Sample::max_size = DEFAULT_MAX_SAMPLE_SIZE;

Sample::Sample() {
size = 0;
bytes = NULL;
Expand Down
4 changes: 3 additions & 1 deletion sample.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ limitations under the License.

#include "mutex.h"

#define MAX_SAMPLE_SIZE 1000000
#define DEFAULT_MAX_SAMPLE_SIZE 1000000

class Sample {
public:
Expand Down Expand Up @@ -61,6 +61,8 @@ class Sample {
void Crop(size_t from, size_t to, Sample* out);

size_t FindFirstDiff(Sample &other);

static size_t max_size;
};

// a Trie-like structure whose purpose is to be able to
Expand Down

0 comments on commit 6e49460

Please sign in to comment.