diff --git a/config/check_spidermonkey_style.py b/config/check_spidermonkey_style.py index 35e4024bf533..cb456daccbc9 100644 --- a/config/check_spidermonkey_style.py +++ b/config/check_spidermonkey_style.py @@ -69,8 +69,6 @@ included_inclnames_to_ignore = set([ 'jscustomallocator.h', # provided by embedders; allowed to be missing 'js-config.h', # generated in $OBJDIR 'fdlibm.h', # fdlibm - 'FuzzerDefs.h', # included without a path - 'FuzzingInterface.h', # included without a path 'mozmemory.h', # included without a path 'pratom.h', # NSPR 'prcvar.h', # NSPR diff --git a/image/test/fuzzing/TestDecoders.cpp b/image/test/fuzzing/TestDecoders.cpp index e25a40222cc5..a7ab09b1f5a2 100644 --- a/image/test/fuzzing/TestDecoders.cpp +++ b/image/test/fuzzing/TestDecoders.cpp @@ -20,7 +20,7 @@ #include "nsString.h" #include "nsThreadUtils.h" -#include "FuzzingInterfaceStream.h" +#include "FuzzingInterface.h" using namespace mozilla; using namespace mozilla::gfx; diff --git a/js/app.mozbuild b/js/app.mozbuild index 80488800c5ea..3f0876a2f9dd 100644 --- a/js/app.mozbuild +++ b/js/app.mozbuild @@ -36,8 +36,3 @@ if CONFIG['COMPILE_ENVIRONMENT'] and CONFIG['BUILD_CTYPES']: '/config/external/ffi', ] -if CONFIG['JS_STANDALONE'] and CONFIG['FUZZING']: - DIRS += [ - '/tools/fuzzing/', - ] - diff --git a/js/src/fuzz-tests/README b/js/src/fuzz-tests/README deleted file mode 100644 index 2c98c1ffa266..000000000000 --- a/js/src/fuzz-tests/README +++ /dev/null @@ -1,31 +0,0 @@ -# JS Fuzzing Interface - -This directory contains fuzzing targets that implement the unified fuzzing -interface to be used with libFuzzer or AFL. - -## Building the fuzzing targets - -To include this directory in your JS build, you need to build with Clang -and the --enable-fuzzing flag enabled. The build system will automatically -detect if you are building with afl-clang-fast for AFL or regular Clang -for libFuzzer. - -## Running a fuzzing target - -To run a particular target with libFuzzer, use: - - cd $OBJDIR/dist/bin - FUZZER=YourTargetName ./fuzz-tests - -To run with AFL, use something like - - cd $OBJDIR/dist/bin - FUZZER=YourTargetName MOZ_FUZZ_TESTFILE=input \ - afl-fuzz -f input ./fuzz-tests - - -## Writing a fuzzing target - -1. Check testExample.cpp for a target skeleton with comments. - -2. Add your own .cpp file to UNIFIED_SOURCES in moz.build diff --git a/js/src/fuzz-tests/moz.build b/js/src/fuzz-tests/moz.build deleted file mode 100644 index a8dd94cefbcd..000000000000 --- a/js/src/fuzz-tests/moz.build +++ /dev/null @@ -1,52 +0,0 @@ -# -*- Mode: python; 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/. - -GeckoProgram('fuzz-tests', linkage=None) - -UNIFIED_SOURCES += [ - 'testExample.cpp', - 'tests.cpp', -] - -DEFINES['EXPORT_JS_API'] = True - -LOCAL_INCLUDES += [ - '!..', - '..', -] - -if CONFIG['ENABLE_INTL_API'] and CONFIG['MOZ_ICU_DATA_ARCHIVE']: - # The ICU libraries linked into libmozjs will not include the ICU data, - # so link it directly. - USE_LIBS += ['icudata'] - -if CONFIG['FUZZING']: - USE_LIBS += [ - 'static:fuzzer-registry', - ] - -if CONFIG['LIBFUZZER']: - USE_LIBS += [ - 'static:fuzzer', - ] - - # Add trace-pc coverage for libfuzzer - CFLAGS += ['-fsanitize-coverage=trace-pc-guard'] - CXXFLAGS += ['-fsanitize-coverage=trace-pc-guard'] - -USE_LIBS += [ - 'static:js', -] - -if CONFIG['MOZ_NEEDS_LIBATOMIC']: - OS_LIBS += ['atomic'] - -OS_LIBS += CONFIG['MOZ_ZLIB_LIBS'] - -if CONFIG['CC_TYPE'] in ('clang', 'gcc'): - CXXFLAGS += ['-Wno-shadow', '-Werror=format', '-fno-strict-aliasing'] - -DEFINES['topsrcdir'] = '%s/js/src' % TOPSRCDIR diff --git a/js/src/fuzz-tests/testExample.cpp b/js/src/fuzz-tests/testExample.cpp deleted file mode 100644 index ee86d63c6c7f..000000000000 --- a/js/src/fuzz-tests/testExample.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - */ -/* 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 "mozilla/ScopeExit.h" -#include "jsapi.h" -#include "fuzz-tests/tests.h" -#include "vm/Interpreter.h" -#include "jscntxtinlines.h" - -using namespace JS; -using namespace js; - -extern JS::PersistentRootedObject gGlobal; -extern JSContext* gCx; - -static int -testExampleInit(int *argc, char ***argv) { - /* This function is called once at startup. You can use it to e.g. read - environment variables to initialize additional options you might need. - Note that `gCx` and `gGlobal` are pre-initialized by the harness. - */ - return 0; -} - -static int -testExampleFuzz(const uint8_t* buf, size_t size) -{ - /* If your code directly or indirectly allocates GC memory, then it makes sense - to attempt and collect that after every iteration. This should detect GC issues - as soon as possible (right after your iteration), rather than later when your - code happens to trigger GC coincidentially. You can of course disable this code - if it is not required in your use case, which will speed up fuzzing. */ - auto gcGuard = mozilla::MakeScopeExit([&] { - JS::PrepareForFullGC(gCx); - JS::GCForReason(gCx, GC_NORMAL, JS::gcreason::API); - }); - - /* Add code here that processes the given buffer. - While doing so, you need to follow these rules: - - 1. Do not modify or free the buffer. Make a copy if necessary. - 2. This function must always return 0. - 3. Do not crash or abort unless the condition constitutes a bug. - 4. You may use the `gGlobal` and `gCx` variables, they are pre-initialized. - 5. Try to keep the effects of this function contained, such that future - calls to this function are not affected. Otherwise you end up with - non-reproducible testcases and coverage measurements will be incorrect. - */ - - return 0; -} - -MOZ_FUZZING_INTERFACE_RAW( - testExampleInit, /* init function */ - testExampleFuzz, /* fuzzing function */ - Example /* module name */ -); diff --git a/js/src/fuzz-tests/tests.cpp b/js/src/fuzz-tests/tests.cpp deleted file mode 100644 index b0e3c46411c0..000000000000 --- a/js/src/fuzz-tests/tests.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 "fuzz-tests/tests.h" - -#include - -#include "jsalloc.h" -#include "jscntxt.h" -#include "js/Initialization.h" -#include "js/RootingAPI.h" - -#ifdef LIBFUZZER -#include "FuzzerDefs.h" -#endif - -using namespace mozilla; - -JS::PersistentRootedObject gGlobal; -JSContext* gCx = nullptr; -JSCompartment* gOldCompartment = nullptr; - -static const JSClass* -getGlobalClass() -{ - static const JSClassOps cOps = { - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, - JS_GlobalObjectTraceHook - }; - static const JSClass c = { - "global", JSCLASS_GLOBAL_FLAGS, - &cOps - }; - return &c; -} - -static JSObject* -jsfuzz_createGlobal(JSContext* cx, JSPrincipals* principals) -{ - /* Create the global object. */ - JS::RootedObject newGlobal(cx); - JS::CompartmentOptions options; -#ifdef ENABLE_STREAMS - options.creationOptions().setStreamsEnabled(true); -#endif - newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook, - options); - if (!newGlobal) - return nullptr; - - JSAutoCompartment ac(cx, newGlobal); - - // Populate the global object with the standard globals like Object and - // Array. - if (!JS_InitStandardClasses(cx, newGlobal)) - return nullptr; - - return newGlobal; -} - -static bool -jsfuzz_init(JSContext** cx, JS::PersistentRootedObject* global) -{ - *cx = JS_NewContext(8L * 1024 * 1024); - if (!*cx) - return false; - - const size_t MAX_STACK_SIZE = 500000; - - JS_SetNativeStackQuota(*cx, MAX_STACK_SIZE); - - js::UseInternalJobQueues(*cx); - if (!JS::InitSelfHostedCode(*cx)) - return false; - JS_BeginRequest(*cx); - global->init(*cx); - *global = jsfuzz_createGlobal(*cx, nullptr); - if (!*global) - return false; - JS_EnterCompartment(*cx, *global); - return true; -} - -static void -jsfuzz_uninit(JSContext* cx, JSCompartment* oldCompartment) -{ - if (oldCompartment) { - JS_LeaveCompartment(cx, oldCompartment); - oldCompartment = nullptr; - } - if (cx) { - JS_EndRequest(cx); - JS_DestroyContext(cx); - cx = nullptr; - } -} - -int -main(int argc, char* argv[]) -{ - if (!JS_Init()) { - fprintf(stderr, "Error: Call to jsfuzz_init() failed\n"); - return 1; - } - - if (!jsfuzz_init(&gCx, &gGlobal)) { - fprintf(stderr, "Error: Call to jsfuzz_init() failed\n"); - return 1; - } - - const char* fuzzerEnv = getenv("FUZZER"); - if (!fuzzerEnv) { - fprintf(stderr, "Must specify fuzzing target in FUZZER environment variable\n"); - return 1; - } - - std::string moduleNameStr(getenv("FUZZER")); - - 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 - fuzzer::FuzzerDriver(&argc, &argv, testingFunc); -#elif __AFL_COMPILER - testingFunc(nullptr, 0); -#endif - - jsfuzz_uninit(gCx, nullptr); - - JS_ShutDown(); - - return 0; -} diff --git a/js/src/fuzz-tests/tests.h b/js/src/fuzz-tests/tests.h deleted file mode 100644 index 24d173156235..000000000000 --- a/js/src/fuzz-tests/tests.h +++ /dev/null @@ -1,19 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=8 sts=4 et sw=4 tw=99: - * 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 fuzz_tests_tests_h -#define fuzz_tests_tests_h - -#include -#include -#include -#include - -#include "FuzzingInterface.h" - -#include "jscntxt.h" - -#endif /* fuzz_tests_tests_h */ diff --git a/js/src/make-source-package.sh b/js/src/make-source-package.sh index 9e9e6f8ac406..b2b14a81ce68 100755 --- a/js/src/make-source-package.sh +++ b/js/src/make-source-package.sh @@ -168,13 +168,6 @@ case $cmd in ${TOPSRCDIR}/memory/fallible \ ${TOPSRCDIR}/memory/mozalloc \ ${tgtpath}/memory - ${MKDIR} -p ${tgtpath}/tools/fuzzing - cp -pPR \ - ${TOPSRCDIR}/tools/fuzzing/moz.build \ - ${TOPSRCDIR}/tools/fuzzing/interface \ - ${TOPSRCDIR}/tools/fuzzing/registry \ - ${TOPSRCDIR}/tools/fuzzing/libfuzzer \ - ${tgtpath}/tools/fuzzing # remove *.pyc and *.pyo files if any find ${tgtpath} -type f -name "*.pyc" -o -name "*.pyo" |xargs rm -f diff --git a/js/src/moz.build b/js/src/moz.build index 33166edace05..36679284398d 100755 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -50,16 +50,6 @@ if not CONFIG['JS_DISABLE_SHELL']: TEST_DIRS += ['jsapi-tests', 'tests', 'gdb'] -if CONFIG['FUZZING']: - if CONFIG['LIBFUZZER']: - # Add trace-pc coverage for libfuzzer - CFLAGS += ['-fsanitize-coverage=trace-pc-guard'] - CXXFLAGS += ['-fsanitize-coverage=trace-pc-guard'] - - TEST_DIRS += [ - 'fuzz-tests', - ] - CONFIGURE_SUBST_FILES += [ 'devtools/rootAnalysis/Makefile', ] diff --git a/media/mtransport/fuzztest/stun_parser_libfuzz.cpp b/media/mtransport/fuzztest/stun_parser_libfuzz.cpp index 13d04ed00949..fee3cda333ec 100644 --- a/media/mtransport/fuzztest/stun_parser_libfuzz.cpp +++ b/media/mtransport/fuzztest/stun_parser_libfuzz.cpp @@ -9,6 +9,7 @@ #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 d1a5f50353c2..7388a2e91b92 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -281,19 +281,17 @@ nsString gAbsoluteArgv0Path; extern "C" MFBT_API bool IsSignalHandlingBroken(); #endif -#ifdef FUZZING -#include "FuzzerRunner.h" +#ifdef LIBFUZZER +#include "LibFuzzerRunner.h" namespace mozilla { -FuzzerRunner* fuzzerRunner = 0; +LibFuzzerRunner* libFuzzerRunner = 0; } // namespace mozilla -#ifdef LIBFUZZER void XRE_LibFuzzerSetDriver(LibFuzzerDriver aDriver) { - mozilla::fuzzerRunner->setParams(aDriver); + mozilla::libFuzzerRunner->setParams(aDriver); } #endif -#endif // FUZZING namespace mozilla { int (*RunGTest)(int*, char**) = 0; @@ -3893,10 +3891,10 @@ XREMain::XRE_mainStartup(bool* aExitFlag) return 1; #endif /* MOZ_WIDGET_GTK */ -#ifdef FUZZING - if (PR_GetEnv("FUZZER")) { +#ifdef LIBFUZZER + if (PR_GetEnv("LIBFUZZER")) { *aExitFlag = true; - return mozilla::fuzzerRunner->Run(&gArgc, &gArgv); + return mozilla::libFuzzerRunner->Run(&gArgc, &gArgv); } #endif diff --git a/tools/fuzzing/interface/FuzzingInterfaceStream.cpp b/tools/fuzzing/interface/FuzzingInterface.cpp similarity index 71% rename from tools/fuzzing/interface/FuzzingInterfaceStream.cpp rename to tools/fuzzing/interface/FuzzingInterface.cpp index e042f2eca0cc..8a2610155698 100644 --- a/tools/fuzzing/interface/FuzzingInterfaceStream.cpp +++ b/tools/fuzzing/interface/FuzzingInterface.cpp @@ -7,18 +7,13 @@ * Interface implementation for the unified fuzzing interface */ -#include "FuzzingInterfaceStream.h" +#include "FuzzingInterface.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 = @@ -44,6 +39,29 @@ 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/FuzzingInterface.h b/tools/fuzzing/interface/FuzzingInterface.h index 677b5f5db42d..c72aba123795 100644 --- a/tools/fuzzing/interface/FuzzingInterface.h +++ b/tools/fuzzing/interface/FuzzingInterface.h @@ -10,78 +10,91 @@ #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 -#include "FuzzerRegistry.h" -#include "mozilla/Assertions.h" +#ifdef LIBFUZZER +#include "LibFuzzerRegistry.h" +#endif 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); -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() \ +#define MOZ_AFL_INTERFACE_COMMON(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 1; \ + EXPECT_TRUE(false) << "Must specify testfile in MOZ_FUZZ_TESTFILE environment variable."; \ + return; \ } \ /* Make a copy of testFilePtr so the testing function can safely call getenv */ \ std::string testFile(testFilePtr); -#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 \ - ); \ +#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); \ } #else +#define MOZ_AFL_INTERFACE_STREAM(initFunc, testFunc, moduleName) /* Nothing */ #define MOZ_AFL_INTERFACE_RAW(initFunc, testFunc, moduleName) /* Nothing */ -#endif // __AFL_COMPILER +#endif #ifdef LIBFUZZER -#define MOZ_LIBFUZZER_INTERFACE_RAW(initFunc, testFunc, moduleName) \ - static void __attribute__ ((constructor)) LibFuzzerRegister##moduleName() { \ - ::mozilla::FuzzerRegistry::getInstance().registerModule( \ - #moduleName, initFunc, testFunc \ - ); \ +#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 \ + ); \ } #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/FuzzingInterfaceStream.h b/tools/fuzzing/interface/FuzzingInterfaceStream.h deleted file mode 100644 index 985d94c12e83..000000000000 --- a/tools/fuzzing/interface/FuzzingInterfaceStream.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- 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 deleted file mode 100644 index 57054482e281..000000000000 --- a/tools/fuzzing/interface/harness/FuzzerRunner.cpp +++ /dev/null @@ -1,73 +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 "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/interface/moz.build b/tools/fuzzing/interface/moz.build index 56e86846500b..6b2bb968cf56 100644 --- a/tools/fuzzing/interface/moz.build +++ b/tools/fuzzing/interface/moz.build @@ -4,25 +4,12 @@ # 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', ] -if CONFIG['JS_STANDALONE']: - FINAL_LIBRARY = "js" -else: - EXPORTS += [ - 'FuzzingInterfaceStream.h', - ] +SOURCES += [ + 'FuzzingInterface.cpp', +] - SOURCES += [ - 'FuzzingInterfaceStream.cpp', - ] - - DIRS += [ - 'harness', - ] - - FINAL_LIBRARY = 'xul-gtest' +FINAL_LIBRARY = 'xul-gtest' diff --git a/tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.cpp b/tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.cpp new file mode 100644 index 000000000000..a758067b5783 --- /dev/null +++ b/tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.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 "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 new file mode 100644 index 000000000000..a2f81d7358e3 --- /dev/null +++ b/tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.h @@ -0,0 +1,42 @@ +/* -*- 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 new file mode 100644 index 000000000000..c06d36dbe35c --- /dev/null +++ b/tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.cpp @@ -0,0 +1,53 @@ +/* -*- 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/interface/harness/FuzzerRunner.h b/tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.h similarity index 81% rename from tools/fuzzing/interface/harness/FuzzerRunner.h rename to tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.h index c19662fcb3b8..8ccff40e72a8 100644 --- a/tools/fuzzing/interface/harness/FuzzerRunner.h +++ b/tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.h @@ -3,22 +3,19 @@ * * 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" +#include "LibFuzzerRegistry.h" namespace mozilla { -class FuzzerRunner { +class LibFuzzerRunner { public: int Run(int* argc, char*** argv); - -#ifdef LIBFUZZER void setParams(LibFuzzerDriver aDriver); private: LibFuzzerDriver mFuzzerDriver; -#endif }; -extern FuzzerRunner* fuzzerRunner; +extern LibFuzzerRunner* libFuzzerRunner; } // namespace mozilla diff --git a/tools/fuzzing/interface/harness/FuzzerTestHarness.h b/tools/fuzzing/libfuzzer/harness/LibFuzzerTestHarness.h similarity index 98% rename from tools/fuzzing/interface/harness/FuzzerTestHarness.h rename to tools/fuzzing/libfuzzer/harness/LibFuzzerTestHarness.h index 456344478782..a242a3786c54 100644 --- a/tools/fuzzing/interface/harness/FuzzerTestHarness.h +++ b/tools/fuzzing/libfuzzer/harness/LibFuzzerTestHarness.h @@ -9,8 +9,8 @@ * and stdio.h/stdlib.h. */ -#ifndef FuzzerTestHarness_h__ -#define FuzzerTestHarness_h__ +#ifndef LibFuzzerTestHarness_h__ +#define LibFuzzerTestHarness_h__ #include "mozilla/ArrayUtils.h" #include "mozilla/Attributes.h" @@ -273,4 +273,4 @@ ScopedXPCOM::Release() } // namespace -#endif // FuzzerTestHarness_h__ +#endif // LibFuzzerTestHarness_h__ diff --git a/tools/fuzzing/interface/harness/moz.build b/tools/fuzzing/libfuzzer/harness/moz.build similarity index 78% rename from tools/fuzzing/interface/harness/moz.build rename to tools/fuzzing/libfuzzer/harness/moz.build index e243fecb19bf..596018cb3c74 100644 --- a/tools/fuzzing/interface/harness/moz.build +++ b/tools/fuzzing/libfuzzer/harness/moz.build @@ -7,10 +7,13 @@ Library('fuzzer-runner') SOURCES += [ - 'FuzzerRunner.cpp', + 'LibFuzzerRegistry.cpp', + 'LibFuzzerRunner.cpp', ] + EXPORTS += [ - 'FuzzerRunner.h', + 'LibFuzzerRegistry.h', + 'LibFuzzerRunner.h', ] FINAL_LIBRARY = "xul" diff --git a/tools/fuzzing/libfuzzer/moz.build b/tools/fuzzing/libfuzzer/moz.build index 57869a183b3b..dc9616da1991 100644 --- a/tools/fuzzing/libfuzzer/moz.build +++ b/tools/fuzzing/libfuzzer/moz.build @@ -6,8 +6,8 @@ Library('fuzzer') -EXPORTS += [ - 'FuzzerDefs.h', +DIRS += [ + 'harness', ] SOURCES += [ diff --git a/tools/fuzzing/moz.build b/tools/fuzzing/moz.build index 8a42fde4c08a..bc867068ac3a 100644 --- a/tools/fuzzing/moz.build +++ b/tools/fuzzing/moz.build @@ -5,17 +5,12 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. DIRS += [ + 'common', 'interface', - 'registry', + 'messagemanager', + 'shmem' ] -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 deleted file mode 100644 index aad2b010344f..000000000000 --- a/tools/fuzzing/registry/FuzzerRegistry.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 "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 deleted file mode 100644 index caf45629a6d1..000000000000 --- a/tools/fuzzing/registry/FuzzerRegistry.h +++ /dev/null @@ -1,43 +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 _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 deleted file mode 100644 index c028418330a2..000000000000 --- a/tools/fuzzing/registry/moz.build +++ /dev/null @@ -1,20 +0,0 @@ -# -*- 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 77f757d30fb7..b0f67c169a37 100644 --- a/xpcom/build/nsXULAppAPI.h +++ b/xpcom/build/nsXULAppAPI.h @@ -513,7 +513,7 @@ XRE_API(int, const XREShellData* aShellData)) #ifdef LIBFUZZER -#include "FuzzerRegistry.h" +#include "LibFuzzerRegistry.h" XRE_API(void, XRE_LibFuzzerSetDriver, (LibFuzzerDriver))