Bug 1879171 - Add AFL++ fuzzing build r=decoder,taskgraph-reviewers,bhearsum

Differential Revision: https://phabricator.services.mozilla.com/D208401
This commit is contained in:
cat 2024-04-25 22:16:22 +00:00
Родитель 599c8b98ba
Коммит bcc2c75572
12 изменённых файлов: 116 добавлений и 137 удалений

Просмотреть файл

@ -62,6 +62,8 @@ if CONFIG["LIBFUZZER"]:
LOCAL_INCLUDES += [
"/tools/fuzzing/libfuzzer",
]
elif CONFIG["FUZZING_INTERFACES"]:
USE_LIBS += ["fuzzer-interface"]
if CONFIG["MOZ_GECKODRIVER"]:
DEFINES["MOZ_GECKODRIVER"] = True

Просмотреть файл

@ -0,0 +1,9 @@
. "$topsrcdir/browser/config/mozconfigs/linux64/nightly-fuzzing-asan"
export CC="$MOZ_FETCHES_DIR/afl-instrumentation/bin/afl-clang-fast"
export CXX="$MOZ_FETCHES_DIR/afl-instrumentation/bin/afl-clang-fast++"
export HOST_CC="$MOZ_FETCHES_DIR/clang/bin/clang"
export HOST_CXX="$MOZ_FETCHES_DIR/clang/bin/clang++"
. "$topsrcdir/build/mozconfig.common.override"

Просмотреть файл

@ -33,9 +33,10 @@ if CONFIG["FUZZING"]:
include("/tools/fuzzing/libfuzzer-config.mozbuild")
if CONFIG["FUZZING_INTERFACES"]:
USE_LIBS += [
"static:fuzzer",
]
if CONFIG["LIBFUZZER"]:
USE_LIBS += ["static:fuzzer"]
else:
USE_LIBS += ["static:fuzzer-interface"]
USE_LIBS += [
"static:js",

Просмотреть файл

@ -11,8 +11,10 @@
#include <stdio.h> // fflush, fprintf, fputs
#include "FuzzerDefs.h"
#include "FuzzingInterface.h"
#ifdef LIBFUZZER
# include "FuzzerDefs.h"
#endif
#include "jsapi.h" // JS_ClearPendingException, JS_IsExceptionPending
#include "js/CompilationAndEvaluation.h" // JS::Evaluate

Просмотреть файл

@ -26,9 +26,10 @@ UNIFIED_SOURCES += [
if CONFIG["FUZZING_INTERFACES"]:
UNIFIED_SOURCES += ["jsrtfuzzing/jsrtfuzzing.cpp"]
USE_LIBS += [
"static:fuzzer",
]
if CONFIG["LIBFUZZER"]:
USE_LIBS += ["static:fuzzer"]
else:
USE_LIBS += ["static:fuzzer-interface"]
if CONFIG["FUZZING_JS_FUZZILLI"]:
OS_LIBS += ["rt"]

Просмотреть файл

@ -10,8 +10,11 @@ SOURCES += [
"xpcshell.cpp",
]
if CONFIG["LIBFUZZER"]:
USE_LIBS += ["fuzzer"]
if CONFIG["FUZZING_INTERFACES"]:
if CONFIG["LIBFUZZER"]:
USE_LIBS += ["fuzzer"]
else:
USE_LIBS += ["fuzzer-interface"]
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
SOURCES += [

Просмотреть файл

@ -1084,6 +1084,56 @@ linux64-asan-fuzzing/noopt:
optimization:
skip-unless-expanded: null
linux64-asan-fuzzing-afl/opt:
description: "Linux64 Fuzzing Opt ASAN AFL"
index:
product: firefox
job-name: linux64-fuzzing-asan-afl-opt
attributes:
# The gtest libxul contains libFuzzer targets
skip-verify-test-packaging: true
treeherder:
platform: linux64/asan
symbol: Boaf
worker:
env:
PERFHERDER_EXTRA_OPTIONS: asan-fuzzing-afl
MOZ_AUTOMATION_PACKAGE_TESTS: "1"
AFL_CC: /builds/worker/fetches/clang/bin/clang
AFL_CXX: /builds/worker/fetches/clang/bin/clang++
AFL_LLVM_INSTRUMENT: llvmnative
AFL_LLVM_NO_RPATH: "1"
max-run-time: 7200
run:
using: mozharness
actions: [get-secrets, build]
config:
- builds/releng_base_firefox.py
- builds/releng_base_linux_64_builds.py
script: "mozharness/scripts/fx_desktop_build.py"
secrets: true
custom-build-variant-cfg: fuzzing-asan-tc
mozconfig-variant: nightly-fuzzing-asan-afl
tooltool-downloads: public
use-sccache: true
fetches:
toolchain:
- linux64-afl-instrumentation
- linux64-clang
- linux64-rust-dev
- linux64-rust-size
- linux64-cbindgen
- linux64-dump_syms
- linux64-llvm-symbolizer
- linux64-sccache
- linux64-nasm
- linux64-node
- linux64-pkgconf
- sysroot-x86_64-linux-gnu
- sysroot-wasm32-wasi
optimization:
skip-unless-expanded: null
linux64-asan-fuzzing-nyx/opt:
description: "Linux64 Fuzzing Opt ASAN NYX"
index:

Просмотреть файл

@ -28,3 +28,21 @@ LazyLogModule gFuzzingLog("nsFuzzing");
#endif
} // namespace mozilla
#ifdef AFLFUZZ
__AFL_FUZZ_INIT();
int afl_interface_raw(FuzzingTestFuncRaw testFunc) {
# ifdef __AFL_HAVE_MANUAL_CONTROL
__AFL_INIT();
# endif
uint8_t* buf = __AFL_FUZZ_TESTCASE_BUF;
while (__AFL_LOOP(1000)) {
size_t len = __AFL_FUZZ_TESTCASE_LEN;
testFunc(buf, len);
}
return 0;
}
#endif // AFLFUZZ

Просмотреть файл

@ -37,55 +37,17 @@ extern LazyLogModule gFuzzingLog;
MOZ_LOG(mozilla::gFuzzingLog, mozilla::LogLevel::Verbose, args)
#endif // JS_STANDALONE
} // namespace mozilla
typedef int (*FuzzingTestFuncRaw)(const uint8_t*, size_t);
#ifdef AFLFUZZ
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) { \
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);
int afl_interface_raw(FuzzingTestFuncRaw 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); \
return afl_interface_raw(testFunc); \
} \
static void __attribute__((constructor)) AFLRegister##moduleName() { \
::mozilla::FuzzerRegistry::getInstance().registerModule( \
@ -110,6 +72,4 @@ static int afl_interface_raw(const char* testFile,
MOZ_LIBFUZZER_INTERFACE_RAW(initFunc, testFunc, moduleName); \
MOZ_AFL_INTERFACE_RAW(initFunc, testFunc, moduleName);
} // namespace mozilla
#endif // FuzzingInterface_h__

Просмотреть файл

@ -1,54 +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/. */
/*
* Interface implementation for the unified fuzzing interface
*/
#include "nsIFile.h"
#include "nsIPrefService.h"
#include "nsIProperties.h"
#include "FuzzingInterfaceStream.h"
#include "mozilla/Assertions.h"
#ifndef JS_STANDALONE
# include "nsNetUtil.h"
#endif
namespace mozilla {
#ifdef AFLFUZZ
void afl_interface_stream(const char* testFile,
FuzzingTestFuncStream testFunc) {
nsresult rv;
nsCOMPtr<nsIProperties> dirService =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
MOZ_RELEASE_ASSERT(dirService != nullptr);
nsCOMPtr<nsIFile> file;
rv = dirService->Get(NS_OS_CURRENT_WORKING_DIR, NS_GET_IID(nsIFile),
getter_AddRefs(file));
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
file->AppendNative(nsDependentCString(testFile));
while (__AFL_LOOP(1000)) {
nsCOMPtr<nsIInputStream> inputStream;
rv = NS_NewLocalFileInputStream(getter_AddRefs(inputStream), file);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
if (!NS_InputStreamIsBuffered(inputStream)) {
nsCOMPtr<nsIInputStream> bufStream;
rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream),
inputStream.forget(), 1024);
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
inputStream = bufStream;
}
testFunc(inputStream.forget());
}
}
#endif
} // namespace mozilla

Просмотреть файл

@ -28,32 +28,25 @@
#include "FuzzingInterface.h"
namespace mozilla {
typedef int (*FuzzingTestFuncStream)(nsCOMPtr<nsIInputStream>);
#ifdef AFLFUZZ
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); \
# define MOZ_AFL_INTERFACE_STREAM(initFunc, testFunc, moduleName) \
static int afl_fuzz_inner_##moduleName(const uint8_t* data, size_t size) { \
if (size > INT32_MAX) return 0; \
nsCOMPtr<nsIInputStream> stream; \
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), \
Span((const char*)data, size), \
NS_ASSIGNMENT_DEPEND); \
MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); \
return testFunc(stream.forget()); \
} \
static int afl_fuzz_##moduleName(const uint8_t* data, size_t size) { \
return afl_interface_raw(afl_fuzz_inner_##moduleName); \
} \
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 \
@ -85,6 +78,4 @@ void afl_interface_stream(const char* testFile, FuzzingTestFuncStream testFunc);
MOZ_LIBFUZZER_INTERFACE_STREAM(initFunc, testFunc, moduleName); \
MOZ_AFL_INTERFACE_STREAM(initFunc, testFunc, moduleName);
} // namespace mozilla
#endif // FuzzingInterfaceStream_h__

Просмотреть файл

@ -21,10 +21,6 @@ else:
"FuzzingInterfaceStream.h",
]
SOURCES += [
"FuzzingInterfaceStream.cpp",
]
DIRS += [
"harness",
]