mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-26 23:01:05 +08:00
Add libfuzzer support
Adds the build support for using libfuzzer controlled by setting `crashpad_use_libfuzzer=true`. Also adds a first fuzzer (for ElfImageReader). Currently only runs on Linux, but should work on Fuchsia too with some minor fixes (not sure yet whether the fixes required are toolchain or in our build setup). Run as: out/lin/elf_image_reader_fuzzer snapshot/elf/elf_image_reader_fuzzer_corpus/ hits an OOM pretty quickly in trying to allocate a giant buffer. Bug: crashpad:30, crashpad:196, crashpad:233 Change-Id: Idd3ca11fe00319b8b29e029d5e13b17bfd518ea0 Reviewed-on: https://chromium-review.googlesource.com/1083451 Reviewed-by: Robert Sesek <rsesek@chromium.org> Reviewed-by: Joshua Peraza <jperaza@chromium.org> Commit-Queue: Scott Graham <scottmg@chromium.org>
This commit is contained in:
parent
3edb7869da
commit
9a97daff39
1
.gitignore
vendored
1
.gitignore
vendored
@ -15,6 +15,7 @@
|
||||
/third_party/fuchsia/qemu
|
||||
/third_party/fuchsia/sdk
|
||||
/third_party/gtest/gtest
|
||||
/third_party/libfuzzer
|
||||
/third_party/linux/.cipd
|
||||
/third_party/linux/clang
|
||||
/third_party/linux/sysroot
|
||||
|
3
DEPS
3
DEPS
@ -30,6 +30,9 @@ deps = {
|
||||
'crashpad/third_party/mini_chromium/mini_chromium':
|
||||
Var('chromium_git') + '/chromium/mini_chromium@' +
|
||||
'd5a36d3c51a7a270afc2c888baaaec2a6e496219',
|
||||
'crashpad/third_party/libfuzzer/src':
|
||||
Var('chromium_git') + '/chromium/llvm-project/compiler-rt/lib/fuzzer.git@' +
|
||||
'fda403cf93ecb8792cb1d061564d89a6553ca020',
|
||||
'crashpad/third_party/zlib/zlib':
|
||||
Var('chromium_git') + '/chromium/src/third_party/zlib@' +
|
||||
'13dc246a58e4b72104d35f9b1809af95221ebda7',
|
||||
|
@ -37,3 +37,15 @@ group("default_exe_manifest_win") {
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
config("crashpad_fuzzer_flags") {
|
||||
cflags = [
|
||||
"-fsanitize=address",
|
||||
"-fsanitize-address-use-after-scope",
|
||||
"-fsanitize=fuzzer",
|
||||
]
|
||||
|
||||
ldflags = [
|
||||
"-fsanitize=address",
|
||||
]
|
||||
}
|
||||
|
@ -46,6 +46,10 @@ declare_args() {
|
||||
# and logging. When false, enables the release configuration, with additional
|
||||
# optimizations.
|
||||
is_debug = false
|
||||
|
||||
# When true, build all code with -fsanitize=fuzzer, and enable various
|
||||
# *_fuzzer targets.
|
||||
crashpad_use_libfuzzer = false
|
||||
}
|
||||
|
||||
_default_configs = [
|
||||
@ -53,6 +57,10 @@ _default_configs = [
|
||||
"//third_party/mini_chromium/mini_chromium/build:Wexit_time_destructors",
|
||||
]
|
||||
|
||||
if (crashpad_use_libfuzzer) {
|
||||
_default_configs += [ "//build:crashpad_fuzzer_flags" ]
|
||||
}
|
||||
|
||||
_default_executable_configs =
|
||||
_default_configs + [
|
||||
"//third_party/mini_chromium/mini_chromium/build:executable",
|
||||
|
46
build/crashpad_fuzzer_test.gni
Normal file
46
build/crashpad_fuzzer_test.gni
Normal file
@ -0,0 +1,46 @@
|
||||
# Copyright 2018 The Crashpad Authors. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import("crashpad_buildconfig.gni")
|
||||
import("test.gni")
|
||||
|
||||
template("fuzzer_test") {
|
||||
if (crashpad_is_standalone && crashpad_use_libfuzzer) {
|
||||
test(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"cflags",
|
||||
"cflags_cc",
|
||||
"check_includes",
|
||||
"defines",
|
||||
"include_dirs",
|
||||
"sources",
|
||||
])
|
||||
configs += [ "..:crashpad_config" ]
|
||||
if (defined(invoker.deps)) {
|
||||
deps = invoker.deps
|
||||
}
|
||||
deps += [ "../third_party/libfuzzer" ]
|
||||
|
||||
if (!defined(invoker.cflags)) {
|
||||
cflags = []
|
||||
}
|
||||
cflags += [ "-fsanitize=fuzzer" ]
|
||||
}
|
||||
} else {
|
||||
not_needed(invoker, "*")
|
||||
group(target_name) {
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import("../build/crashpad_buildconfig.gni")
|
||||
import("../build/crashpad_fuzzer_test.gni")
|
||||
|
||||
if (crashpad_is_in_chromium) {
|
||||
import("//build/config/compiler/compiler.gni")
|
||||
@ -238,6 +239,17 @@ if (crashpad_is_win) {
|
||||
}
|
||||
}
|
||||
|
||||
fuzzer_test("elf_image_reader_fuzzer") {
|
||||
sources = [
|
||||
"elf/elf_image_reader_fuzzer.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":snapshot",
|
||||
"../third_party/mini_chromium:base",
|
||||
]
|
||||
}
|
||||
|
||||
static_library("test_support") {
|
||||
testonly = true
|
||||
|
||||
|
75
snapshot/elf/elf_image_reader_fuzzer.cc
Normal file
75
snapshot/elf/elf_image_reader_fuzzer.cc
Normal file
@ -0,0 +1,75 @@
|
||||
// Copyright 2018 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "snapshot/elf/elf_image_reader.h"
|
||||
#include "util/process/process_memory.h"
|
||||
|
||||
using namespace crashpad;
|
||||
|
||||
class FakeProcessMemory : public ProcessMemory {
|
||||
public:
|
||||
FakeProcessMemory(const uint8_t* data, size_t size, VMAddress fake_base)
|
||||
: data_(data), size_(size), fake_base_(fake_base) {}
|
||||
|
||||
ssize_t ReadUpTo(VMAddress address,
|
||||
size_t size,
|
||||
void* buffer) const override {
|
||||
VMAddress offset_in_data = address - fake_base_;
|
||||
if (offset_in_data > size_)
|
||||
return -1;
|
||||
ssize_t read_size = std::min(size_ - offset_in_data, size);
|
||||
memcpy(buffer, &data_[offset_in_data], read_size);
|
||||
return read_size;
|
||||
}
|
||||
|
||||
private:
|
||||
const uint8_t* data_;
|
||||
size_t size_;
|
||||
VMAddress fake_base_;
|
||||
};
|
||||
|
||||
extern "C" int LLVMFuzzerInitialize(int* argc, char*** argv) {
|
||||
// Swallow all logs to avoid spam.
|
||||
logging::SetLogMessageHandler(
|
||||
[](logging::LogSeverity, const char*, int, size_t, const std::string&) {
|
||||
return true;
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||
constexpr size_t kBase = 0x10000;
|
||||
FakeProcessMemory process_memory(data, size, kBase);
|
||||
ProcessMemoryRange process_memory_range;
|
||||
process_memory_range.Initialize(&process_memory, true, kBase, size);
|
||||
|
||||
ElfImageReader reader;
|
||||
if (!reader.Initialize(process_memory_range, kBase))
|
||||
return 0;
|
||||
|
||||
ElfImageReader::NoteReader::Result result;
|
||||
std::string note_name;
|
||||
std::string note_desc;
|
||||
ElfImageReader::NoteReader::NoteType note_type;
|
||||
auto notes = reader.Notes(-1);
|
||||
while ((result = notes->NextNote(¬e_name, ¬e_type, ¬e_desc)) ==
|
||||
ElfImageReader::NoteReader::Result::kSuccess) {
|
||||
LOG(ERROR) << note_name << note_type << note_desc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Binary file not shown.
BIN
snapshot/elf/elf_image_reader_fuzzer_corpus/ret42
Executable file
BIN
snapshot/elf/elf_image_reader_fuzzer_corpus/ret42
Executable file
Binary file not shown.
49
third_party/libfuzzer/BUILD.gn
vendored
Normal file
49
third_party/libfuzzer/BUILD.gn
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
# Copyright 2018 The Crashpad Authors. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
source_set("libfuzzer") {
|
||||
if (crashpad_use_libfuzzer) {
|
||||
sources = [
|
||||
"src/FuzzerClangCounters.cpp",
|
||||
"src/FuzzerCrossOver.cpp",
|
||||
"src/FuzzerDriver.cpp",
|
||||
"src/FuzzerExtFunctionsDlsym.cpp",
|
||||
"src/FuzzerExtFunctionsDlsymWin.cpp",
|
||||
"src/FuzzerExtFunctionsWeak.cpp",
|
||||
"src/FuzzerExtFunctionsWeakAlias.cpp",
|
||||
"src/FuzzerExtraCounters.cpp",
|
||||
"src/FuzzerIO.cpp",
|
||||
"src/FuzzerIOPosix.cpp",
|
||||
"src/FuzzerIOWindows.cpp",
|
||||
"src/FuzzerLoop.cpp",
|
||||
"src/FuzzerMain.cpp",
|
||||
"src/FuzzerMerge.cpp",
|
||||
"src/FuzzerMutate.cpp",
|
||||
"src/FuzzerSHA1.cpp",
|
||||
"src/FuzzerShmemPosix.cpp",
|
||||
"src/FuzzerShmemWindows.cpp",
|
||||
"src/FuzzerTracePC.cpp",
|
||||
"src/FuzzerUtil.cpp",
|
||||
"src/FuzzerUtilDarwin.cpp",
|
||||
"src/FuzzerUtilLinux.cpp",
|
||||
"src/FuzzerUtilPosix.cpp",
|
||||
"src/FuzzerUtilWindows.cpp",
|
||||
]
|
||||
|
||||
configs -= [
|
||||
"//third_party/mini_chromium/mini_chromium/build:Wexit_time_destructors",
|
||||
"//build:crashpad_fuzzer_flags",
|
||||
]
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user