Backed out 2 changesets (bug 1431090) for Bf bustage at src/tools/fuzzing/interface/harness/FuzzerTestHarness.h

Backed out changeset 2e98bda3f397 (bug 1431090)
Backed out changeset eb6acc9e44ad (bug 1431090)

--HG--
rename : tools/fuzzing/registry/FuzzerRegistry.cpp => tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.cpp
rename : tools/fuzzing/registry/FuzzerRegistry.h => tools/fuzzing/libfuzzer/harness/LibFuzzerRegistry.h
rename : tools/fuzzing/interface/harness/FuzzerRunner.cpp => tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.cpp
rename : tools/fuzzing/interface/harness/FuzzerRunner.h => tools/fuzzing/libfuzzer/harness/LibFuzzerRunner.h
rename : tools/fuzzing/interface/harness/FuzzerTestHarness.h => tools/fuzzing/libfuzzer/harness/LibFuzzerTestHarness.h
rename : tools/fuzzing/interface/harness/moz.build => tools/fuzzing/libfuzzer/harness/moz.build
This commit is contained in:
Coroiu Cristina 2018-01-23 13:49:26 +02:00
parent 08e812cc03
commit faa2f8c7da
29 changed files with 232 additions and 685 deletions

View File

@ -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

View File

@ -20,7 +20,7 @@
#include "nsString.h"
#include "nsThreadUtils.h"
#include "FuzzingInterfaceStream.h"
#include "FuzzingInterface.h"
using namespace mozilla;
using namespace mozilla::gfx;

View File

@ -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/',
]

View File

@ -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 <regular AFL options> -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

View File

@ -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

View File

@ -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 */
);

View File

@ -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 <stdio.h>
#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;
}

View File

@ -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 <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "FuzzingInterface.h"
#include "jscntxt.h"
#endif /* fuzz_tests_tests_h */

View File

@ -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

View File

@ -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',
]

View File

@ -9,6 +9,7 @@
#include "gtest/gtest.h"
#include "FuzzingInterface.h"
#include "LibFuzzerRegistry.h"
extern "C" {
#include <csi_platform.h>

View File

@ -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

View File

@ -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<nsIProperties> 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

View File

@ -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 <fstream>
#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<nsIInputStream>);
#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<nsIInputStream> 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);

View File

@ -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 <fstream>
#include "FuzzingInterface.h"
namespace mozilla {
typedef int(*FuzzingTestFuncStream)(nsCOMPtr<nsIInputStream>);
#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<nsIInputStream> 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__

View File

@ -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 <cstdlib>
#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

View File

@ -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'

View File

@ -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<std::string, LibFuzzerFunctions>(moduleName,LibFuzzerFunctions(initFunc, testingFunc)));
}
LibFuzzerFunctions LibFuzzerRegistry::getModuleFunctions(std::string& moduleName) {
return moduleMap[moduleName];
}
} // namespace mozilla

View File

@ -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 <cstdint>
#include <map>
#include <string>
#include <utility>
#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<LibFuzzerInitFunc, LibFuzzerTestingFunc> 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<std::string, LibFuzzerFunctions> moduleMap;
};
} // namespace mozilla
#endif // _LibFuzzerRegistry_h__

View File

@ -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 <cstdlib>
#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

View File

@ -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

View File

@ -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__

View File

@ -7,10 +7,13 @@
Library('fuzzer-runner')
SOURCES += [
'FuzzerRunner.cpp',
'LibFuzzerRegistry.cpp',
'LibFuzzerRunner.cpp',
]
EXPORTS += [
'FuzzerRunner.h',
'LibFuzzerRegistry.h',
'LibFuzzerRunner.h',
]
FINAL_LIBRARY = "xul"

View File

@ -6,8 +6,8 @@
Library('fuzzer')
EXPORTS += [
'FuzzerDefs.h',
DIRS += [
'harness',
]
SOURCES += [

View File

@ -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',

View File

@ -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<std::string, FuzzerFunctions>(moduleName,FuzzerFunctions(initFunc, testingFunc)));
}
FuzzerFunctions FuzzerRegistry::getModuleFunctions(std::string& moduleName) {
return moduleMap[moduleName];
}
} // namespace mozilla

View File

@ -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 <cstdint>
#include <map>
#include <string>
#include <utility>
#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<FuzzerInitFunc, FuzzerTestingFunc> 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<std::string, FuzzerFunctions> moduleMap;
};
} // namespace mozilla
#endif // _FuzzerRegistry_h__

View File

@ -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"

View File

@ -513,7 +513,7 @@ XRE_API(int,
const XREShellData* aShellData))
#ifdef LIBFUZZER
#include "FuzzerRegistry.h"
#include "LibFuzzerRegistry.h"
XRE_API(void,
XRE_LibFuzzerSetDriver, (LibFuzzerDriver))