[fuzzer] Add basic support for emscripten.
authorJonathan Metzman <metzman@chromium.org>
Thu, 12 Dec 2019 16:48:54 +0000 (08:48 -0800)
committerJonathan Metzman <metzman@chromium.org>
Thu, 12 Dec 2019 16:56:47 +0000 (08:56 -0800)
Summary:
Add basic support for emscripten.

This enables libFuzzer to build (using build.sh) for emscripten and fuzz
a target compiled with
-fsanitize-coverage=inline-8bit-counters.

Basic fuzzing and bug finding work with this commit.
RSS limit and timeouts will not work because they depend on system
functions that are not implemented/widely supported in emscripten.

Reviewers: kcc, vitalybuka, hctim

Reviewed By: hctim

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D71285

compiler-rt/lib/fuzzer/FuzzerDefs.h
compiler-rt/lib/fuzzer/FuzzerDriver.cpp
compiler-rt/lib/fuzzer/FuzzerExtFunctionsWeak.cpp
compiler-rt/lib/fuzzer/FuzzerExtraCounters.cpp
compiler-rt/lib/fuzzer/FuzzerUtilLinux.cpp
compiler-rt/lib/fuzzer/FuzzerUtilPosix.cpp

index 5dc2d8e..5793e86 100644 (file)
@@ -30,6 +30,7 @@
 #define LIBFUZZER_FREEBSD 0
 #define LIBFUZZER_OPENBSD 0
 #define LIBFUZZER_WINDOWS 0
+#define LIBFUZZER_EMSCRIPTEN 0
 #elif __APPLE__
 #define LIBFUZZER_APPLE 1
 #define LIBFUZZER_FUCHSIA 0
@@ -38,6 +39,7 @@
 #define LIBFUZZER_FREEBSD 0
 #define LIBFUZZER_OPENBSD 0
 #define LIBFUZZER_WINDOWS 0
+#define LIBFUZZER_EMSCRIPTEN 0
 #elif __NetBSD__
 #define LIBFUZZER_APPLE 0
 #define LIBFUZZER_FUCHSIA 0
@@ -46,6 +48,7 @@
 #define LIBFUZZER_FREEBSD 0
 #define LIBFUZZER_OPENBSD 0
 #define LIBFUZZER_WINDOWS 0
+#define LIBFUZZER_EMSCRIPTEN 0
 #elif __FreeBSD__
 #define LIBFUZZER_APPLE 0
 #define LIBFUZZER_FUCHSIA 0
@@ -54,6 +57,7 @@
 #define LIBFUZZER_FREEBSD 1
 #define LIBFUZZER_OPENBSD 0
 #define LIBFUZZER_WINDOWS 0
+#define LIBFUZZER_EMSCRIPTEN 0
 #elif __OpenBSD__
 #define LIBFUZZER_APPLE 0
 #define LIBFUZZER_FUCHSIA 0
@@ -62,6 +66,7 @@
 #define LIBFUZZER_FREEBSD 0
 #define LIBFUZZER_OPENBSD 1
 #define LIBFUZZER_WINDOWS 0
+#define LIBFUZZER_EMSCRIPTEN 0
 #elif _WIN32
 #define LIBFUZZER_APPLE 0
 #define LIBFUZZER_FUCHSIA 0
@@ -70,6 +75,7 @@
 #define LIBFUZZER_FREEBSD 0
 #define LIBFUZZER_OPENBSD 0
 #define LIBFUZZER_WINDOWS 1
+#define LIBFUZZER_EMSCRIPTEN 0
 #elif __Fuchsia__
 #define LIBFUZZER_APPLE 0
 #define LIBFUZZER_FUCHSIA 1
 #define LIBFUZZER_FREEBSD 0
 #define LIBFUZZER_OPENBSD 0
 #define LIBFUZZER_WINDOWS 0
+#define LIBFUZZER_EMSCRIPTEN 0
+#elif __EMSCRIPTEN__
+#define LIBFUZZER_APPLE 0
+#define LIBFUZZER_FUCHSIA 0
+#define LIBFUZZER_LINUX 0
+#define LIBFUZZER_NETBSD 0
+#define LIBFUZZER_FREEBSD 0
+#define LIBFUZZER_OPENBSD 0
+#define LIBFUZZER_WINDOWS 0
+#define LIBFUZZER_EMSCRIPTEN 1
 #else
 #error "Support for your platform has not been implemented"
 #endif
 
 #define LIBFUZZER_POSIX                                                        \
   (LIBFUZZER_APPLE || LIBFUZZER_LINUX || LIBFUZZER_NETBSD ||                   \
-   LIBFUZZER_FREEBSD || LIBFUZZER_OPENBSD)
+   LIBFUZZER_FREEBSD || LIBFUZZER_OPENBSD || LIBFUZZER_EMSCRIPTEN)
 
 #ifdef __x86_64
 #  if __has_attribute(target)
index 44c9065..dd3cab0 100644 (file)
@@ -280,7 +280,8 @@ static void RssThread(Fuzzer *F, size_t RssLimitMb) {
 }
 
 static void StartRssThread(Fuzzer *F, size_t RssLimitMb) {
-  if (!RssLimitMb) return;
+  if (!RssLimitMb)
+    return;
   std::thread T(RssThread, F, RssLimitMb);
   T.detach();
 }
@@ -737,7 +738,11 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
     if (U.size() <= Word::GetMaxSize())
       MD->AddWordToManualDictionary(Word(U.data(), U.size()));
 
+      // Threads are only supported by Chrome. Don't use them with emscripten
+      // for now.
+#if !LIBFUZZER_EMSCRIPTEN
   StartRssThread(F, Flags.rss_limit_mb);
+#endif // LIBFUZZER_EMSCRIPTEN
 
   Options.HandleAbrt = Flags.handle_abrt;
   Options.HandleBus = Flags.handle_bus;
index ea5b87b..d56dab3 100644 (file)
@@ -13,7 +13,7 @@
 //===----------------------------------------------------------------------===//
 #include "FuzzerDefs.h"
 #if LIBFUZZER_LINUX || LIBFUZZER_NETBSD || LIBFUZZER_FUCHSIA ||                \
-    LIBFUZZER_FREEBSD || LIBFUZZER_OPENBSD
+    LIBFUZZER_FREEBSD || LIBFUZZER_OPENBSD || LIBFUZZER_EMSCRIPTEN
 
 #include "FuzzerExtFunctions.h"
 #include "FuzzerIO.h"
index cd62394..b2face7 100644 (file)
@@ -11,7 +11,7 @@
 #include "FuzzerDefs.h"
 
 #if LIBFUZZER_LINUX || LIBFUZZER_NETBSD || LIBFUZZER_FREEBSD ||                \
-    LIBFUZZER_OPENBSD || LIBFUZZER_FUCHSIA
+    LIBFUZZER_OPENBSD || LIBFUZZER_FUCHSIA || LIBFUZZER_EMSCRIPTEN
 __attribute__((weak)) extern uint8_t __start___libfuzzer_extra_counters;
 __attribute__((weak)) extern uint8_t __stop___libfuzzer_extra_counters;
 
index bf305b4..993023e 100644 (file)
@@ -9,7 +9,7 @@
 //===----------------------------------------------------------------------===//
 #include "FuzzerDefs.h"
 #if LIBFUZZER_LINUX || LIBFUZZER_NETBSD || LIBFUZZER_FREEBSD ||                \
-    LIBFUZZER_OPENBSD
+    LIBFUZZER_OPENBSD || LIBFUZZER_EMSCRIPTEN
 #include "FuzzerCommand.h"
 
 #include <stdlib.h>
index cefe7ae..8048e6a 100644 (file)
@@ -98,7 +98,8 @@ void SetTimer(int Seconds) {
 }
 
 void SetSignalHandler(const FuzzingOptions& Options) {
-  if (Options.UnitTimeoutSec > 0)
+  // setitimer is not implemented in emscripten.
+  if (Options.UnitTimeoutSec > 0 && !LIBFUZZER_EMSCRIPTEN)
     SetTimer(Options.UnitTimeoutSec / 2 + 1);
   if (Options.HandleInt)
     SetSigaction(SIGINT, InterruptHandler);
@@ -133,7 +134,7 @@ size_t GetPeakRSSMb() {
   if (getrusage(RUSAGE_SELF, &usage))
     return 0;
   if (LIBFUZZER_LINUX || LIBFUZZER_FREEBSD || LIBFUZZER_NETBSD ||
-      LIBFUZZER_OPENBSD) {
+      LIBFUZZER_OPENBSD || LIBFUZZER_EMSCRIPTEN) {
     // ru_maxrss is in KiB
     return usage.ru_maxrss >> 10;
   } else if (LIBFUZZER_APPLE) {