Bug 1431439 - Add StructuredCloneReader fuzzing target. r=sfink,jandem

--HG--
extra : rebase_source : 74c309e28cdc2f7060dab0c0abba8a6556652c32
This commit is contained in:
Christian Holler 2018-01-17 17:06:11 +01:00
Родитель 8831866d46
Коммит a5332611aa
3 изменённых файлов: 111 добавлений и 9 удалений

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

@ -9,6 +9,7 @@ GeckoProgram('fuzz-tests', linkage=None)
UNIFIED_SOURCES += [
'testExample.cpp',
'tests.cpp',
'testStructuredCloneReader.cpp',
]
if CONFIG['JS_BUILD_BINAST']:

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

@ -0,0 +1,86 @@
/* -*- 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 "vm/JSContext-inl.h"
using namespace js;
// These are defined and pre-initialized by the harness (in tests.cpp).
extern JS::PersistentRootedObject gGlobal;
extern JSContext* gCx;
static int
testStructuredCloneReaderInit(int *argc, char ***argv) {
return 0;
}
static int
testStructuredCloneReaderFuzz(const uint8_t* buf, size_t size) {
auto gcGuard = mozilla::MakeScopeExit([&] {
JS::PrepareForFullGC(gCx);
JS::GCForReason(gCx, GC_NORMAL, JS::gcreason::API);
});
if (!size) return 0;
// Make sure to pad the buffer to a multiple of kSegmentAlignment
const size_t kSegmentAlignment = 8;
size_t buf_size = JS_ROUNDUP(size, kSegmentAlignment);
auto clonebuf = MakeUnique<JSStructuredCloneData>(0, 0, buf_size);
if (!clonebuf || !clonebuf->Init(buf_size, buf_size)) {
ReportOutOfMemory(gCx);
return 0;
}
// Initialize with zeros, including padding, then copy buffer
memset(clonebuf->Start(), '\0', buf_size);
js_memcpy(clonebuf->Start(), buf, size);
JS::StructuredCloneScope scope = JS::StructuredCloneScope::DifferentProcess;
RootedValue deserialized(gCx);
if (!JS_ReadStructuredClone(gCx, *clonebuf,
JS_STRUCTURED_CLONE_VERSION,
scope,
&deserialized, nullptr, nullptr))
{
return 0;
}
/* If we succeeded in deserializing, we should try to reserialize the data.
This has two main advantages:
1) It tests parts of the serializer as well.
2) The deserialized data is actually used, making it more likely to detect
further memory-related problems.
Tests show that this also doesn't cause a serious performance penalty.
*/
mozilla::Maybe<JSAutoStructuredCloneBuffer> clonebufOut;
JS::CloneDataPolicy policy;
clonebufOut.emplace(scope, nullptr, nullptr);
if (!clonebufOut->write(gCx, deserialized, UndefinedHandleValue, policy))
return 0;
return 0;
}
MOZ_FUZZING_INTERFACE_RAW(
testStructuredCloneReaderInit,
testStructuredCloneReaderFuzz,
StructuredCloneReader
);

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

@ -49,15 +49,31 @@ if not CONFIG['JS_DISABLE_SHELL']:
TEST_DIRS += ['jsapi-tests', 'tests', 'gdb']
if CONFIG['FUZZING_INTERFACES']:
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',
]
if CONFIG['FUZZING_INTERFACES'] and CONFIG['LIBFUZZER']:
# In addition to regular coverage provided by trace-pc-guard,
# LibFuzzer can use trace-cmp to instrument various compare instructions.
# Only use this feature on source files that do a lot of constant
# comparisons that would otherwise be hard to guess by LibFuzzer,
# as it comes with a larger overhead (requires -use_value_profile=1).
libfuzzer_flags = ['-fsanitize-coverage=trace-pc-guard']
libfuzzer_flags_cmp = ['-fsanitize-coverage=trace-pc-guard', '-fsanitize-coverage=trace-cmp']
# Any files that are targeted by LibFuzzer should be added here so they can
# be built with the necessary instrumentation flags, rather than just building
# the whole JS engine with instrumentation, to reduce the amount of noise.
SOURCES += [
'vm/StructuredClone.cpp',
]
SOURCES['vm/StructuredClone.cpp'].flags += libfuzzer_flags_cmp
else:
UNIFIED_SOURCES += [
'vm/StructuredClone.cpp',
]
CONFIGURE_SUBST_FILES += [
'devtools/rootAnalysis/Makefile',
]
@ -374,7 +390,6 @@ UNIFIED_SOURCES += [
'vm/Stack.cpp',
'vm/Stopwatch.cpp',
'vm/StringType.cpp',
'vm/StructuredClone.cpp',
'vm/SymbolType.cpp',
'vm/TaggedProto.cpp',
'vm/Time.cpp',
@ -697,9 +712,9 @@ if CONFIG['JS_BUILD_BINAST']:
# Instrument BinAST files for fuzzing as we have a fuzzing target for BinAST.
if CONFIG['FUZZING_INTERFACES'] and CONFIG['LIBFUZZER']:
SOURCES['frontend/BinSource.cpp'].flags += ['-fsanitize-coverage=trace-pc-guard']
SOURCES['frontend/BinToken.cpp'].flags += ['-fsanitize-coverage=trace-pc-guard']
SOURCES['frontend/BinTokenReaderTester.cpp'].flags += ['-fsanitize-coverage=trace-pc-guard']
SOURCES['frontend/BinSource.cpp'].flags += libfuzzer_flags_cmp
SOURCES['frontend/BinToken.cpp'].flags += libfuzzer_flags_cmp
SOURCES['frontend/BinTokenReaderTester.cpp'].flags += libfuzzer_flags_cmp
# Wasm code should use WASM_HUGE_MEMORY instead of JS_CODEGEN_X64
# so that it is easy to use the huge-mapping optimization for other