[libFuzzer] swap bytes in integers when handling CMP traces

llvm-svn: 284301
This commit is contained in:
Kostya Serebryany 2016-10-15 04:00:07 +00:00
parent 49db68d59b
commit 9a4b10a56f
5 changed files with 49 additions and 15 deletions

View File

@ -117,5 +117,10 @@ struct ScopedDoingMyOwnMemmem {
~ScopedDoingMyOwnMemmem();
};
inline uint8_t Bswap(uint8_t x) { return x; }
inline uint16_t Bswap(uint16_t x) { return __builtin_bswap16(x); }
inline uint32_t Bswap(uint32_t x) { return __builtin_bswap32(x); }
inline uint64_t Bswap(uint64_t x) { return __builtin_bswap64(x); }
} // namespace fuzzer
#endif // LLVM_FUZZER_DEFS_H

View File

@ -293,11 +293,6 @@ 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;

View File

@ -208,22 +208,22 @@ void TracePC::TORCToDict(Dictionary *Dict, T FindInData, T Substitute,
const size_t DataSize = sizeof(T);
const uint8_t *End = Data + Size;
int Attempts = 3;
// TODO: also swap bytes in FindInData.
for (const uint8_t *Cur = Data; Cur < End && Attempts--; Cur++) {
Cur = (uint8_t *)memmem(Cur, End - Cur, &FindInData, DataSize);
if (!Cur)
break;
size_t Pos = Cur - Data;
for (int Offset = 0; Offset <= 0; Offset++) {
T Tmp = Substitute + Offset;
Word W(reinterpret_cast<uint8_t *>(&Tmp), sizeof(Tmp));
for (int DoSwap = 0; DoSwap <= 1; DoSwap++) {
for (const uint8_t *Cur = Data; Cur < End && Attempts--; Cur++) {
Cur = (uint8_t *)memmem(Cur, End - Cur, &FindInData, DataSize);
if (!Cur)
break;
size_t Pos = Cur - Data;
Word W(reinterpret_cast<uint8_t *>(&Substitute), sizeof(Substitute));
DictionaryEntry DE(W, Pos);
// TODO: evict all entries from Dic if it's full.
Dict->push_back(DE);
// Printf("Dict[%zd] TORC%zd %llx => %llx pos %zd\n", Dict->size(),
// sizeof(T),
// (uint64_t)FindInData, (uint64_t)Tmp, Pos);
// (uint64_t)FindInData, (uint64_t)Substitute, Pos);
}
FindInData = Bswap(FindInData);
Substitute = Bswap(Substitute);
}
}

View File

@ -102,6 +102,7 @@ set(Tests
StrcmpTest
StrncmpTest
StrstrTest
SwapCmpTest
SwitchTest
ThreadedLeakTest
ThreadedTest

View File

@ -0,0 +1,33 @@
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
// The fuzzer must find several constants with swapped bytes.
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <cstdio>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (Size < 14) return 0;
uint64_t x = 0;
uint32_t y = 0;
uint16_t z = 0;
memcpy(&x, Data, sizeof(x));
memcpy(&y, Data + Size / 2, sizeof(y));
memcpy(&z, Data + Size - sizeof(z), sizeof(z));
x = __builtin_bswap64(x);
y = __builtin_bswap32(y);
z = __builtin_bswap16(z);
if (x == 0x46555A5A5A5A5546ULL &&
y == 0x66757A7A &&
z == 0x4F4B
) {
if (Data[Size - 3] == 'z') {
fprintf(stderr, "BINGO; Found the target\n");
exit(1);
}
}
return 0;
}