From 9a4b10a56f8b3f7e8dc46cc48451836cd7fa6a9a Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Sat, 15 Oct 2016 04:00:07 +0000 Subject: [PATCH] [libFuzzer] swap bytes in integers when handling CMP traces llvm-svn: 284301 --- llvm/lib/Fuzzer/FuzzerDefs.h | 5 +++++ llvm/lib/Fuzzer/FuzzerMutate.cpp | 5 ----- llvm/lib/Fuzzer/FuzzerTracePC.cpp | 20 ++++++++++---------- llvm/lib/Fuzzer/test/CMakeLists.txt | 1 + llvm/lib/Fuzzer/test/SwapCmpTest.cpp | 33 +++++++++++++++++++++++++++++++++ 5 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 llvm/lib/Fuzzer/test/SwapCmpTest.cpp diff --git a/llvm/lib/Fuzzer/FuzzerDefs.h b/llvm/lib/Fuzzer/FuzzerDefs.h index 99b478f..6a9e323 100644 --- a/llvm/lib/Fuzzer/FuzzerDefs.h +++ b/llvm/lib/Fuzzer/FuzzerDefs.h @@ -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 diff --git a/llvm/lib/Fuzzer/FuzzerMutate.cpp b/llvm/lib/Fuzzer/FuzzerMutate.cpp index 76585dc..d38ee22 100644 --- a/llvm/lib/Fuzzer/FuzzerMutate.cpp +++ b/llvm/lib/Fuzzer/FuzzerMutate.cpp @@ -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 size_t ChangeBinaryInteger(uint8_t *Data, size_t Size, Random &Rand) { if (Size < sizeof(T)) return 0; diff --git a/llvm/lib/Fuzzer/FuzzerTracePC.cpp b/llvm/lib/Fuzzer/FuzzerTracePC.cpp index cfaf9c5..6b9e210 100644 --- a/llvm/lib/Fuzzer/FuzzerTracePC.cpp +++ b/llvm/lib/Fuzzer/FuzzerTracePC.cpp @@ -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(&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(&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); } } diff --git a/llvm/lib/Fuzzer/test/CMakeLists.txt b/llvm/lib/Fuzzer/test/CMakeLists.txt index d52c282..1475c66 100644 --- a/llvm/lib/Fuzzer/test/CMakeLists.txt +++ b/llvm/lib/Fuzzer/test/CMakeLists.txt @@ -102,6 +102,7 @@ set(Tests StrcmpTest StrncmpTest StrstrTest + SwapCmpTest SwitchTest ThreadedLeakTest ThreadedTest diff --git a/llvm/lib/Fuzzer/test/SwapCmpTest.cpp b/llvm/lib/Fuzzer/test/SwapCmpTest.cpp new file mode 100644 index 0000000..3c1199e --- /dev/null +++ b/llvm/lib/Fuzzer/test/SwapCmpTest.cpp @@ -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 +#include +#include +#include + +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; +} -- 2.7.4