[libFuzzer] start refactoring the Mutator and adding tests to it

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243817 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Kostya Serebryany 2015-08-01 01:42:51 +00:00
parent 8bf187c91f
commit 8d4c8061c9
5 changed files with 58 additions and 14 deletions

View File

@ -33,6 +33,8 @@ void CopyFileToErr(const std::string &Path);
std::string DirPlusFile(const std::string &DirPath,
const std::string &FileName);
size_t Mutate_EraseByte(uint8_t *Data, size_t size, size_t MaxSize,
FuzzerRandomBase &Rand);
size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize,
FuzzerRandomBase &Rand);

View File

@ -33,6 +33,16 @@ static char RandCh(FuzzerRandomBase &Rand) {
return Special[Rand(sizeof(Special) - 1)];
}
size_t Mutate_EraseByte(uint8_t *Data, size_t Size, size_t MaxSize,
FuzzerRandomBase &Rand) {
assert(Size);
if (Size == 1) return Size;
size_t Idx = Rand(Size);
// Erase Data[Idx].
memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1);
return Size - 1;
}
// Mutates Data in place, returns new size.
size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize,
FuzzerRandomBase &Rand) {
@ -46,13 +56,7 @@ size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize,
assert(Size > 0);
size_t Idx = Rand(Size);
switch (Rand(3)) {
case 0:
if (Size > 1) {
// Erase Data[Idx].
memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1);
Size = Size - 1;
}
[[clang::fallthrough]];
case 0: Size = Mutate_EraseByte(Data, Size, MaxSize, Rand); break;
case 1:
if (Size < MaxSize) {
// Insert new value at Data[Idx].

View File

@ -140,7 +140,7 @@ static bool ComputeCmp(size_t CmpSize, size_t CmpType, uint64_t Arg1,
if (CmpSize == 1) return ComputeCmp<uint8_t, int8_t>(CmpType, Arg1, Arg2);
// Other size, ==
if (CmpType == ICMP_EQ) return Arg1 == Arg2;
assert(0 && "unsupported cmp and type size combination");
// assert(0 && "unsupported cmp and type size combination");
return true;
}

View File

@ -2,6 +2,8 @@
#include "gtest/gtest.h"
#include <set>
using namespace fuzzer;
// For now, have LLVMFuzzerTestOneInput just to make it link.
// Later we may want to make unittests that actually call LLVMFuzzerTestOneInput.
extern "C" void LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
@ -9,7 +11,6 @@ extern "C" void LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
}
TEST(Fuzzer, CrossOver) {
using namespace fuzzer;
FuzzerRandomLibc Rand(0);
Unit A({0, 1, 2}), B({5, 6, 7});
Unit C;
@ -72,3 +73,36 @@ TEST(Fuzzer, Hash) {
U.push_back('d');
EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
}
typedef size_t (*Mutator)(uint8_t *Data, size_t Size, size_t MaxSize,
FuzzerRandomBase &Rand);
void TestEraseByte(Mutator M, int NumIter) {
uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
FuzzerRandomLibc Rand(0);
int FoundMask = 0;
for (int i = 0; i < NumIter; i++) {
uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
size_t NewSize = Mutate_EraseByte(T, sizeof(T), sizeof(T), Rand);
EXPECT_EQ(7UL, NewSize);
if (!memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
if (!memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
if (!memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
if (!memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
if (!memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
if (!memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
if (!memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
if (!memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
}
EXPECT_EQ(FoundMask, 255);
}
TEST(FuzzerMutate, EraseByte1) { TestEraseByte(Mutate_EraseByte, 50); }
TEST(FuzzerMutate, EraseByte2) { TestEraseByte(Mutate, 100); }

View File

@ -1,15 +1,19 @@
CHECK: BINGO
CHECK1: BINGO
CHECK2: BINGO
CHECK3: BINGO
CHECK4: BINGO
CHECK_DFSanCmpCallback: DFSanCmpCallback: PC
CHECK_DFSanSwitchCallback: DFSanSwitchCallback: PC
RUN: not LLVMFuzzer-SimpleCmpTest-DFSan -use_traces=1 -seed=1 -runs=1000000 -timeout=5 2>&1 | FileCheck %s
RUN: not LLVMFuzzer-SimpleCmpTest-DFSan -use_traces=1 -seed=1 -runs=1000000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK1
RUN: LLVMFuzzer-SimpleCmpTest-DFSan -use_traces=1 -seed=1 -runs=100 -timeout=5 -verbosity=3 2>&1 | FileCheck %s -check-prefix=CHECK_DFSanCmpCallback
RUN: not LLVMFuzzer-MemcmpTest-DFSan -use_traces=1 -seed=1 -runs=1000 -timeout=5 2>&1 | FileCheck %s
RUN: not LLVMFuzzer-MemcmpTest-DFSan -use_traces=1 -seed=1 -runs=1000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK2
RUN: LLVMFuzzer-MemcmpTest-DFSan -use_traces=1 -seed=1 -runs=2 -timeout=5 -verbosity=3 2>&1 | FileCheck %s -check-prefix=CHECK_DFSanCmpCallback
RUN: not LLVMFuzzer-StrncmpTest-DFSan -use_traces=1 -seed=1 -runs=10000 -timeout=5 2>&1 | FileCheck %s
RUN: not LLVMFuzzer-StrncmpTest-DFSan -use_traces=1 -seed=1 -runs=10000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK3
RUN: LLVMFuzzer-StrncmpTest-DFSan -use_traces=1 -seed=1 -runs=2 -timeout=5 -verbosity=3 2>&1 | FileCheck %s -check-prefix=CHECK_DFSanCmpCallback
RUN: not LLVMFuzzer-SwitchTest-DFSan -use_traces=1 -seed=1 -runs=10000 -timeout=5 2>&1 | FileCheck %s
RUN: not LLVMFuzzer-SwitchTest-DFSan -use_traces=1 -seed=1 -runs=100000 -timeout=5 2>&1 | FileCheck %s --check-prefix=CHECK4
RUN: LLVMFuzzer-SwitchTest-DFSan -use_traces=1 -seed=1 -runs=2 -timeout=5 -verbosity=3 2>&1 | FileCheck %s -check-prefix=CHECK_DFSanSwitchCallback