[libFuzzer] swap bytes in integers when handling CMP traces
authorKostya Serebryany <kcc@google.com>
Sat, 15 Oct 2016 04:00:07 +0000 (04:00 +0000)
committerKostya Serebryany <kcc@google.com>
Sat, 15 Oct 2016 04:00:07 +0000 (04:00 +0000)
llvm-svn: 284301

llvm/lib/Fuzzer/FuzzerDefs.h
llvm/lib/Fuzzer/FuzzerMutate.cpp
llvm/lib/Fuzzer/FuzzerTracePC.cpp
llvm/lib/Fuzzer/test/CMakeLists.txt
llvm/lib/Fuzzer/test/SwapCmpTest.cpp [new file with mode: 0644]

index 99b478f..6a9e323 100644 (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
index 76585dc..d38ee22 100644 (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;
index cfaf9c5..6b9e210 100644 (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);
   }
 }
 
index d52c282..1475c66 100644 (file)
@@ -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 (file)
index 0000000..3c1199e
--- /dev/null
@@ -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;
+}