Commit b8488871 authored by Joshua Peraza's avatar Joshua Peraza Committed by Commit Bot

Update Crashpad to 0cccdc0b7ec32bd31e789b3945a08c04ef775834

9cd1a4dadb51 doc: Upgrade the crashpad-home App Engine app to the Go
             1.11 runtime
94b7e45210a7 fix OS guards for attachments
2f66eefb7921 Update language to eliminate 'whitelist'
0cccdc0b7ec3 Replace is_linux with is_linux || is_chromeos

Change-Id: Ia91ba57d7051b49d398f3cfa18c335cf6303e993
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2341940
Commit-Queue: Matthew Denton <mpdenton@chromium.org>
Auto-Submit: Joshua Peraza <jperaza@chromium.org>
Reviewed-by: default avatarMark Mentovai <mark@chromium.org>
Reviewed-by: default avatarMatthew Denton <mpdenton@chromium.org>
Cr-Commit-Position: refs/heads/master@{#795766}
parent 00719dda
...@@ -187,10 +187,10 @@ bool CrashReporterClient::ShouldWriteMinidumpToLog() { ...@@ -187,10 +187,10 @@ bool CrashReporterClient::ShouldWriteMinidumpToLog() {
#if defined(OS_ANDROID) || defined(OS_LINUX) #if defined(OS_ANDROID) || defined(OS_LINUX)
void CrashReporterClient::GetSanitizationInformation( void CrashReporterClient::GetSanitizationInformation(
const char* const** annotations_whitelist, const char* const** allowed_annotations,
void** target_module, void** target_module,
bool* sanitize_stacks) { bool* sanitize_stacks) {
*annotations_whitelist = nullptr; *allowed_annotations = nullptr;
*target_module = nullptr; *target_module = nullptr;
*sanitize_stacks = false; *sanitize_stacks = false;
} }
......
...@@ -188,9 +188,9 @@ void DumpProcessWithoutCrashing(task_t task_port); ...@@ -188,9 +188,9 @@ void DumpProcessWithoutCrashing(task_t task_port);
class CrashReporterClient; class CrashReporterClient;
bool DumpWithoutCrashingForClient(CrashReporterClient* client); bool DumpWithoutCrashingForClient(CrashReporterClient* client);
// Used under WebView to whitelist a memory range so it's accessible using // If a CrashReporterClient has enabled sanitization, this function specifies
// crashpad's ProcessMemory interface. // regions of memory which are allowed to be collected by Crashpad.
void WhitelistMemoryRange(void* begin, size_t size); void AllowMemoryRange(void* begin, size_t size);
#endif // OS_ANDROID #endif // OS_ANDROID
#if defined(OS_LINUX) #if defined(OS_LINUX)
......
...@@ -52,56 +52,59 @@ ...@@ -52,56 +52,59 @@
namespace crashpad { namespace crashpad {
namespace { namespace {
class MemoryRangeWhitelist { class AllowedMemoryRanges {
public: public:
MemoryRangeWhitelist() { AllowedMemoryRanges() {
whitelist_.entries = 0; allowed_memory_ranges_.entries = 0;
whitelist_.size = 0; allowed_memory_ranges_.size = 0;
} }
void AddEntry(VMAddress base, VMSize length) { void AddEntry(VMAddress base, VMSize length) {
SanitizationMemoryRangeWhitelist::Range new_entry; SanitizationAllowedMemoryRanges::Range new_entry;
new_entry.base = base; new_entry.base = base;
new_entry.length = length; new_entry.length = length;
base::AutoLock lock(lock_); base::AutoLock lock(lock_);
std::vector<SanitizationMemoryRangeWhitelist::Range> new_array(array_); std::vector<SanitizationAllowedMemoryRanges::Range> new_array(array_);
new_array.push_back(new_entry); new_array.push_back(new_entry);
whitelist_.entries = FromPointerCast<VMAddress>(new_array.data()); allowed_memory_ranges_.entries =
whitelist_.size += 1; FromPointerCast<VMAddress>(new_array.data());
allowed_memory_ranges_.size += 1;
array_ = std::move(new_array); array_ = std::move(new_array);
} }
SanitizationMemoryRangeWhitelist* GetSanitizationAddress() { SanitizationAllowedMemoryRanges* GetSanitizationAddress() {
return &whitelist_; return &allowed_memory_ranges_;
} }
static MemoryRangeWhitelist* Singleton() { static AllowedMemoryRanges* Singleton() {
static base::NoDestructor<MemoryRangeWhitelist> singleton; static base::NoDestructor<AllowedMemoryRanges> singleton;
return singleton.get(); return singleton.get();
} }
private: private:
base::Lock lock_; base::Lock lock_;
SanitizationMemoryRangeWhitelist whitelist_; SanitizationAllowedMemoryRanges allowed_memory_ranges_;
std::vector<SanitizationMemoryRangeWhitelist::Range> array_; std::vector<SanitizationAllowedMemoryRanges::Range> array_;
DISALLOW_COPY_AND_ASSIGN(MemoryRangeWhitelist); DISALLOW_COPY_AND_ASSIGN(AllowedMemoryRanges);
}; };
bool SetSanitizationInfo(crash_reporter::CrashReporterClient* client, bool SetSanitizationInfo(crash_reporter::CrashReporterClient* client,
SanitizationInformation* info) { SanitizationInformation* info) {
const char* const* whitelist = nullptr; const char* const* allowed_annotations = nullptr;
void* target_module = nullptr; void* target_module = nullptr;
bool sanitize_stacks = false; bool sanitize_stacks = false;
client->GetSanitizationInformation(&whitelist, &target_module, client->GetSanitizationInformation(&allowed_annotations, &target_module,
&sanitize_stacks); &sanitize_stacks);
info->annotations_whitelist_address = FromPointerCast<VMAddress>(whitelist); info->allowed_annotations_address =
FromPointerCast<VMAddress>(allowed_annotations);
info->target_module_address = FromPointerCast<VMAddress>(target_module); info->target_module_address = FromPointerCast<VMAddress>(target_module);
info->memory_range_whitelist_address = FromPointerCast<VMAddress>( info->allowed_memory_ranges_address = FromPointerCast<VMAddress>(
MemoryRangeWhitelist::Singleton()->GetSanitizationAddress()); AllowedMemoryRanges::Singleton()->GetSanitizationAddress());
info->sanitize_stacks = sanitize_stacks; info->sanitize_stacks = sanitize_stacks;
return whitelist != nullptr || target_module != nullptr || sanitize_stacks; return allowed_annotations != nullptr || target_module != nullptr ||
sanitize_stacks;
} }
void SetExceptionInformation(siginfo_t* siginfo, void SetExceptionInformation(siginfo_t* siginfo,
...@@ -689,8 +692,8 @@ bool DumpWithoutCrashingForClient(CrashReporterClient* client) { ...@@ -689,8 +692,8 @@ bool DumpWithoutCrashingForClient(CrashReporterClient* client) {
return handler_client.RequestCrashDump(info) == 0; return handler_client.RequestCrashDump(info) == 0;
} }
void WhitelistMemoryRange(void* begin, size_t length) { void AllowMemoryRange(void* begin, size_t length) {
crashpad::MemoryRangeWhitelist::Singleton()->AddEntry( crashpad::AllowedMemoryRanges::Singleton()->AddEntry(
crashpad::FromPointerCast<crashpad::VMAddress>(begin), crashpad::FromPointerCast<crashpad::VMAddress>(begin),
static_cast<crashpad::VMSize>(length)); static_cast<crashpad::VMSize>(length));
} }
......
...@@ -189,11 +189,11 @@ void GuardedPageAllocator::Init(size_t max_alloced_pages, ...@@ -189,11 +189,11 @@ void GuardedPageAllocator::Init(size_t max_alloced_pages,
state_.metadata_addr = reinterpret_cast<uintptr_t>(metadata_.get()); state_.metadata_addr = reinterpret_cast<uintptr_t>(metadata_.get());
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// Explicitly whitelist memory ranges the crash_handler needs to reads. This // Explicitly allow memory ranges the crash_handler needs to read. This is
// is required for WebView because it has a stricter set of privacy // required for WebView because it has a stricter set of privacy constraints
// constraints on what it reads from the crashing process. // on what it reads from the crashing process.
for (auto& region : GetInternalMemoryRegions()) for (auto& region : GetInternalMemoryRegions())
crash_reporter::WhitelistMemoryRange(region.first, region.second); crash_reporter::AllowMemoryRange(region.first, region.second);
#endif #endif
} }
......
...@@ -124,22 +124,22 @@ MULTIPROCESS_TEST_MAIN(CrashingProcess) { ...@@ -124,22 +124,22 @@ MULTIPROCESS_TEST_MAIN(CrashingProcess) {
#if defined(OS_LINUX) || defined(OS_ANDROID) #if defined(OS_LINUX) || defined(OS_ANDROID)
static crashpad::SanitizationInformation sanitization_info = {}; static crashpad::SanitizationInformation sanitization_info = {};
static crashpad::SanitizationMemoryRangeWhitelist memory_whitelist; static crashpad::SanitizationAllowedMemoryRanges allowed_memory_ranges;
if (cmd_line->HasSwitch("sanitize")) { if (cmd_line->HasSwitch("sanitize")) {
auto memory_ranges = gpa->GetInternalMemoryRegions(); auto memory_ranges = gpa->GetInternalMemoryRegions();
auto* range_array = auto* range_array =
new crashpad::SanitizationMemoryRangeWhitelist::Range[memory_ranges new crashpad::SanitizationAllowedMemoryRanges::Range[memory_ranges
.size()]; .size()];
for (size_t i = 0; i < memory_ranges.size(); i++) { for (size_t i = 0; i < memory_ranges.size(); i++) {
range_array[i].base = range_array[i].base =
reinterpret_cast<crashpad::VMAddress>(memory_ranges[i].first); reinterpret_cast<crashpad::VMAddress>(memory_ranges[i].first);
range_array[i].length = memory_ranges[i].second; range_array[i].length = memory_ranges[i].second;
} }
memory_whitelist.size = memory_ranges.size(); allowed_memory_ranges.size = memory_ranges.size();
memory_whitelist.entries = allowed_memory_ranges.entries =
reinterpret_cast<crashpad::VMAddress>(range_array); reinterpret_cast<crashpad::VMAddress>(range_array);
sanitization_info.memory_range_whitelist_address = sanitization_info.allowed_memory_ranges_address =
reinterpret_cast<crashpad::VMAddress>(&memory_whitelist); reinterpret_cast<crashpad::VMAddress>(&allowed_memory_ranges);
arguments.push_back(base::StringPrintf("--sanitization-information=%p", arguments.push_back(base::StringPrintf("--sanitization-information=%p",
&sanitization_info)); &sanitization_info));
} }
......
...@@ -2,7 +2,7 @@ Name: Crashpad ...@@ -2,7 +2,7 @@ Name: Crashpad
Short Name: crashpad Short Name: crashpad
URL: https://crashpad.chromium.org/ URL: https://crashpad.chromium.org/
Version: unknown Version: unknown
Revision: 4ae896bad0af491e183269f5783c2c90a87ba9c9 Revision: 0cccdc0b7ec32bd31e789b3945a08c04ef775834
License: Apache 2.0 License: Apache 2.0
License File: crashpad/LICENSE License File: crashpad/LICENSE
Security Critical: yes Security Critical: yes
......
...@@ -292,7 +292,7 @@ def _RunOnAndroidTarget(binary_dir, test, android_device, extra_command_line): ...@@ -292,7 +292,7 @@ def _RunOnAndroidTarget(binary_dir, test, android_device, extra_command_line):
# pseudo-terminal device, Google Test will not normally enable colored # pseudo-terminal device, Google Test will not normally enable colored
# output, so mimic Google Test’s own logic for deciding whether to # output, so mimic Google Test’s own logic for deciding whether to
# enable color by checking this script’s own standard output connection. # enable color by checking this script’s own standard output connection.
# The whitelist of TERM values comes from Google Test’s # The list of TERM values comes from Google Test’s
# googletest/src/gtest.cc testing::internal::ShouldUseColor(). # googletest/src/gtest.cc testing::internal::ShouldUseColor().
env = {'CRASHPAD_TEST_DATA_ROOT': device_temp_dir} env = {'CRASHPAD_TEST_DATA_ROOT': device_temp_dir}
gtest_color = os.environ.get('GTEST_COLOR') gtest_color = os.environ.get('GTEST_COLOR')
......
This is the App Engine app that serves https://crashpad.chromium.org/. This is the App Engine app that serves https://crashpad.chromium.org/.
To work on this app, obtain the App Engine SDK for Go from To work on this app, obtain the following packages:
https://cloud.google.com/appengine/docs/go/download. Unpacking it produces a
go_appengine directory. This may be added to your $PATH for convenience, - Go, from https://golang.org/dl/. This is only necessary for local development
although it is not necessary. and testing. The directory containing the “go” executable, such as
/usr/local/go/bin, must appear in $PATH. It does not appear critical for the
Go version used to match the Go runtime version used (for example, these
instructions were tested with Go 1.14 locally but a Go 1.11 runtime when
deployed), but if problems are encountered, it would be wise to use the same
version for both local development and AppEngine deployment.
- The Google Cloud SDK from, https://cloud.google.com/sdk/docs. This is
necessary for both local development and for AppEngine deployment. Unpacking
this package produces a google-cloud-sdk directory, whose bin child directory
may be added to $PATH for convenience, although this is not strictly
necessary.
The commands in this README are expected to be run from the directory containing The commands in this README are expected to be run from the directory containing
app.yaml. it. $GOPATH must also be set to include this directory:
The App Engine SDK for Go provides App Engine packages at the “appengine” import % export GOPATH="$(go env GOPATH):$(pwd)"
path, but not the newer “google.golang.org/appengine” path. The Crashpad app
uses the newer paths. See
https://github.com/golang/appengine#2-update-import-paths and
https://code.google.com/p/googleappengine/issues/detail?id=11670. To make these
available, obtain a Go release from https://golang.org/dl/, and run:
$ GOROOT=…/go_appengine/goroot GOPATH=…/go_appengine/gopath go get -d
To test locally: To test locally:
$ …/go_appengine/goapp serve % go get -d crashpad-home
% …/google-cloud-sdk/bin/dev_appserver.py src/crashpad-home
Look for the “Starting module "default" running at: http://localhost:8080” line, Look for the “Starting module "default" running at: http://localhost:8080” line,
which tells you the URL of the local running instance of the app. which tells you the URL of the local running instance of the app. Test
http://localhost:8080/ and http://localhost:8080/doxygen to ensure that they
work.
To deploy: To deploy:
$ version=$(git rev-parse --short=12 HEAD) % version=$(git rev-parse --short=12 HEAD)
$ [[ -n "$(git status --porcelain)" ]] && version+=-dirty % [[ -n "$(git status --porcelain)" ]] && version+=-dirty
$ …/go_appengine/goapp deploy -version "${version}" % …/google-cloud-sdk/bin/gcloud app deploy \
--project=crashpad-home --version="${version}" --no-promote \
"$(pwd)/src/crashpad-home"
Note that app.yaml does not name a “version” to encourage you to use a git hash (Note: the $(pwd) is necessary for “gcloud app deploy” to recognize that the
as the version, as above. application is in GOPATH, putting it into “GOPATH mode”. This normally happens
correctly on its own even with a relative path, but will fail for relative
paths when $(pwd) is a symbolic link. Using an absolute path here will save you
from this frustration, freeing you up to undoubtedly experience other
frustrations.)
Activate a newly-deployed version by visiting the App Engine console at Activate a newly-deployed version by visiting the App Engine console at
https://appengine.google.com/deployment?&app_id=s~crashpad-home, selecting it, https://console.cloud.google.com/appengine/versions?project=crashpad-home,
and choosing “Make Default”. It is also possible to delete old versions from selecting it, and choosing “Migrate Traffic”. It is also possible to delete old
this page when they are no longer needed. versions from this page when they are no longer needed.
application: crashpad-home
runtime: go
api_version: go1
handlers:
- url: /.*
script: _go_app
secure: always
# Copyright 2015 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.
runtime: go111
handlers:
- url: /.*
script: auto
secure: always
...@@ -12,8 +12,7 @@ ...@@ -12,8 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package crashpad mirrors crashpad documentation from Chromium’s git repo. package main
package crashpad
import ( import (
"encoding/base64" "encoding/base64"
...@@ -31,6 +30,10 @@ import ( ...@@ -31,6 +30,10 @@ import (
"google.golang.org/appengine/urlfetch" "google.golang.org/appengine/urlfetch"
) )
func main() {
appengine.Main()
}
func init() { func init() {
http.HandleFunc("/", handler) http.HandleFunc("/", handler)
} }
......
...@@ -95,16 +95,21 @@ namespace crashpad { ...@@ -95,16 +95,21 @@ namespace crashpad {
namespace { namespace {
#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \
defined(OS_ANDROID)
#define ATTACHMENTS_SUPPORTED 1
#endif // OS_WIN || OS_LINUX || OS_CHROMEOS || OS_ANDROID
void Usage(const base::FilePath& me) { void Usage(const base::FilePath& me) {
fprintf(stderr, fprintf(stderr,
"Usage: %" PRFilePath " [OPTION]...\n" "Usage: %" PRFilePath " [OPTION]...\n"
"Crashpad's exception handler server.\n" "Crashpad's exception handler server.\n"
"\n" "\n"
" --annotation=KEY=VALUE set a process annotation in each crash report\n" " --annotation=KEY=VALUE set a process annotation in each crash report\n"
#if defined(OS_WIN) || defined(OS_LINUX) #if defined(ATTACHMENTS_SUPPORTED)
" --attachment=FILE_PATH attach specified file to each crash report\n" " --attachment=FILE_PATH attach specified file to each crash report\n"
" at the time of the crash\n" " at the time of the crash\n"
#endif // OS_WIN || OS_LINUX #endif // ATTACHMENTS_SUPPORTED
" --database=PATH store the crash report database at PATH\n" " --database=PATH store the crash report database at PATH\n"
#if defined(OS_APPLE) #if defined(OS_APPLE)
" --handshake-fd=FD establish communication with the client over FD\n" " --handshake-fd=FD establish communication with the client over FD\n"
...@@ -215,10 +220,9 @@ struct Options { ...@@ -215,10 +220,9 @@ struct Options {
base::FilePath minidump_dir_for_tests; base::FilePath minidump_dir_for_tests;
bool always_allow_feedback = false; bool always_allow_feedback = false;
#endif // OS_CHROMEOS #endif // OS_CHROMEOS
#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ #if defined(ATTACHMENTS_SUPPORTED)
defined(OS_ANDROID)
std::vector<base::FilePath> attachments; std::vector<base::FilePath> attachments;
#endif // OS_WIN || OS_LINUX #endif // ATTACHMENTS_SUPPORTED
}; };
// Splits |key_value| on '=' and inserts the resulting key and value into |map|. // Splits |key_value| on '=' and inserts the resulting key and value into |map|.
...@@ -580,9 +584,9 @@ int HandlerMain(int argc, ...@@ -580,9 +584,9 @@ int HandlerMain(int argc,
static constexpr option long_options[] = { static constexpr option long_options[] = {
{"annotation", required_argument, nullptr, kOptionAnnotation}, {"annotation", required_argument, nullptr, kOptionAnnotation},
#if defined(OS_WIN) || defined(OS_LINUX) #if defined(ATTACHMENTS_SUPPORTED)
{"attachment", required_argument, nullptr, kOptionAttachment}, {"attachment", required_argument, nullptr, kOptionAttachment},
#endif // OS_WIN || OS_LINUX #endif // ATTACHMENTS_SUPPORTED
{"database", required_argument, nullptr, kOptionDatabase}, {"database", required_argument, nullptr, kOptionDatabase},
#if defined(OS_APPLE) #if defined(OS_APPLE)
{"handshake-fd", required_argument, nullptr, kOptionHandshakeFD}, {"handshake-fd", required_argument, nullptr, kOptionHandshakeFD},
...@@ -692,14 +696,13 @@ int HandlerMain(int argc, ...@@ -692,14 +696,13 @@ int HandlerMain(int argc,
} }
break; break;
} }
#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS) || \ #if defined(ATTACHMENTS_SUPPORTED)
defined(OS_ANDROID)
case kOptionAttachment: { case kOptionAttachment: {
options.attachments.push_back(base::FilePath( options.attachments.push_back(base::FilePath(
ToolSupport::CommandLineArgumentToFilePathStringType(optarg))); ToolSupport::CommandLineArgumentToFilePathStringType(optarg)));
break; break;
} }
#endif // OS_WIN || OS_LINUX #endif // ATTACHMENTS_SUPPORTED
case kOptionDatabase: { case kOptionDatabase: {
options.database = base::FilePath( options.database = base::FilePath(
ToolSupport::CommandLineArgumentToFilePathStringType(optarg)); ToolSupport::CommandLineArgumentToFilePathStringType(optarg));
...@@ -1012,9 +1015,9 @@ int HandlerMain(int argc, ...@@ -1012,9 +1015,9 @@ int HandlerMain(int argc,
database.get(), database.get(),
static_cast<CrashReportUploadThread*>(upload_thread.Get()), static_cast<CrashReportUploadThread*>(upload_thread.Get()),
&options.annotations, &options.annotations,
#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_ANDROID) #if defined(ATTACHMENTS_SUPPORTED)
&options.attachments, &options.attachments,
#endif // OS_WIN || OS_LINUX #endif // ATTACHMENTS_SUPPORTED
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
options.write_minidump_to_database, options.write_minidump_to_database,
options.write_minidump_to_log, options.write_minidump_to_log,
......
...@@ -80,17 +80,16 @@ bool CaptureSnapshot( ...@@ -80,17 +80,16 @@ bool CaptureSnapshot(
return false; return false;
} }
auto annotations_whitelist = std::make_unique<std::vector<std::string>>(); auto allowed_annotations = std::make_unique<std::vector<std::string>>();
auto memory_range_whitelist = auto allowed_memory_ranges =
std::make_unique<std::vector<std::pair<VMAddress, VMAddress>>>(); std::make_unique<std::vector<std::pair<VMAddress, VMAddress>>>();
if (!ReadAnnotationsWhitelist( if (!ReadAllowedAnnotations(range,
sanitization_info.allowed_annotations_address,
allowed_annotations.get()) ||
!ReadAllowedMemoryRanges(
range, range,
sanitization_info.annotations_whitelist_address, sanitization_info.allowed_memory_ranges_address,
annotations_whitelist.get()) || allowed_memory_ranges.get())) {
!ReadMemoryRangeWhitelist(
range,
sanitization_info.memory_range_whitelist_address,
memory_range_whitelist.get())) {
Metrics::ExceptionCaptureResult( Metrics::ExceptionCaptureResult(
Metrics::CaptureResult::kSanitizationInitializationFailed); Metrics::CaptureResult::kSanitizationInitializationFailed);
return false; return false;
...@@ -99,10 +98,10 @@ bool CaptureSnapshot( ...@@ -99,10 +98,10 @@ bool CaptureSnapshot(
std::unique_ptr<ProcessSnapshotSanitized> sanitized( std::unique_ptr<ProcessSnapshotSanitized> sanitized(
new ProcessSnapshotSanitized()); new ProcessSnapshotSanitized());
if (!sanitized->Initialize(process_snapshot.get(), if (!sanitized->Initialize(process_snapshot.get(),
sanitization_info.annotations_whitelist_address sanitization_info.allowed_annotations_address
? std::move(annotations_whitelist) ? std::move(allowed_annotations)
: nullptr, : nullptr,
std::move(memory_range_whitelist), std::move(allowed_memory_ranges),
sanitization_info.target_module_address, sanitization_info.target_module_address,
sanitization_info.sanitize_stacks)) { sanitization_info.sanitize_stacks)) {
Metrics::ExceptionCaptureResult( Metrics::ExceptionCaptureResult(
......
...@@ -27,7 +27,7 @@ namespace internal { ...@@ -27,7 +27,7 @@ namespace internal {
//! another MemorySnapshot. //! another MemorySnapshot.
//! //!
//! This class redacts all data from the wrapped MemorySnapshot unless: //! This class redacts all data from the wrapped MemorySnapshot unless:
//! 1. The data is pointer aligned and points into a whitelisted address range. //! 1. The data is pointer aligned and points into an allowed address range.
//! 2. The data is pointer aligned and is a small integer. //! 2. The data is pointer aligned and is a small integer.
class MemorySnapshotSanitized final : public MemorySnapshot { class MemorySnapshotSanitized final : public MemorySnapshot {
public: public:
...@@ -41,7 +41,7 @@ class MemorySnapshotSanitized final : public MemorySnapshot { ...@@ -41,7 +41,7 @@ class MemorySnapshotSanitized final : public MemorySnapshot {
//! \brief Constructs this object. //! \brief Constructs this object.
//! //!
//! \param[in] snapshot The MemorySnapshot to sanitize. //! \param[in] snapshot The MemorySnapshot to sanitize.
//! \param[in] ranges A set of whitelisted address ranges. //! \param[in] ranges A set of allowed address ranges.
//! \param[in] is_64_bit `true` if this memory is for a 64-bit process. //! \param[in] is_64_bit `true` if this memory is for a 64-bit process.
MemorySnapshotSanitized(const MemorySnapshot* snapshot, MemorySnapshotSanitized(const MemorySnapshot* snapshot,
RangeSet* ranges, RangeSet* ranges,
......
...@@ -19,9 +19,9 @@ namespace internal { ...@@ -19,9 +19,9 @@ namespace internal {
namespace { namespace {
bool KeyIsInWhitelist(const std::string& name, bool KeyIsAllowed(const std::string& name,
const std::vector<std::string>& whitelist) { const std::vector<std::string>& allowed_keys) {
for (const auto& key : whitelist) { for (const auto& key : allowed_keys) {
if (name == key) { if (name == key) {
return true; return true;
} }
...@@ -33,8 +33,8 @@ bool KeyIsInWhitelist(const std::string& name, ...@@ -33,8 +33,8 @@ bool KeyIsInWhitelist(const std::string& name,
ModuleSnapshotSanitized::ModuleSnapshotSanitized( ModuleSnapshotSanitized::ModuleSnapshotSanitized(
const ModuleSnapshot* snapshot, const ModuleSnapshot* snapshot,
const std::vector<std::string>* annotations_whitelist) const std::vector<std::string>* allowed_annotations)
: snapshot_(snapshot), annotations_whitelist_(annotations_whitelist) {} : snapshot_(snapshot), allowed_annotations_(allowed_annotations) {}
ModuleSnapshotSanitized::~ModuleSnapshotSanitized() = default; ModuleSnapshotSanitized::~ModuleSnapshotSanitized() = default;
...@@ -96,9 +96,9 @@ std::map<std::string, std::string> ...@@ -96,9 +96,9 @@ std::map<std::string, std::string>
ModuleSnapshotSanitized::AnnotationsSimpleMap() const { ModuleSnapshotSanitized::AnnotationsSimpleMap() const {
std::map<std::string, std::string> annotations = std::map<std::string, std::string> annotations =
snapshot_->AnnotationsSimpleMap(); snapshot_->AnnotationsSimpleMap();
if (annotations_whitelist_) { if (allowed_annotations_) {
for (auto kv = annotations.begin(); kv != annotations.end(); ++kv) { for (auto kv = annotations.begin(); kv != annotations.end(); ++kv) {
if (!KeyIsInWhitelist(kv->first, *annotations_whitelist_)) { if (!KeyIsAllowed(kv->first, *allowed_annotations_)) {
annotations.erase(kv); annotations.erase(kv);
} }
} }
...@@ -109,14 +109,14 @@ ModuleSnapshotSanitized::AnnotationsSimpleMap() const { ...@@ -109,14 +109,14 @@ ModuleSnapshotSanitized::AnnotationsSimpleMap() const {
std::vector<AnnotationSnapshot> ModuleSnapshotSanitized::AnnotationObjects() std::vector<AnnotationSnapshot> ModuleSnapshotSanitized::AnnotationObjects()
const { const {
std::vector<AnnotationSnapshot> annotations = snapshot_->AnnotationObjects(); std::vector<AnnotationSnapshot> annotations = snapshot_->AnnotationObjects();
if (annotations_whitelist_) { if (allowed_annotations_) {
std::vector<AnnotationSnapshot> whitelisted; std::vector<AnnotationSnapshot> allowed;
for (const auto& anno : annotations) { for (const auto& anno : annotations) {
if (KeyIsInWhitelist(anno.name, *annotations_whitelist_)) { if (KeyIsAllowed(anno.name, *allowed_annotations_)) {
whitelisted.push_back(anno); allowed.push_back(anno);
} }
} }
annotations.swap(whitelisted); annotations.swap(allowed);
} }
return annotations; return annotations;
} }
......
...@@ -31,12 +31,11 @@ class ModuleSnapshotSanitized final : public ModuleSnapshot { ...@@ -31,12 +31,11 @@ class ModuleSnapshotSanitized final : public ModuleSnapshot {
//! \brief Constructs this object. //! \brief Constructs this object.
//! //!
//! \param[in] snapshot The ModuleSnapshot to sanitize. //! \param[in] snapshot The ModuleSnapshot to sanitize.
//! \param[in] annotations_whitelist A list of annotation names to allow to be //! \param[in] allowed_annotations A list of annotation names to allow to be
//! returned by AnnotationsSimpleMap() or AnnotationObjects(). If //! returned by AnnotationsSimpleMap() or AnnotationObjects(). If
//! `nullptr`, all annotations will be returned. //! `nullptr`, all annotations will be returned.
ModuleSnapshotSanitized( ModuleSnapshotSanitized(const ModuleSnapshot* snapshot,
const ModuleSnapshot* snapshot, const std::vector<std::string>* allowed_annotations);
const std::vector<std::string>* annotations_whitelist);
~ModuleSnapshotSanitized() override; ~ModuleSnapshotSanitized() override;
// ModuleSnapshot: // ModuleSnapshot:
...@@ -65,7 +64,7 @@ class ModuleSnapshotSanitized final : public ModuleSnapshot { ...@@ -65,7 +64,7 @@ class ModuleSnapshotSanitized final : public ModuleSnapshot {
private: private:
const ModuleSnapshot* snapshot_; const ModuleSnapshot* snapshot_;
const std::vector<std::string>* annotations_whitelist_; const std::vector<std::string>* allowed_annotations_;
DISALLOW_COPY_AND_ASSIGN(ModuleSnapshotSanitized); DISALLOW_COPY_AND_ASSIGN(ModuleSnapshotSanitized);
}; };
......
...@@ -84,14 +84,14 @@ ProcessSnapshotSanitized::~ProcessSnapshotSanitized() = default; ...@@ -84,14 +84,14 @@ ProcessSnapshotSanitized::~ProcessSnapshotSanitized() = default;
bool ProcessSnapshotSanitized::Initialize( bool ProcessSnapshotSanitized::Initialize(
const ProcessSnapshot* snapshot, const ProcessSnapshot* snapshot,
std::unique_ptr<const std::vector<std::string>> annotations_whitelist, std::unique_ptr<const std::vector<std::string>> allowed_annotations,
std::unique_ptr<const std::vector<std::pair<VMAddress, VMAddress>>> std::unique_ptr<const std::vector<std::pair<VMAddress, VMAddress>>>
memory_range_whitelist, allowed_memory_ranges,
VMAddress target_module_address, VMAddress target_module_address,
bool sanitize_stacks) { bool sanitize_stacks) {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_); INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
snapshot_ = snapshot; snapshot_ = snapshot;
annotations_whitelist_ = std::move(annotations_whitelist); allowed_annotations_ = std::move(allowed_annotations);
sanitize_stacks_ = sanitize_stacks; sanitize_stacks_ = sanitize_stacks;
if (target_module_address) { if (target_module_address) {
...@@ -139,10 +139,10 @@ bool ProcessSnapshotSanitized::Initialize( ...@@ -139,10 +139,10 @@ bool ProcessSnapshotSanitized::Initialize(
} }
} }
if (annotations_whitelist_) { if (allowed_annotations_) {
for (const auto module : snapshot_->Modules()) { for (const auto module : snapshot_->Modules()) {
modules_.emplace_back(std::make_unique<internal::ModuleSnapshotSanitized>( modules_.emplace_back(std::make_unique<internal::ModuleSnapshotSanitized>(
module, annotations_whitelist_.get())); module, allowed_annotations_.get()));
} }
} }
...@@ -159,7 +159,7 @@ bool ProcessSnapshotSanitized::Initialize( ...@@ -159,7 +159,7 @@ bool ProcessSnapshotSanitized::Initialize(
} }
} }
process_memory_.Initialize(snapshot_->Memory(), memory_range_whitelist.get()); process_memory_.Initialize(snapshot_->Memory(), allowed_memory_ranges.get());
INITIALIZATION_STATE_SET_VALID(initialized_); INITIALIZATION_STATE_SET_VALID(initialized_);
return true; return true;
...@@ -227,7 +227,7 @@ std::vector<const ThreadSnapshot*> ProcessSnapshotSanitized::Threads() const { ...@@ -227,7 +227,7 @@ std::vector<const ThreadSnapshot*> ProcessSnapshotSanitized::Threads() const {
std::vector<const ModuleSnapshot*> ProcessSnapshotSanitized::Modules() const { std::vector<const ModuleSnapshot*> ProcessSnapshotSanitized::Modules() const {
INITIALIZATION_STATE_DCHECK_VALID(initialized_); INITIALIZATION_STATE_DCHECK_VALID(initialized_);
if (!annotations_whitelist_) { if (!allowed_annotations_) {
return snapshot_->Modules(); return snapshot_->Modules();
} }
......
...@@ -47,10 +47,10 @@ class ProcessSnapshotSanitized final : public ProcessSnapshot { ...@@ -47,10 +47,10 @@ class ProcessSnapshotSanitized final : public ProcessSnapshot {
//! this object. //! this object.
//! //!
//! \param[in] snapshot The ProcessSnapshot to sanitize. //! \param[in] snapshot The ProcessSnapshot to sanitize.
//! \param[in] annotations_whitelist A list of annotations names to allow to //! \param[in] allowed_annotations A list of annotations names to allow to
//! be returned by AnnotationsSimpleMap() or from this object's module //! be returned by AnnotationsSimpleMap() or from this object's module
//! snapshots. If `nullptr`, all annotations will be returned. //! snapshots. If `nullptr`, all annotations will be returned.
//! \param[in] memory_range_whitelist A list of memory ranges to allow to be //! \param[in] allowed_memory_ranges A list of memory ranges to allow to be
//! accessible via Memory(), or `nullptr` to allow all ranges. //! accessible via Memory(), or `nullptr` to allow all ranges.
//! \param[in] target_module_address An address in the target process' //! \param[in] target_module_address An address in the target process'
//! address space within the bounds of a module to target. If the //! address space within the bounds of a module to target. If the
...@@ -65,9 +65,9 @@ class ProcessSnapshotSanitized final : public ProcessSnapshot { ...@@ -65,9 +65,9 @@ class ProcessSnapshotSanitized final : public ProcessSnapshot {
//! should be filtered entirely. Otherwise `true`. //! should be filtered entirely. Otherwise `true`.
bool Initialize( bool Initialize(
const ProcessSnapshot* snapshot, const ProcessSnapshot* snapshot,
std::unique_ptr<const std::vector<std::string>> annotations_whitelist, std::unique_ptr<const std::vector<std::string>> allowed_annotations,
std::unique_ptr<const std::vector<std::pair<VMAddress, VMAddress>>> std::unique_ptr<const std::vector<std::pair<VMAddress, VMAddress>>>
memory_range_whitelist, allowed_memory_ranges,
VMAddress target_module_address, VMAddress target_module_address,
bool sanitize_stacks); bool sanitize_stacks);
...@@ -93,7 +93,7 @@ class ProcessSnapshotSanitized final : public ProcessSnapshot { ...@@ -93,7 +93,7 @@ class ProcessSnapshotSanitized final : public ProcessSnapshot {
const ProcessMemory* Memory() const override; const ProcessMemory* Memory() const override;
private: private:
// Only used when annotations_whitelist_ != nullptr. // Only used when allowed_annotations_ != nullptr.
std::vector<std::unique_ptr<internal::ModuleSnapshotSanitized>> modules_; std::vector<std::unique_ptr<internal::ModuleSnapshotSanitized>> modules_;
// Only used when sanitize_stacks_ == true. // Only used when sanitize_stacks_ == true.
...@@ -102,7 +102,7 @@ class ProcessSnapshotSanitized final : public ProcessSnapshot { ...@@ -102,7 +102,7 @@ class ProcessSnapshotSanitized final : public ProcessSnapshot {
RangeSet address_ranges_; RangeSet address_ranges_;
const ProcessSnapshot* snapshot_; const ProcessSnapshot* snapshot_;
ProcessMemorySanitized process_memory_; ProcessMemorySanitized process_memory_;
std::unique_ptr<const std::vector<std::string>> annotations_whitelist_; std::unique_ptr<const std::vector<std::string>> allowed_annotations_;
bool sanitize_stacks_; bool sanitize_stacks_;
InitializationStateDcheck initialized_; InitializationStateDcheck initialized_;
......
...@@ -74,10 +74,10 @@ class ExceptionGenerator { ...@@ -74,10 +74,10 @@ class ExceptionGenerator {
DISALLOW_COPY_AND_ASSIGN(ExceptionGenerator); DISALLOW_COPY_AND_ASSIGN(ExceptionGenerator);
}; };
constexpr char kWhitelistedAnnotationName[] = "name_of_whitelisted_anno"; constexpr char kAllowedAnnotationName[] = "name_of_allowed_anno";
constexpr char kWhitelistedAnnotationValue[] = "some_value"; constexpr char kAllowedAnnotationValue[] = "some_value";
constexpr char kNonWhitelistedAnnotationName[] = "non_whitelisted_anno"; constexpr char kNonAllowedAnnotationName[] = "non_allowed_anno";
constexpr char kNonWhitelistedAnnotationValue[] = "private_annotation"; constexpr char kNonAllowedAnnotationValue[] = "private_annotation";
constexpr char kSensitiveStackData[] = "sensitive_stack_data"; constexpr char kSensitiveStackData[] = "sensitive_stack_data";
struct ChildTestAddresses { struct ChildTestAddresses {
...@@ -92,13 +92,11 @@ void ChildTestFunction() { ...@@ -92,13 +92,11 @@ void ChildTestFunction() {
FileHandle in = StdioFileHandle(StdioStream::kStandardInput); FileHandle in = StdioFileHandle(StdioStream::kStandardInput);
FileHandle out = StdioFileHandle(StdioStream::kStandardOutput); FileHandle out = StdioFileHandle(StdioStream::kStandardOutput);
static StringAnnotation<32> whitelisted_annotation( static StringAnnotation<32> allowed_annotation(kAllowedAnnotationName);
kWhitelistedAnnotationName); allowed_annotation.Set(kAllowedAnnotationValue);
whitelisted_annotation.Set(kWhitelistedAnnotationValue);
static StringAnnotation<32> non_whitelisted_annotation( static StringAnnotation<32> non_allowed_annotation(kNonAllowedAnnotationName);
kNonWhitelistedAnnotationName); non_allowed_annotation.Set(kNonAllowedAnnotationValue);
non_whitelisted_annotation.Set(kNonWhitelistedAnnotationValue);
char string_data[strlen(kSensitiveStackData) + 1]; char string_data[strlen(kSensitiveStackData) + 1];
strcpy(string_data, kSensitiveStackData); strcpy(string_data, kSensitiveStackData);
...@@ -126,39 +124,39 @@ CRASHPAD_CHILD_TEST_MAIN(ChildToBeSanitized) { ...@@ -126,39 +124,39 @@ CRASHPAD_CHILD_TEST_MAIN(ChildToBeSanitized) {
} }
void ExpectAnnotations(ProcessSnapshot* snapshot, bool sanitized) { void ExpectAnnotations(ProcessSnapshot* snapshot, bool sanitized) {
bool found_whitelisted = false; bool found_allowed = false;
bool found_non_whitelisted = false; bool found_non_allowed = false;
for (auto module : snapshot->Modules()) { for (auto module : snapshot->Modules()) {
for (const auto& anno : module->AnnotationObjects()) { for (const auto& anno : module->AnnotationObjects()) {
if (anno.name == kWhitelistedAnnotationName) { if (anno.name == kAllowedAnnotationName) {
found_whitelisted = true; found_allowed = true;
} else if (anno.name == kNonWhitelistedAnnotationName) { } else if (anno.name == kNonAllowedAnnotationName) {
found_non_whitelisted = true; found_non_allowed = true;
} }
} }
} }
EXPECT_TRUE(found_whitelisted); EXPECT_TRUE(found_allowed);
if (sanitized) { if (sanitized) {
EXPECT_FALSE(found_non_whitelisted); EXPECT_FALSE(found_non_allowed);
} else { } else {
EXPECT_TRUE(found_non_whitelisted); EXPECT_TRUE(found_non_allowed);
} }
} }
void ExpectProcessMemory(ProcessSnapshot* snapshot, void ExpectProcessMemory(ProcessSnapshot* snapshot,
VMAddress whitelisted_byte, VMAddress allowed_byte,
bool sanitized) { bool sanitized) {
auto memory = snapshot->Memory(); auto memory = snapshot->Memory();
char out; char out;
EXPECT_TRUE(memory->Read(whitelisted_byte, 1, &out)); EXPECT_TRUE(memory->Read(allowed_byte, 1, &out));
bool unwhitelisted_read = memory->Read(whitelisted_byte + 1, 1, &out); bool disallowed_read = memory->Read(allowed_byte + 1, 1, &out);
if (sanitized) { if (sanitized) {
EXPECT_FALSE(unwhitelisted_read); EXPECT_FALSE(disallowed_read);
} else { } else {
EXPECT_TRUE(unwhitelisted_read); EXPECT_TRUE(disallowed_read);
} }
} }
...@@ -272,18 +270,18 @@ class SanitizeTest : public MultiprocessExec { ...@@ -272,18 +270,18 @@ class SanitizeTest : public MultiprocessExec {
addrs.string_address, addrs.string_address,
/* sanitized= */ false); /* sanitized= */ false);
auto annotations_whitelist = std::make_unique<std::vector<std::string>>(); auto allowed_annotations = std::make_unique<std::vector<std::string>>();
annotations_whitelist->push_back(kWhitelistedAnnotationName); allowed_annotations->push_back(kAllowedAnnotationName);
auto memory_ranges_whitelist = auto allowed_memory_ranges =
std::make_unique<std::vector<std::pair<VMAddress, VMAddress>>>(); std::make_unique<std::vector<std::pair<VMAddress, VMAddress>>>();
memory_ranges_whitelist->push_back( allowed_memory_ranges->push_back(
std::make_pair(addrs.string_address, addrs.string_address + 1)); std::make_pair(addrs.string_address, addrs.string_address + 1));
ProcessSnapshotSanitized sanitized; ProcessSnapshotSanitized sanitized;
ASSERT_TRUE(sanitized.Initialize(&snapshot, ASSERT_TRUE(sanitized.Initialize(&snapshot,
std::move(annotations_whitelist), std::move(allowed_annotations),
std::move(memory_ranges_whitelist), std::move(allowed_memory_ranges),
addrs.module_address, addrs.module_address,
true)); true));
......
...@@ -24,18 +24,18 @@ namespace crashpad { ...@@ -24,18 +24,18 @@ namespace crashpad {
namespace { namespace {
template <typename Pointer> template <typename Pointer>
bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory, bool ReadAllowedAnnotations(const ProcessMemoryRange& memory,
VMAddress whitelist_address, VMAddress list_address,
std::vector<std::string>* whitelist) { std::vector<std::string>* allowed_annotations) {
if (!whitelist_address) { if (!list_address) {
return true; return true;
} }
std::vector<std::string> local_whitelist; std::vector<std::string> local_allowed_annotations;
Pointer name_address; Pointer name_address;
while (memory.Read(whitelist_address, sizeof(name_address), &name_address)) { while (memory.Read(list_address, sizeof(name_address), &name_address)) {
if (!name_address) { if (!name_address) {
whitelist->swap(local_whitelist); allowed_annotations->swap(local_allowed_annotations);
return true; return true;
} }
...@@ -44,8 +44,8 @@ bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory, ...@@ -44,8 +44,8 @@ bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory,
name_address, Annotation::kNameMaxLength, &name)) { name_address, Annotation::kNameMaxLength, &name)) {
return false; return false;
} }
local_whitelist.push_back(name); local_allowed_annotations.push_back(name);
whitelist_address += sizeof(Pointer); list_address += sizeof(Pointer);
} }
return false; return false;
...@@ -53,27 +53,27 @@ bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory, ...@@ -53,27 +53,27 @@ bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory,
} // namespace } // namespace
bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory, bool ReadAllowedAnnotations(const ProcessMemoryRange& memory,
VMAddress whitelist_address, VMAddress list_address,
std::vector<std::string>* whitelist) { std::vector<std::string>* allowed_annotations) {
return memory.Is64Bit() ? ReadAnnotationsWhitelist<uint64_t>( return memory.Is64Bit() ? ReadAllowedAnnotations<uint64_t>(
memory, whitelist_address, whitelist) memory, list_address, allowed_annotations)
: ReadAnnotationsWhitelist<uint32_t>( : ReadAllowedAnnotations<uint32_t>(
memory, whitelist_address, whitelist); memory, list_address, allowed_annotations);
} }
bool ReadMemoryRangeWhitelist( bool ReadAllowedMemoryRanges(
const ProcessMemoryRange& memory, const ProcessMemoryRange& memory,
VMAddress whitelist_address, VMAddress list_address,
std::vector<std::pair<VMAddress, VMAddress>>* whitelist) { std::vector<std::pair<VMAddress, VMAddress>>* allowed_memory_ranges) {
whitelist->clear(); allowed_memory_ranges->clear();
if (!whitelist_address) { if (!list_address) {
return true; return true;
} }
SanitizationMemoryRangeWhitelist list; SanitizationAllowedMemoryRanges list;
if (!memory.Read(whitelist_address, sizeof(list), &list)) { if (!memory.Read(list_address, sizeof(list), &list)) {
LOG(ERROR) << "Failed to read memory range whitelist."; LOG(ERROR) << "Failed to read allowed memory ranges";
return false; return false;
} }
...@@ -84,32 +84,32 @@ bool ReadMemoryRangeWhitelist( ...@@ -84,32 +84,32 @@ bool ReadMemoryRangeWhitelist(
// An upper bound of entries that we never expect to see more than. // An upper bound of entries that we never expect to see more than.
constexpr size_t kMaxListSize = 256; constexpr size_t kMaxListSize = 256;
if (list.size > kMaxListSize) { if (list.size > kMaxListSize) {
LOG(ERROR) << "Whitelist exceeded maximum, size=" << list.size; LOG(ERROR) << "list exceeded maximum, size=" << list.size;
return false; return false;
} }
std::vector<SanitizationMemoryRangeWhitelist::Range> ranges(list.size); std::vector<SanitizationAllowedMemoryRanges::Range> ranges(list.size);
if (!memory.Read(list.entries, sizeof(ranges[0]) * list.size, if (!memory.Read(list.entries, sizeof(ranges[0]) * list.size,
ranges.data())) { ranges.data())) {
LOG(ERROR) << "Failed to read memory range whitelist entries."; LOG(ERROR) << "Failed to read allowed memory ranges";
return false; return false;
} }
const VMAddress vm_max = memory.Is64Bit() const VMAddress vm_max = memory.Is64Bit()
? std::numeric_limits<uint64_t>::max() ? std::numeric_limits<uint64_t>::max()
: std::numeric_limits<uint32_t>::max(); : std::numeric_limits<uint32_t>::max();
std::vector<std::pair<VMAddress, VMAddress>> local_whitelist; std::vector<std::pair<VMAddress, VMAddress>> local_allowed_memory_ranges;
for (size_t i = 0; i < list.size; i++) { for (size_t i = 0; i < list.size; ++i) {
if (ranges[i].base > vm_max || ranges[i].length > vm_max - ranges[i].base) { if (ranges[i].base > vm_max || ranges[i].length > vm_max - ranges[i].base) {
LOG(ERROR) << "Invalid memory range whitelist entry base=" LOG(ERROR) << "Invalid range: base=" << ranges[i].base
<< ranges[i].base << " length=" << ranges[i].length; << " length=" << ranges[i].length;
return false; return false;
} }
local_whitelist.emplace_back(ranges[i].base, local_allowed_memory_ranges.emplace_back(ranges[i].base,
ranges[i].base + ranges[i].length); ranges[i].base + ranges[i].length);
} }
whitelist->swap(local_whitelist); allowed_memory_ranges->swap(local_allowed_memory_ranges);
return true; return true;
} }
......
...@@ -35,9 +35,9 @@ namespace crashpad { ...@@ -35,9 +35,9 @@ namespace crashpad {
struct SanitizationInformation { struct SanitizationInformation {
//! \brief The address in the client process' address space of a nullptr //! \brief The address in the client process' address space of a nullptr
//! terminated array of NUL-terminated strings. The string values are the //! terminated array of NUL-terminated strings. The string values are the
//! names of whitelisted annotations. This value is 0 if there is no //! names of allowed annotations. This value is 0 if all annotations are
//! whitelist and all annotations are allowed. //! allowed.
VMAddress annotations_whitelist_address; VMAddress allowed_annotations_address;
//! \brief An address in the client process' address space within a module to //! \brief An address in the client process' address space within a module to
//! target. When a target module is used, crash dumps are discarded unless //! target. When a target module is used, crash dumps are discarded unless
...@@ -47,17 +47,17 @@ struct SanitizationInformation { ...@@ -47,17 +47,17 @@ struct SanitizationInformation {
VMAddress target_module_address; VMAddress target_module_address;
//! \brief The address in the client process' address space of a //! \brief The address in the client process' address space of a
//! a \a SanitizationMemoryRangeWhitelist, a list of whitelisted address //! \a SanitizationAllowedMemoryRanges, a list of address ranges allowed
//! ranges allowed to be accessed by ProcessMemorySanitized. This value //! to be accessed by ProcessMemorySanitized. This value is 0 if no memory
//! is 0 if no memory is allowed to be read using ProcessMemorySanitized. //! is allowed to be read using ProcessMemorySanitized.
VMAddress memory_range_whitelist_address; VMAddress allowed_memory_ranges_address;
//! \brief Non-zero if stacks should be sanitized for possible PII. //! \brief Non-zero if stacks should be sanitized for possible PII.
uint8_t sanitize_stacks; uint8_t sanitize_stacks;
}; };
//! \brief Describes a list of white listed memory ranges. //! \brief Describes a list of allowed memory ranges.
struct SanitizationMemoryRangeWhitelist { struct SanitizationAllowedMemoryRanges {
//! \brief Describes a range of memory. //! \brief Describes a range of memory.
struct Range { struct Range {
VMAddress base; VMAddress base;
...@@ -71,30 +71,30 @@ struct SanitizationMemoryRangeWhitelist { ...@@ -71,30 +71,30 @@ struct SanitizationMemoryRangeWhitelist {
#pragma pack(pop) #pragma pack(pop)
//! \brief Reads an annotations whitelist from another process. //! \brief Reads a list of allowed annotations from another process.
//! //!
//! \param[in] memory A memory reader for the target process. //! \param[in] memory A memory reader for the target process.
//! \param[in] whitelist_address The address in the target process' address //! \param[in] list_address The address in the target process' address space of
//! space of a nullptr terminated array of NUL-terminated strings. //! a nullptr terminated array of NUL-terminated strings.
//! \param[out] whitelist The whitelist read, valid only if this function //! \param[out] allowed_annotations The list read, valid only if this function
//! returns `true`. //! returns `true`.
//! \return `true` on success, `false` on failure with a message logged. //! \return `true` on success, `false` on failure with a message logged.
bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory, bool ReadAllowedAnnotations(const ProcessMemoryRange& memory,
VMAddress whitelist_address, VMAddress list_address,
std::vector<std::string>* whitelist); std::vector<std::string>* allowed_annotations);
//! \brief Reads a memory range whitelist from another process. //! \brief Reads a list of allowed memory ranges from another process.
//! //!
//! \param[in] memory A memory reader for the target process. //! \param[in] memory A memory reader for the target process.
//! \param[in] whitelist_address The address in the target process' address //! \param[in] list_address The address in the target process' address space of
//! space of a nullptr terminated array of NUL-terminated strings. //! a nullptr terminated array of NUL-terminated strings.
//! \param[out] whitelist A list of whitelisted memory regions, valid only if //! \param[out] allowed_memory_ranges A list of allowed memory regions, valid
//! this function returns `true`. //! only if this function returns `true`.
//! \return `true` on success, `false` on failure with a message logged. //! \return `true` on success, `false` on failure with a message logged.
bool ReadMemoryRangeWhitelist( bool ReadAllowedMemoryRanges(
const ProcessMemoryRange& memory, const ProcessMemoryRange& memory,
VMAddress whitelist_address, VMAddress list_address,
std::vector<std::pair<VMAddress, VMAddress>>* whitelist); std::vector<std::pair<VMAddress, VMAddress>>* allowed_memory_ranges);
} // namespace crashpad } // namespace crashpad
......
...@@ -24,7 +24,7 @@ namespace crashpad { ...@@ -24,7 +24,7 @@ namespace crashpad {
namespace test { namespace test {
namespace { namespace {
class WhitelistTest : public testing::Test { class AllowedAnnotationsTest : public testing::Test {
public: public:
void SetUp() override { void SetUp() override {
ASSERT_TRUE(memory_.Initialize(getpid())); ASSERT_TRUE(memory_.Initialize(getpid()));
...@@ -36,33 +36,34 @@ class WhitelistTest : public testing::Test { ...@@ -36,33 +36,34 @@ class WhitelistTest : public testing::Test {
} }
protected: protected:
bool ReadWhitelist(const char* const* address) { bool DoReadAllowedAnnotations(const char* const* address) {
return ReadAnnotationsWhitelist( return ReadAllowedAnnotations(
range_, FromPointerCast<VMAddress>(address), &whitelist_); range_, FromPointerCast<VMAddress>(address), &allowed_annotations_);
} }
ProcessMemoryLinux memory_; ProcessMemoryLinux memory_;
ProcessMemoryRange range_; ProcessMemoryRange range_;
std::vector<std::string> whitelist_; std::vector<std::string> allowed_annotations_;
}; };
const char* const kEmptyWhitelist[] = {nullptr}; const char* const kEmptyAllowedAnnotations[] = {nullptr};
TEST_F(WhitelistTest, EmptyWhitelist) { TEST_F(AllowedAnnotationsTest, EmptyAllowedAnnotations) {
ASSERT_TRUE(ReadWhitelist(kEmptyWhitelist)); ASSERT_TRUE(DoReadAllowedAnnotations(kEmptyAllowedAnnotations));
EXPECT_EQ(whitelist_, std::vector<std::string>()); EXPECT_EQ(allowed_annotations_, std::vector<std::string>());
} }
const char* const kNonEmptyWhitelist[] = {"string1", const char* const kNonEmptyAllowedAnnotations[] = {"string1",
"another_string", "another_string",
"", "",
nullptr}; nullptr};
TEST_F(WhitelistTest, NonEmptyWhitelist) { TEST_F(AllowedAnnotationsTest, NonEmptyAllowedAnnotations) {
ASSERT_TRUE(ReadWhitelist(kNonEmptyWhitelist)); ASSERT_TRUE(DoReadAllowedAnnotations(kNonEmptyAllowedAnnotations));
ASSERT_EQ(whitelist_.size(), base::size(kNonEmptyWhitelist) - 1); ASSERT_EQ(allowed_annotations_.size(),
for (size_t index = 0; index < base::size(kNonEmptyWhitelist) - 1; ++index) { base::size(kNonEmptyAllowedAnnotations) - 1);
EXPECT_EQ(whitelist_[index], kNonEmptyWhitelist[index]); for (size_t index = 0; index < allowed_annotations_.size(); ++index) {
EXPECT_EQ(allowed_annotations_[index], kNonEmptyAllowedAnnotations[index]);
} }
} }
......
...@@ -28,17 +28,17 @@ ...@@ -28,17 +28,17 @@
namespace crashpad { namespace crashpad {
ProcessMemorySanitized::ProcessMemorySanitized() ProcessMemorySanitized::ProcessMemorySanitized()
: ProcessMemory(), memory_(nullptr), whitelist_() {} : ProcessMemory(), memory_(nullptr), allowed_ranges_() {}
ProcessMemorySanitized::~ProcessMemorySanitized() {} ProcessMemorySanitized::~ProcessMemorySanitized() {}
bool ProcessMemorySanitized::Initialize( bool ProcessMemorySanitized::Initialize(
const ProcessMemory* memory, const ProcessMemory* memory,
const std::vector<std::pair<VMAddress, VMAddress>>* whitelist) { const std::vector<std::pair<VMAddress, VMAddress>>* allowed_ranges) {
INITIALIZATION_STATE_SET_INITIALIZING(initialized_); INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
memory_ = memory; memory_ = memory;
if (whitelist) if (allowed_ranges)
whitelist_ = *whitelist; allowed_ranges_ = *allowed_ranges;
INITIALIZATION_STATE_SET_VALID(initialized_); INITIALIZATION_STATE_SET_VALID(initialized_);
return true; return true;
} }
...@@ -49,7 +49,7 @@ ssize_t ProcessMemorySanitized::ReadUpTo(VMAddress address, ...@@ -49,7 +49,7 @@ ssize_t ProcessMemorySanitized::ReadUpTo(VMAddress address,
INITIALIZATION_STATE_DCHECK_VALID(initialized_); INITIALIZATION_STATE_DCHECK_VALID(initialized_);
VMAddress end = address + size; VMAddress end = address + size;
for (auto&& entry : whitelist_) { for (auto&& entry : allowed_ranges_) {
if (address >= entry.first && address < entry.second && if (address >= entry.first && address < entry.second &&
end >= entry.first && end <= entry.second) { end >= entry.first && end <= entry.second) {
return memory_->ReadUpTo(address, size, buffer); return memory_->ReadUpTo(address, size, buffer);
...@@ -57,7 +57,7 @@ ssize_t ProcessMemorySanitized::ReadUpTo(VMAddress address, ...@@ -57,7 +57,7 @@ ssize_t ProcessMemorySanitized::ReadUpTo(VMAddress address,
} }
DLOG(ERROR) DLOG(ERROR)
<< "ProcessMemorySanitized failed to read unwhitelisted region. address=" << "ProcessMemorySanitized failed to read disallowed region. address="
<< address << " size=" << size; << address << " size=" << size;
return 0; return 0;
} }
......
...@@ -34,25 +34,25 @@ class ProcessMemorySanitized final : public ProcessMemory { ...@@ -34,25 +34,25 @@ class ProcessMemorySanitized final : public ProcessMemory {
~ProcessMemorySanitized(); ~ProcessMemorySanitized();
//! \brief Initializes this object to read memory from the underlying //! \brief Initializes this object to read memory from the underlying
//! \a memory object if the memory range is in the provided \a whitelist. //! \a memory object if the memory range is in \a allowed_ranges.
//! //!
//! This method must be called successfully prior to calling any other method //! This method must be called successfully prior to calling any other method
//! in this class. //! in this class.
//! //!
//! \param[in] memory The memory object to read whitelisted regions from. //! \param[in] memory The memory object to read memory from.
//! \param[in] whitelist A whitelist of memory regions. //! \param[in] allowed_ranges A list of allowed memory ranges.
//! //!
//! \return `true` on success, `false` on failure with a message logged. //! \return `true` on success, `false` on failure with a message logged.
bool Initialize( bool Initialize(
const ProcessMemory* memory, const ProcessMemory* memory,
const std::vector<std::pair<VMAddress, VMAddress>>* whitelist); const std::vector<std::pair<VMAddress, VMAddress>>* allowed_ranges);
private: private:
ssize_t ReadUpTo(VMAddress address, size_t size, void* buffer) const override; ssize_t ReadUpTo(VMAddress address, size_t size, void* buffer) const override;
const ProcessMemory* memory_; const ProcessMemory* memory_;
InitializationStateDcheck initialized_; InitializationStateDcheck initialized_;
std::vector<std::pair<VMAddress, VMAddress>> whitelist_; std::vector<std::pair<VMAddress, VMAddress>> allowed_ranges_;
DISALLOW_COPY_AND_ASSIGN(ProcessMemorySanitized); DISALLOW_COPY_AND_ASSIGN(ProcessMemorySanitized);
}; };
......
...@@ -23,7 +23,7 @@ namespace crashpad { ...@@ -23,7 +23,7 @@ namespace crashpad {
namespace test { namespace test {
namespace { namespace {
TEST(ProcessMemorySanitized, DenyOnEmptyWhitelist) { TEST(ProcessMemorySanitized, DenyDisallowedMemory) {
ProcessMemoryNative memory; ProcessMemoryNative memory;
ASSERT_TRUE(memory.Initialize(GetSelfProcess())); ASSERT_TRUE(memory.Initialize(GetSelfProcess()));
...@@ -34,25 +34,25 @@ TEST(ProcessMemorySanitized, DenyOnEmptyWhitelist) { ...@@ -34,25 +34,25 @@ TEST(ProcessMemorySanitized, DenyOnEmptyWhitelist) {
san_null.Initialize(&memory, nullptr); san_null.Initialize(&memory, nullptr);
EXPECT_FALSE(san_null.Read(FromPointerCast<VMAddress>(&c), 1, &out)); EXPECT_FALSE(san_null.Read(FromPointerCast<VMAddress>(&c), 1, &out));
std::vector<std::pair<VMAddress, VMAddress>> whitelist; std::vector<std::pair<VMAddress, VMAddress>> allowed_memory;
ProcessMemorySanitized san_blank; ProcessMemorySanitized san_empty;
san_blank.Initialize(&memory, &whitelist); san_empty.Initialize(&memory, &allowed_memory);
EXPECT_FALSE(san_blank.Read(FromPointerCast<VMAddress>(&c), 1, &out)); EXPECT_FALSE(san_empty.Read(FromPointerCast<VMAddress>(&c), 1, &out));
} }
TEST(ProcessMemorySanitized, WhitelistingWorks) { TEST(ProcessMemorySanitized, AllowedMemory) {
ProcessMemoryNative memory; ProcessMemoryNative memory;
ASSERT_TRUE(memory.Initialize(GetSelfProcess())); ASSERT_TRUE(memory.Initialize(GetSelfProcess()));
char str[4] = "ABC"; char str[4] = "ABC";
char out[4]; char out[4];
std::vector<std::pair<VMAddress, VMAddress>> whitelist; std::vector<std::pair<VMAddress, VMAddress>> allowed_memory;
whitelist.push_back(std::make_pair(FromPointerCast<VMAddress>(str + 1), allowed_memory.push_back(std::make_pair(FromPointerCast<VMAddress>(str + 1),
FromPointerCast<VMAddress>(str + 2))); FromPointerCast<VMAddress>(str + 2)));
ProcessMemorySanitized sanitized; ProcessMemorySanitized sanitized;
sanitized.Initialize(&memory, &whitelist); sanitized.Initialize(&memory, &allowed_memory);
EXPECT_FALSE(sanitized.Read(FromPointerCast<VMAddress>(str), 1, &out)); EXPECT_FALSE(sanitized.Read(FromPointerCast<VMAddress>(str), 1, &out));
EXPECT_TRUE(sanitized.Read(FromPointerCast<VMAddress>(str + 1), 1, &out)); EXPECT_TRUE(sanitized.Read(FromPointerCast<VMAddress>(str + 1), 1, &out));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment