diff --git a/image/test/fuzzing/TestDecoders.cpp b/image/test/fuzzing/TestDecoders.cpp index a7ab09b1f5a2..e25a40222cc5 100644 --- a/image/test/fuzzing/TestDecoders.cpp +++ b/image/test/fuzzing/TestDecoders.cpp @@ -20,7 +20,7 @@ #include "nsString.h" #include "nsThreadUtils.h" -#include "FuzzingInterface.h" +#include "FuzzingInterfaceStream.h" using namespace mozilla; using namespace mozilla::gfx; diff --git a/media/mtransport/fuzztest/stun_parser_libfuzz.cpp b/media/mtransport/fuzztest/stun_parser_libfuzz.cpp index fee3cda333ec..13d04ed00949 100644 --- a/media/mtransport/fuzztest/stun_parser_libfuzz.cpp +++ b/media/mtransport/fuzztest/stun_parser_libfuzz.cpp @@ -9,7 +9,6 @@ #include "gtest/gtest.h" #include "FuzzingInterface.h" -#include "LibFuzzerRegistry.h" extern "C" { #include diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 7388a2e91b92..d1a5f50353c2 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -281,17 +281,19 @@ nsString gAbsoluteArgv0Path; extern "C" MFBT_API bool IsSignalHandlingBroken(); #endif -#ifdef LIBFUZZER -#include "LibFuzzerRunner.h" +#ifdef FUZZING +#include "FuzzerRunner.h" namespace mozilla { -LibFuzzerRunner* libFuzzerRunner = 0; +FuzzerRunner* fuzzerRunner = 0; } // namespace mozilla +#ifdef LIBFUZZER void XRE_LibFuzzerSetDriver(LibFuzzerDriver aDriver) { - mozilla::libFuzzerRunner->setParams(aDriver); + mozilla::fuzzerRunner->setParams(aDriver); } #endif +#endif // FUZZING namespace mozilla { int (*RunGTest)(int*, char**) = 0; @@ -3891,10 +3893,10 @@ XREMain::XRE_mainStartup(bool* aExitFlag) return 1; #endif /* MOZ_WIDGET_GTK */ -#ifdef LIBFUZZER - if (PR_GetEnv("LIBFUZZER")) { +#ifdef FUZZING + if (PR_GetEnv("FUZZER")) { *aExitFlag = true; - return mozilla::libFuzzerRunner->Run(&gArgc, &gArgv); + return mozilla::fuzzerRunner->Run(&gArgc, &gArgv); } #endif diff --git a/tools/fuzzing/interface/FuzzingInterface.h b/tools/fuzzing/interface/FuzzingInterface.h index c72aba123795..677b5f5db42d 100644 --- a/tools/fuzzing/interface/FuzzingInterface.h +++ b/tools/fuzzing/interface/FuzzingInterface.h @@ -10,91 +10,78 @@ #ifndef FuzzingInterface_h__ #define FuzzingInterface_h__ -#include "gtest/gtest.h" -#include "nsComponentManagerUtils.h" -#include "nsCOMPtr.h" -#include "nsIInputStream.h" - -#include "nsDirectoryServiceDefs.h" -#include "nsIDirectoryService.h" -#include "nsIFile.h" -#include "nsStreamUtils.h" -#include "nsStringStream.h" - #include -#ifdef LIBFUZZER -#include "LibFuzzerRegistry.h" -#endif +#include "FuzzerRegistry.h" +#include "mozilla/Assertions.h" namespace mozilla { typedef int(*FuzzingTestFuncRaw)(const uint8_t*, size_t); -typedef int(*FuzzingTestFuncStream)(nsCOMPtr); #ifdef __AFL_COMPILER -void afl_interface_stream(const char* testFile, FuzzingTestFuncStream testFunc); -void afl_interface_raw(const char* testFile, FuzzingTestFuncRaw testFunc); -#define MOZ_AFL_INTERFACE_COMMON(initFunc) \ - initFunc(NULL, NULL); \ +static int afl_interface_raw(const char* testFile, FuzzingTestFuncRaw testFunc) { + char* buf = NULL; + + while(__AFL_LOOP(1000)) { + std::ifstream is; + is.open (testFile, std::ios::binary); + is.seekg (0, std::ios::end); + int len = is.tellg(); + is.seekg (0, std::ios::beg); + MOZ_RELEASE_ASSERT(len >= 0); + if (!len) { + is.close(); + continue; + } + buf = (char*)realloc(buf, len); + MOZ_RELEASE_ASSERT(buf); + is.read(buf,len); + is.close(); + testFunc((uint8_t*)buf, (size_t)len); + } + + free(buf); + + return 0; +} + +#define MOZ_AFL_INTERFACE_COMMON() \ char* testFilePtr = getenv("MOZ_FUZZ_TESTFILE"); \ if (!testFilePtr) { \ - EXPECT_TRUE(false) << "Must specify testfile in MOZ_FUZZ_TESTFILE environment variable."; \ - return; \ + fprintf(stderr, "Must specify testfile in MOZ_FUZZ_TESTFILE environment variable.\n"); \ + return 1; \ } \ /* Make a copy of testFilePtr so the testing function can safely call getenv */ \ std::string testFile(testFilePtr); -#define MOZ_AFL_INTERFACE_STREAM(initFunc, testFunc, moduleName) \ - TEST(AFL, moduleName) { \ - MOZ_AFL_INTERFACE_COMMON(initFunc); \ - ::mozilla::afl_interface_stream(testFile.c_str(), testFunc); \ - } - -#define MOZ_AFL_INTERFACE_RAW(initFunc, testFunc, moduleName) \ - TEST(AFL, moduleName) { \ - MOZ_AFL_INTERFACE_COMMON(initFunc); \ - ::mozilla::afl_interface_raw(testFile.c_str(), testFunc); \ +#define MOZ_AFL_INTERFACE_RAW(initFunc, testFunc, moduleName) \ + static int afl_fuzz_##moduleName(const uint8_t *data, size_t size) { \ + MOZ_RELEASE_ASSERT(data == NULL && size == 0); \ + MOZ_AFL_INTERFACE_COMMON(); \ + return ::mozilla::afl_interface_raw(testFile.c_str(), testFunc); \ + } \ + static void __attribute__ ((constructor)) AFLRegister##moduleName() { \ + ::mozilla::FuzzerRegistry::getInstance().registerModule( \ + #moduleName, initFunc, afl_fuzz_##moduleName \ + ); \ } #else -#define MOZ_AFL_INTERFACE_STREAM(initFunc, testFunc, moduleName) /* Nothing */ #define MOZ_AFL_INTERFACE_RAW(initFunc, testFunc, moduleName) /* Nothing */ -#endif +#endif // __AFL_COMPILER #ifdef LIBFUZZER -#define MOZ_LIBFUZZER_INTERFACE_STREAM(initFunc, testFunc, moduleName) \ - static int LibFuzzerTest##moduleName (const uint8_t *data, size_t size) { \ - if (size > INT32_MAX) \ - return 0; \ - nsCOMPtr stream; \ - nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), \ - (const char*)data, size, NS_ASSIGNMENT_DEPEND); \ - MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); \ - testFunc(stream.forget()); \ - return 0; \ - } \ - static void __attribute__ ((constructor)) LibFuzzerRegister() { \ - ::mozilla::LibFuzzerRegistry::getInstance().registerModule( \ - #moduleName, initFunc, LibFuzzerTest##moduleName \ - ); \ - } - -#define MOZ_LIBFUZZER_INTERFACE_RAW(initFunc, testFunc, moduleName) \ - static void __attribute__ ((constructor)) LibFuzzerRegister() { \ - ::mozilla::LibFuzzerRegistry::getInstance().registerModule( \ - #moduleName, initFunc, testFunc \ - ); \ +#define MOZ_LIBFUZZER_INTERFACE_RAW(initFunc, testFunc, moduleName) \ + static void __attribute__ ((constructor)) LibFuzzerRegister##moduleName() { \ + ::mozilla::FuzzerRegistry::getInstance().registerModule( \ + #moduleName, initFunc, testFunc \ + ); \ } #else -#define MOZ_LIBFUZZER_INTERFACE_STREAM(initFunc, testFunc, moduleName) /* Nothing */ #define MOZ_LIBFUZZER_INTERFACE_RAW(initFunc, testFunc, moduleName) /* Nothing */ #endif -#define MOZ_FUZZING_INTERFACE_STREAM(initFunc, testFunc, moduleName) \ - MOZ_LIBFUZZER_INTERFACE_STREAM(initFunc, testFunc, moduleName); \ - MOZ_AFL_INTERFACE_STREAM(initFunc, testFunc, moduleName); - #define MOZ_FUZZING_INTERFACE_RAW(initFunc, testFunc, moduleName) \ MOZ_LIBFUZZER_INTERFACE_RAW(initFunc, testFunc, moduleName); \ MOZ_AFL_INTERFACE_RAW(initFunc, testFunc, moduleName); diff --git a/tools/fuzzing/interface/FuzzingInterface.cpp b/tools/fuzzing/interface/FuzzingInterfaceStream.cpp similarity index 71% rename from tools/fuzzing/interface/FuzzingInterface.cpp rename to tools/fuzzing/interface/FuzzingInterfaceStream.cpp index 8a2610155698..e042f2eca0cc 100644 --- a/tools/fuzzing/interface/FuzzingInterface.cpp +++ b/tools/fuzzing/interface/FuzzingInterfaceStream.cpp @@ -7,13 +7,18 @@ * Interface implementation for the unified fuzzing interface */ -#include "FuzzingInterface.h" +#include "FuzzingInterfaceStream.h" +#include "mozilla/Assertions.h" + +#ifndef JS_STANDALONE #include "nsNetUtil.h" +#endif namespace mozilla { #ifdef __AFL_COMPILER + void afl_interface_stream(const char* testFile, FuzzingTestFuncStream testFunc) { nsresult rv; nsCOMPtr dirService = @@ -39,29 +44,6 @@ void afl_interface_stream(const char* testFile, FuzzingTestFuncStream testFunc) } } -void afl_interface_raw(const char* testFile, FuzzingTestFuncRaw testFunc) { - char* buf = NULL; - - while(__AFL_LOOP(1000)) { - std::ifstream is; - is.open (testFile, std::ios::binary); - is.seekg (0, std::ios::end); - int len = is.tellg(); - is.seekg (0, std::ios::beg); - MOZ_RELEASE_ASSERT(len >= 0); - if (!len) { - is.close(); - continue; - } - buf = (char*)realloc(buf, len); - MOZ_RELEASE_ASSERT(buf); - is.read(buf,len); - is.close(); - testFunc((uint8_t*)buf, (size_t)len); - } - - free(buf); -} #endif } // namespace mozilla diff --git a/tools/fuzzing/interface/FuzzingInterfaceStream.h b/tools/fuzzing/interface/FuzzingInterfaceStream.h new file mode 100644 index 000000000000..985d94c12e83 --- /dev/null +++ b/tools/fuzzing/interface/FuzzingInterfaceStream.h @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + * Interface definitions for the unified fuzzing interface with streaming support + */ + +#ifndef FuzzingInterfaceStream_h__ +#define FuzzingInterfaceStream_h__ + +#ifdef JS_STANDALONE +#error "FuzzingInterfaceStream.h cannot be used in JS standalone builds." +#endif + +#include "gtest/gtest.h" +#include "nsComponentManagerUtils.h" +#include "nsCOMPtr.h" +#include "nsIInputStream.h" + +#include "nsDirectoryServiceDefs.h" +#include "nsIDirectoryService.h" +#include "nsIFile.h" +#include "nsStreamUtils.h" +#include "nsStringStream.h" + +#include + +#include "FuzzingInterface.h" + +namespace mozilla { + +typedef int(*FuzzingTestFuncStream)(nsCOMPtr); + +#ifdef __AFL_COMPILER +void afl_interface_stream(const char* testFile, FuzzingTestFuncStream testFunc); + +#define MOZ_AFL_INTERFACE_COMMON(initFunc) \ + if (initFunc) initFunc(NULL, NULL); \ + char* testFilePtr = getenv("MOZ_FUZZ_TESTFILE"); \ + if (!testFilePtr) { \ + fprintf(stderr, "Must specify testfile in MOZ_FUZZ_TESTFILE environment variable.\n"); \ + return; \ + } \ + /* Make a copy of testFilePtr so the testing function can safely call getenv */ \ + std::string testFile(testFilePtr); + +#define MOZ_AFL_INTERFACE_STREAM(initFunc, testFunc, moduleName) \ + TEST(AFL, moduleName) { \ + MOZ_AFL_INTERFACE_COMMON(initFunc); \ + ::mozilla::afl_interface_stream(testFile.c_str(), testFunc); \ + } +#else +#define MOZ_AFL_INTERFACE_STREAM(initFunc, testFunc, moduleName) /* Nothing */ +#endif + +#ifdef LIBFUZZER +#define MOZ_LIBFUZZER_INTERFACE_STREAM(initFunc, testFunc, moduleName) \ + static int LibFuzzerTest##moduleName (const uint8_t *data, size_t size) { \ + if (size > INT32_MAX) \ + return 0; \ + nsCOMPtr stream; \ + nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), \ + (const char*)data, size, NS_ASSIGNMENT_DEPEND); \ + MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); \ + testFunc(stream.forget()); \ + return 0; \ + } \ + static void __attribute__ ((constructor)) LibFuzzerRegister() { \ + ::mozilla::FuzzerRegistry::getInstance().registerModule( \ + #moduleName, initFunc, LibFuzzerTest##moduleName \ + ); \ + } +#else +#define MOZ_LIBFUZZER_INTERFACE_STREAM(initFunc, testFunc, moduleName) /* Nothing */ +#endif + +#define MOZ_FUZZING_INTERFACE_STREAM(initFunc, testFunc, moduleName) \ + MOZ_LIBFUZZER_INTERFACE_STREAM(initFunc, testFunc, moduleName); \ + MOZ_AFL_INTERFACE_STREAM(initFunc, testFunc, moduleName); + +} // namespace mozilla + +#endif // FuzzingInterfaceStream_h__ diff --git a/tools/fuzzing/interface/harness/FuzzerRunner.cpp b/tools/fuzzing/interface/harness/FuzzerRunner.cpp new file mode 100644 index 000000000000..57054482e281 --- /dev/null +++ b/tools/fuzzing/interface/harness/FuzzerRunner.cpp @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * * This Source Code Form is subject to the terms of the Mozilla Public + * * License, v. 2.0. If a copy of the MPL was not distributed with this + * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "FuzzerRunner.h" +#include "mozilla/Attributes.h" +#include "prenv.h" + +#include "FuzzerTestHarness.h" + +namespace mozilla { + +// We use a static var 'fuzzerRunner' defined in nsAppRunner.cpp. +// fuzzerRunner is initialized to nullptr but if this file is linked in, +// then fuzzerRunner will be set here indicating that +// we want to call into either LibFuzzer's main or the AFL entrypoint. +class _InitFuzzer { +public: + _InitFuzzer() { + fuzzerRunner = new FuzzerRunner(); + } +} InitLibFuzzer; + +int FuzzerRunner::Run(int* argc, char*** argv) { + ScopedXPCOM xpcom("Fuzzer"); + const char* fuzzerEnv = getenv("FUZZER"); + + if (!fuzzerEnv) { + fuzzerEnv = getenv("LIBFUZZER"); + if (fuzzerEnv) { + fprintf(stderr, "Fuzzer Interface: Warning: \ + Using deprecated LIBFUZZER variable, use FUZZER instead\n"); + } else { + fprintf(stderr, "Must specify fuzzing target in FUZZER environment variable\n"); + return 1; + } + } + + std::string moduleNameStr(fuzzerEnv); + FuzzerFunctions funcs = FuzzerRegistry::getInstance().getModuleFunctions(moduleNameStr); + FuzzerInitFunc initFunc = funcs.first; + FuzzerTestingFunc testingFunc = funcs.second; + if (initFunc) { + int ret = initFunc(argc, argv); + if (ret) { + fprintf(stderr, "Fuzzing Interface: Error: Initialize callback failed\n"); + return ret; + } + } + + if (!testingFunc) { + fprintf(stderr, "Fuzzing Interface: Error: No testing callback found\n"); + return 1; + } + +#ifdef LIBFUZZER + return mFuzzerDriver(argc, argv, testingFunc); +#else + // For AFL, testingFunc points to the entry function we need. + return testingFunc(NULL, 0); +#endif +} + +#ifdef LIBFUZZER +void FuzzerRunner::setParams(LibFuzzerDriver aDriver) { + mFuzzerDriver = aDriver; +} +#endif + +} // namespace mozilla diff --git a/tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.h b/tools/fuzzing/interface/harness/FuzzerRunner.h similarity index 81% rename from tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.h rename to tools/fuzzing/interface/harness/FuzzerRunner.h index 8ccff40e72a8..c19662fcb3b8 100644 --- a/tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.h +++ b/tools/fuzzing/interface/harness/FuzzerRunner.h @@ -3,19 +3,22 @@ * * License, v. 2.0. If a copy of the MPL was not distributed with this * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include "LibFuzzerRegistry.h" +#include "FuzzerRegistry.h" namespace mozilla { -class LibFuzzerRunner { +class FuzzerRunner { public: int Run(int* argc, char*** argv); + +#ifdef LIBFUZZER void setParams(LibFuzzerDriver aDriver); private: LibFuzzerDriver mFuzzerDriver; +#endif }; -extern LibFuzzerRunner* libFuzzerRunner; +extern FuzzerRunner* fuzzerRunner; } // namespace mozilla diff --git a/tools/fuzzing/libfuzzer/harness/LibFuzzerTestHarness.h b/tools/fuzzing/interface/harness/FuzzerTestHarness.h similarity index 98% rename from tools/fuzzing/libfuzzer/harness/LibFuzzerTestHarness.h rename to tools/fuzzing/interface/harness/FuzzerTestHarness.h index a242a3786c54..456344478782 100644 --- a/tools/fuzzing/libfuzzer/harness/LibFuzzerTestHarness.h +++ b/tools/fuzzing/interface/harness/FuzzerTestHarness.h @@ -9,8 +9,8 @@ * and stdio.h/stdlib.h. */ -#ifndef LibFuzzerTestHarness_h__ -#define LibFuzzerTestHarness_h__ +#ifndef FuzzerTestHarness_h__ +#define FuzzerTestHarness_h__ #include "mozilla/ArrayUtils.h" #include "mozilla/Attributes.h" @@ -273,4 +273,4 @@ ScopedXPCOM::Release() } // namespace -#endif // LibFuzzerTestHarness_h__ +#endif // FuzzerTestHarness_h__ diff --git a/tools/fuzzing/libfuzzer/harness/moz.build b/tools/fuzzing/interface/harness/moz.build similarity index 78% rename from tools/fuzzing/libfuzzer/harness/moz.build rename to tools/fuzzing/interface/harness/moz.build index 596018cb3c74..e243fecb19bf 100644 --- a/tools/fuzzing/libfuzzer/harness/moz.build +++ b/tools/fuzzing/interface/harness/moz.build @@ -7,13 +7,10 @@ Library('fuzzer-runner') SOURCES += [ - 'LibFuzzerRegistry.cpp', - 'LibFuzzerRunner.cpp', + 'FuzzerRunner.cpp', ] - EXPORTS += [ - 'LibFuzzerRegistry.h', - 'LibFuzzerRunner.h', + 'FuzzerRunner.h', ] FINAL_LIBRARY = "xul" diff --git a/tools/fuzzing/interface/moz.build b/tools/fuzzing/interface/moz.build index 6b2bb968cf56..56e86846500b 100644 --- a/tools/fuzzing/interface/moz.build +++ b/tools/fuzzing/interface/moz.build @@ -4,12 +4,25 @@ # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. +Library('fuzzer-interface') + EXPORTS += [ 'FuzzingInterface.h', ] -SOURCES += [ - 'FuzzingInterface.cpp', -] +if CONFIG['JS_STANDALONE']: + FINAL_LIBRARY = "js" +else: + EXPORTS += [ + 'FuzzingInterfaceStream.h', + ] -FINAL_LIBRARY = 'xul-gtest' + SOURCES += [ + 'FuzzingInterfaceStream.cpp', + ] + + DIRS += [ + 'harness', + ] + + FINAL_LIBRARY = 'xul-gtest' diff --git a/tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.cpp b/tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.cpp deleted file mode 100644 index a758067b5783..000000000000 --- a/tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * * This Source Code Form is subject to the terms of the Mozilla Public - * * License, v. 2.0. If a copy of the MPL was not distributed with this - * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "LibFuzzerRegistry.h" - -namespace mozilla { - -LibFuzzerRegistry& LibFuzzerRegistry::getInstance() { - static LibFuzzerRegistry instance; - return instance; -} - -void LibFuzzerRegistry::registerModule(std::string moduleName, LibFuzzerInitFunc initFunc, LibFuzzerTestingFunc testingFunc) { - moduleMap.insert(std::pair(moduleName,LibFuzzerFunctions(initFunc, testingFunc))); -} - -LibFuzzerFunctions LibFuzzerRegistry::getModuleFunctions(std::string& moduleName) { - return moduleMap[moduleName]; -} - -} // namespace mozilla diff --git a/tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.h b/tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.h deleted file mode 100644 index a2f81d7358e3..000000000000 --- a/tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * * This Source Code Form is subject to the terms of the Mozilla Public - * * License, v. 2.0. If a copy of the MPL was not distributed with this - * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef _LibFuzzerRegistry_h__ -#define _LibFuzzerRegistry_h__ - -#include -#include -#include -#include - -#include "mozilla/Attributes.h" -#include "mozilla/Types.h" - -typedef int(*LibFuzzerInitFunc)(int*, char***); -typedef int(*LibFuzzerTestingFunc)(const uint8_t*, size_t); -typedef int(*LibFuzzerDriver)(int*, char***, LibFuzzerTestingFunc); - -namespace mozilla { - -typedef std::pair LibFuzzerFunctions; - -class LibFuzzerRegistry { - public: - MOZ_EXPORT static LibFuzzerRegistry& getInstance(); - MOZ_EXPORT void registerModule(std::string moduleName, LibFuzzerInitFunc initFunc, LibFuzzerTestingFunc testingFunc); - MOZ_EXPORT LibFuzzerFunctions getModuleFunctions(std::string& moduleName); - - LibFuzzerRegistry(LibFuzzerRegistry const&) = delete; - void operator=(LibFuzzerRegistry const&) = delete; - - private: - LibFuzzerRegistry() {}; - std::map moduleMap; -}; - -} // namespace mozilla - - -#endif // _LibFuzzerRegistry_h__ diff --git a/tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.cpp b/tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.cpp deleted file mode 100644 index c06d36dbe35c..000000000000 --- a/tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * * This Source Code Form is subject to the terms of the Mozilla Public - * * License, v. 2.0. If a copy of the MPL was not distributed with this - * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include - -#include "LibFuzzerRunner.h" -#include "mozilla/Attributes.h" -#include "prenv.h" - -#include "LibFuzzerTestHarness.h" - -namespace mozilla { - -// We use a static var 'libFuzzerRunner' defined in nsAppRunner.cpp. -// libFuzzerRunner is initialized to nullptr but if LibFuzzer (this file) -// is linked in then libFuzzerRunner will be set here indicating that -// we want to call into LibFuzzer's main. -class _InitLibFuzzer { -public: - _InitLibFuzzer() { - libFuzzerRunner = new LibFuzzerRunner(); - } -} InitLibFuzzer; - -int LibFuzzerRunner::Run(int* argc, char*** argv) { - ScopedXPCOM xpcom("LibFuzzer"); - std::string moduleNameStr(getenv("LIBFUZZER")); - LibFuzzerFunctions funcs = LibFuzzerRegistry::getInstance().getModuleFunctions(moduleNameStr); - LibFuzzerInitFunc initFunc = funcs.first; - LibFuzzerTestingFunc testingFunc = funcs.second; - if (initFunc) { - int ret = initFunc(argc, argv); - if (ret) { - fprintf(stderr, "LibFuzzer: Error: Initialize callback failed\n"); - return ret; - } - } - - if (!testingFunc) { - fprintf(stderr, "LibFuzzer: Error: No testing callback found\n"); - return 1; - } - - return mFuzzerDriver(argc, argv, testingFunc); -} - -void LibFuzzerRunner::setParams(LibFuzzerDriver aDriver) { - mFuzzerDriver = aDriver; -} - -} // namespace mozilla diff --git a/tools/fuzzing/libfuzzer/moz.build b/tools/fuzzing/libfuzzer/moz.build index dc9616da1991..57869a183b3b 100644 --- a/tools/fuzzing/libfuzzer/moz.build +++ b/tools/fuzzing/libfuzzer/moz.build @@ -6,8 +6,8 @@ Library('fuzzer') -DIRS += [ - 'harness', +EXPORTS += [ + 'FuzzerDefs.h', ] SOURCES += [ diff --git a/tools/fuzzing/moz.build b/tools/fuzzing/moz.build index bc867068ac3a..8a42fde4c08a 100644 --- a/tools/fuzzing/moz.build +++ b/tools/fuzzing/moz.build @@ -5,12 +5,17 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. DIRS += [ - 'common', 'interface', - 'messagemanager', - 'shmem' + 'registry', ] +if not CONFIG['JS_STANDALONE']: + DIRS += [ + 'common', + 'messagemanager', + 'shmem', + ] + if CONFIG['LIBFUZZER']: DIRS += [ 'libfuzzer', diff --git a/tools/fuzzing/registry/FuzzerRegistry.cpp b/tools/fuzzing/registry/FuzzerRegistry.cpp new file mode 100644 index 000000000000..aad2b010344f --- /dev/null +++ b/tools/fuzzing/registry/FuzzerRegistry.cpp @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * * This Source Code Form is subject to the terms of the Mozilla Public + * * License, v. 2.0. If a copy of the MPL was not distributed with this + * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "FuzzerRegistry.h" + +namespace mozilla { + +FuzzerRegistry& FuzzerRegistry::getInstance() { + static FuzzerRegistry instance; + return instance; +} + +void FuzzerRegistry::registerModule(std::string moduleName, FuzzerInitFunc initFunc, FuzzerTestingFunc testingFunc) { + moduleMap.insert(std::pair(moduleName,FuzzerFunctions(initFunc, testingFunc))); +} + +FuzzerFunctions FuzzerRegistry::getModuleFunctions(std::string& moduleName) { + return moduleMap[moduleName]; +} + +} // namespace mozilla diff --git a/tools/fuzzing/registry/FuzzerRegistry.h b/tools/fuzzing/registry/FuzzerRegistry.h new file mode 100644 index 000000000000..caf45629a6d1 --- /dev/null +++ b/tools/fuzzing/registry/FuzzerRegistry.h @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * * This Source Code Form is subject to the terms of the Mozilla Public + * * License, v. 2.0. If a copy of the MPL was not distributed with this + * * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _FuzzerRegistry_h__ +#define _FuzzerRegistry_h__ + +#include +#include +#include +#include + +#include "mozilla/Attributes.h" +#include "mozilla/Types.h" + +typedef int(*FuzzerInitFunc)(int*, char***); +typedef int(*FuzzerTestingFunc)(const uint8_t*, size_t); + +typedef int(*LibFuzzerDriver)(int*, char***, FuzzerTestingFunc); + +namespace mozilla { + +typedef std::pair FuzzerFunctions; + +class FuzzerRegistry { + public: + MOZ_EXPORT static FuzzerRegistry& getInstance(); + MOZ_EXPORT void registerModule(std::string moduleName, FuzzerInitFunc initFunc, FuzzerTestingFunc testingFunc); + MOZ_EXPORT FuzzerFunctions getModuleFunctions(std::string& moduleName); + + FuzzerRegistry(FuzzerRegistry const&) = delete; + void operator=(FuzzerRegistry const&) = delete; + + private: + FuzzerRegistry() {}; + std::map moduleMap; +}; + +} // namespace mozilla + + +#endif // _FuzzerRegistry_h__ diff --git a/tools/fuzzing/registry/moz.build b/tools/fuzzing/registry/moz.build new file mode 100644 index 000000000000..c028418330a2 --- /dev/null +++ b/tools/fuzzing/registry/moz.build @@ -0,0 +1,20 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +Library('fuzzer-registry') + +SOURCES += [ + 'FuzzerRegistry.cpp', +] + +EXPORTS += [ + 'FuzzerRegistry.h', +] + +if CONFIG['JS_STANDALONE']: + FINAL_LIBRARY = "js" +else: + FINAL_LIBRARY = "xul" diff --git a/xpcom/build/nsXULAppAPI.h b/xpcom/build/nsXULAppAPI.h index b0f67c169a37..77f757d30fb7 100644 --- a/xpcom/build/nsXULAppAPI.h +++ b/xpcom/build/nsXULAppAPI.h @@ -513,7 +513,7 @@ XRE_API(int, const XREShellData* aShellData)) #ifdef LIBFUZZER -#include "LibFuzzerRegistry.h" +#include "FuzzerRegistry.h" XRE_API(void, XRE_LibFuzzerSetDriver, (LibFuzzerDriver))