mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-13 17:00:01 +00:00
[libfuzzer] custom crossover interface function.
Differential Revision: http://reviews.llvm.org/D21089 llvm-svn: 272054
This commit is contained in:
parent
3b57eca787
commit
fa48306d58
@ -19,5 +19,10 @@ EXT_FUNC(LLVMFuzzerInitialize, int, (int *argc, char ***argv), false);
|
||||
EXT_FUNC(LLVMFuzzerCustomMutator, size_t,
|
||||
(uint8_t * Data, size_t Size, size_t MaxSize, unsigned int Seed),
|
||||
false);
|
||||
EXT_FUNC(LLVMFuzzerCustomCrossOver, size_t,
|
||||
(const uint8_t * Data1, size_t Size1,
|
||||
const uint8_t * Data2, size_t Size2,
|
||||
uint8_t * Out, size_t MaxOutSize, unsigned int Seed),
|
||||
false);
|
||||
|
||||
// TODO: Sanitizer functions
|
||||
|
@ -45,6 +45,15 @@ int LLVMFuzzerInitialize(int *argc, char ***argv);
|
||||
size_t LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize,
|
||||
unsigned int Seed);
|
||||
|
||||
// Optional user-provided custom cross-over function.
|
||||
// Combines pieces of Data1 & Data2 together into Out.
|
||||
// Returns the new size, which is not greater than MaxOutSize.
|
||||
// Should produce the same mutation given the same Seed.
|
||||
size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,
|
||||
const uint8_t *Data2, size_t Size2,
|
||||
uint8_t *Out, size_t MaxOutSize,
|
||||
unsigned int Seed);
|
||||
|
||||
// Experimental, may go away in future.
|
||||
// libFuzzer-provided function to be used inside LLVMFuzzerTestOneInput.
|
||||
// Mutates raw data in [Data, Data+Size) inplace.
|
||||
|
@ -215,6 +215,8 @@ public:
|
||||
void RecordSuccessfulMutationSequence();
|
||||
/// Mutates data by invoking user-provided mutator.
|
||||
size_t Mutate_Custom(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
/// Mutates data by invoking user-provided crossover.
|
||||
size_t Mutate_CustomCrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
/// Mutates data by shuffling bytes.
|
||||
size_t Mutate_ShuffleBytes(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
/// Mutates data by erasing a byte.
|
||||
|
@ -41,6 +41,10 @@ MutationDispatcher::MutationDispatcher(Random &Rand) : Rand(Rand) {
|
||||
Mutators.push_back({&MutationDispatcher::Mutate_Custom, "Custom"});
|
||||
else
|
||||
Mutators = DefaultMutators;
|
||||
|
||||
if (EF.LLVMFuzzerCustomCrossOver)
|
||||
Mutators.push_back(
|
||||
{&MutationDispatcher::Mutate_CustomCrossOver, "CustomCrossOver"});
|
||||
}
|
||||
|
||||
static char FlipRandomBit(char X, Random &Rand) {
|
||||
@ -66,6 +70,25 @@ size_t MutationDispatcher::Mutate_Custom(uint8_t *Data, size_t Size,
|
||||
return EF.LLVMFuzzerCustomMutator(Data, Size, MaxSize, Rand.Rand());
|
||||
}
|
||||
|
||||
size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size,
|
||||
size_t MaxSize) {
|
||||
if (!Corpus || Corpus->size() < 2 || Size == 0)
|
||||
return 0;
|
||||
size_t Idx = Rand(Corpus->size());
|
||||
const Unit &Other = (*Corpus)[Idx];
|
||||
if (Other.empty())
|
||||
return 0;
|
||||
MutateInPlaceHere.resize(MaxSize);
|
||||
auto &U = MutateInPlaceHere;
|
||||
size_t NewSize = EF.LLVMFuzzerCustomCrossOver(
|
||||
Data, Size, Other.data(), Other.size(), U.data(), U.size(), Rand.Rand());
|
||||
if (!NewSize)
|
||||
return 0;
|
||||
assert(NewSize <= MaxSize && "CustomCrossOver returned overisized unit");
|
||||
memcpy(Data, U.data(), NewSize);
|
||||
return NewSize;
|
||||
}
|
||||
|
||||
size_t MutationDispatcher::Mutate_ShuffleBytes(uint8_t *Data, size_t Size,
|
||||
size_t MaxSize) {
|
||||
assert(Size);
|
||||
|
@ -66,6 +66,7 @@ set(Tests
|
||||
BufferOverflowOnInput
|
||||
CallerCalleeTest
|
||||
CounterTest
|
||||
CustomCrossOverTest
|
||||
CustomMutatorTest
|
||||
EmptyTest
|
||||
FourIndependentBranchesTest
|
||||
|
57
lib/Fuzzer/test/CustomCrossOverTest.cpp
Normal file
57
lib/Fuzzer/test/CustomCrossOverTest.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
|
||||
// Simple test for a cutom mutator.
|
||||
#include <assert.h>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <string.h>
|
||||
|
||||
#include "FuzzerInterface.h"
|
||||
|
||||
static const char *Separator = "-_^_-";
|
||||
static const char *Target = "012-_^_-abc";
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
||||
assert(Data);
|
||||
std::string Str(reinterpret_cast<const char *>(Data), Size);
|
||||
|
||||
if (Str.find(Target) != std::string::npos) {
|
||||
std::cout << "BINGO; Found the target, exiting\n";
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,
|
||||
const uint8_t *Data2, size_t Size2,
|
||||
uint8_t *Out, size_t MaxOutSize,
|
||||
unsigned int Seed) {
|
||||
static bool Printed;
|
||||
static size_t SeparatorLen = strlen(Separator);
|
||||
|
||||
if (!Printed) {
|
||||
std::cerr << "In LLVMFuzzerCustomCrossover\n";
|
||||
Printed = true;
|
||||
}
|
||||
|
||||
std::mt19937 R(Seed);
|
||||
|
||||
size_t Offset1 = 0;
|
||||
size_t Len1 = R() % (Size1 - Offset1);
|
||||
size_t Offset2 = 0;
|
||||
size_t Len2 = R() % (Size2 - Offset2);
|
||||
size_t Size = Len1 + Len2 + SeparatorLen;
|
||||
|
||||
if (Size > MaxOutSize)
|
||||
return 0;
|
||||
|
||||
memcpy(Out, Data1 + Offset1, Len1);
|
||||
memcpy(Out + Len1, Separator, SeparatorLen);
|
||||
memcpy(Out + Len1 + SeparatorLen, Data2 + Offset2, Len2);
|
||||
|
||||
return Len1 + Len2 + SeparatorLen;
|
||||
}
|
10
lib/Fuzzer/test/fuzzer-customcrossover.test
Normal file
10
lib/Fuzzer/test/fuzzer-customcrossover.test
Normal file
@ -0,0 +1,10 @@
|
||||
RUN: rm -rf %t/CustomCrossover
|
||||
RUN: mkdir -p %t/CustomCrossover
|
||||
RUN: echo "0123456789" > %t/CustomCrossover/digits
|
||||
RUN: echo "abcdefghij" > %t/CustomCrossover/chars
|
||||
RUN: not LLVMFuzzer-CustomCrossOverTest -seed=1 -use_memcmp=0 -runs=100000 -prune_corpus=0 %t/CustomCrossover 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomCrossover
|
||||
RUN: rm -rf %t/CustomCrossover
|
||||
|
||||
LLVMFuzzerCustomCrossover: In LLVMFuzzerCustomCrossover
|
||||
LLVMFuzzerCustomCrossover: BINGO
|
||||
|
Loading…
x
Reference in New Issue
Block a user