mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-23 20:44:51 +00:00
[libFuzzer] one more mutation: ChangeBinaryInteger; also fix the breakage from r278970
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278982 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
0a6e4fd5d3
commit
9744bb48e4
@ -290,6 +290,8 @@ public:
|
||||
|
||||
/// Tries to find an ASCII integer in Data, changes it to another ASCII int.
|
||||
size_t Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
/// Change a 1-, 2-, 4-, or 8-byte integer in interesting ways.
|
||||
size_t Mutate_ChangeBinaryInteger(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
|
||||
/// CrossOver Data with some other element of the corpus.
|
||||
size_t Mutate_CrossOver(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
|
@ -32,6 +32,7 @@ MutationDispatcher::MutationDispatcher(Random &Rand,
|
||||
{&MutationDispatcher::Mutate_ChangeBit, "ChangeBit"},
|
||||
{&MutationDispatcher::Mutate_ShuffleBytes, "ShuffleBytes"},
|
||||
{&MutationDispatcher::Mutate_ChangeASCIIInteger, "ChangeASCIIInt"},
|
||||
{&MutationDispatcher::Mutate_ChangeBinaryInteger, "ChangeBinInt"},
|
||||
{&MutationDispatcher::Mutate_CopyPart, "CopyPart"},
|
||||
{&MutationDispatcher::Mutate_CrossOver, "CrossOver"},
|
||||
{&MutationDispatcher::Mutate_AddWordFromManualDictionary,
|
||||
@ -269,6 +270,42 @@ size_t MutationDispatcher::Mutate_ChangeASCIIInteger(uint8_t *Data, size_t Size,
|
||||
return Size;
|
||||
}
|
||||
|
||||
uint8_t Bswap(uint8_t x) { return x; }
|
||||
uint16_t Bswap(uint16_t x) { return __builtin_bswap16(x); }
|
||||
uint32_t Bswap(uint32_t x) { return __builtin_bswap32(x); }
|
||||
uint64_t Bswap(uint64_t x) { return __builtin_bswap64(x); }
|
||||
|
||||
template<class T>
|
||||
size_t ChangeBinaryInteger(uint8_t *Data, size_t Size, Random &Rand) {
|
||||
if (Size < sizeof(T)) return 0;
|
||||
size_t Off = Rand(Size - sizeof(T) + 1);
|
||||
assert(Off + sizeof(T) <= Size);
|
||||
T Val;
|
||||
memcpy(&Val, Data + Off, sizeof(Val));
|
||||
T Add = Rand(21);
|
||||
Add -= 10;
|
||||
if (Rand.RandBool())
|
||||
Val = Bswap(T(Bswap(Val) + Add)); // Add assuming different endiannes.
|
||||
else
|
||||
Val = Val + Add; // Add assuming current endiannes.
|
||||
if (Add == 0 || Rand.RandBool()) // Maybe negate.
|
||||
Val = -Val;
|
||||
memcpy(Data + Off, &Val, sizeof(Val));
|
||||
return Size;
|
||||
}
|
||||
|
||||
size_t MutationDispatcher::Mutate_ChangeBinaryInteger(uint8_t *Data,
|
||||
size_t Size,
|
||||
size_t MaxSize) {
|
||||
switch (Rand(4)) {
|
||||
case 3: return ChangeBinaryInteger<uint64_t>(Data, Size, Rand);
|
||||
case 2: return ChangeBinaryInteger<uint32_t>(Data, Size, Rand);
|
||||
case 1: return ChangeBinaryInteger<uint16_t>(Data, Size, Rand);
|
||||
case 0: return ChangeBinaryInteger<uint8_t>(Data, Size, Rand);
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
|
||||
size_t MaxSize) {
|
||||
if (!Corpus || Corpus->size() < 2 || Size == 0) return 0;
|
||||
@ -286,7 +323,7 @@ size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
|
||||
NewSize = InsertPartOf(O.data(), O.size(), U.data(), U.size(), MaxSize);
|
||||
if (NewSize)
|
||||
break;
|
||||
LLVM_FALLTHROUGH;
|
||||
// LLVM_FALLTHROUGH;
|
||||
case 2:
|
||||
NewSize = CopyPartOf(O.data(), O.size(), U.data(), U.size());
|
||||
break;
|
||||
|
@ -219,7 +219,7 @@ TEST(FuzzerMutate, InsertRepeatedBytes1) {
|
||||
TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes, 10000);
|
||||
}
|
||||
TEST(FuzzerMutate, InsertRepeatedBytes2) {
|
||||
TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 200000);
|
||||
TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 300000);
|
||||
}
|
||||
|
||||
void TestChangeByte(Mutator M, int NumIter) {
|
||||
@ -475,6 +475,42 @@ TEST(FuzzerMutate, ChangeASCIIInteger2) {
|
||||
TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
|
||||
}
|
||||
|
||||
void TestChangeBinaryInteger(Mutator M, int NumIter) {
|
||||
std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
|
||||
fuzzer::EF = t.get();
|
||||
Random Rand(0);
|
||||
MutationDispatcher MD(Rand, {});
|
||||
|
||||
uint8_t CH0[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x79};
|
||||
uint8_t CH1[8] = {0x00, 0x11, 0x22, 0x31, 0x44, 0x55, 0x66, 0x77};
|
||||
uint8_t CH2[8] = {0xff, 0x10, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
|
||||
uint8_t CH3[8] = {0x00, 0x11, 0x2a, 0x33, 0x44, 0x55, 0x66, 0x77};
|
||||
uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x4f, 0x66, 0x77};
|
||||
uint8_t CH5[8] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88};
|
||||
|
||||
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 = (MD.*M)(T, 8, 8);
|
||||
/**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
|
||||
else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
|
||||
else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
|
||||
else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
|
||||
else if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
|
||||
else if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
|
||||
}
|
||||
EXPECT_EQ(FoundMask, 63);
|
||||
}
|
||||
|
||||
TEST(FuzzerMutate, ChangeBinaryInteger1) {
|
||||
TestChangeBinaryInteger(&MutationDispatcher::Mutate_ChangeBinaryInteger,
|
||||
1 << 12);
|
||||
}
|
||||
|
||||
TEST(FuzzerMutate, ChangeBinaryInteger2) {
|
||||
TestChangeBinaryInteger(&MutationDispatcher::Mutate, 1 << 15);
|
||||
}
|
||||
|
||||
|
||||
TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
|
||||
Unit U;
|
||||
|
Loading…
Reference in New Issue
Block a user