mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-27 15:32:10 +08:00
android/linux: add a client interface to control sanitization
Sanitization is controlled by a SanitizationInformation struct to be read from the client's memory. The address of this struct is either passed in a ClientInformation when the client requests a crash dump, or as a flag to the handler --sanitization_information. Bug: crashpad:30 Change-Id: I2744f8fb85b4fea7362b2b88faa4bef1da74e36b Reviewed-on: https://chromium-review.googlesource.com/1083143 Commit-Queue: Joshua Peraza <jperaza@chromium.org> Reviewed-by: Scott Graham <scottmg@chromium.org>
This commit is contained in:
parent
a42b5269b4
commit
d1e6a2130d
@ -28,6 +28,7 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "snapshot/annotation_snapshot.h"
|
||||
#include "snapshot/minidump/process_snapshot_minidump.h"
|
||||
#include "snapshot/sanitized/sanitization_information.h"
|
||||
#include "test/multiprocess.h"
|
||||
#include "test/multiprocess_exec.h"
|
||||
#include "test/scoped_temp_dir.h"
|
||||
@ -210,7 +211,9 @@ class StartHandlerForClientTest {
|
||||
StartHandlerForClientTest() = default;
|
||||
~StartHandlerForClientTest() = default;
|
||||
|
||||
bool Initialize() {
|
||||
bool Initialize(bool sanitize) {
|
||||
sanitize_ = sanitize;
|
||||
|
||||
int socks[2];
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) != 0) {
|
||||
PLOG(ERROR) << "socketpair";
|
||||
@ -253,19 +256,23 @@ class StartHandlerForClientTest {
|
||||
ASSERT_TRUE(database);
|
||||
|
||||
std::vector<CrashReportDatabase::Report> reports;
|
||||
ASSERT_EQ(database->GetPendingReports(&reports),
|
||||
CrashReportDatabase::kNoError);
|
||||
EXPECT_EQ(reports.size(), 1u);
|
||||
|
||||
reports.clear();
|
||||
ASSERT_EQ(database->GetCompletedReports(&reports),
|
||||
CrashReportDatabase::kNoError);
|
||||
EXPECT_EQ(reports.size(), 0u);
|
||||
|
||||
reports.clear();
|
||||
ASSERT_EQ(database->GetPendingReports(&reports),
|
||||
CrashReportDatabase::kNoError);
|
||||
if (sanitize_) {
|
||||
EXPECT_EQ(reports.size(), 0u);
|
||||
} else {
|
||||
EXPECT_EQ(reports.size(), 1u);
|
||||
}
|
||||
}
|
||||
|
||||
bool InstallHandler() {
|
||||
auto signal_handler = SandboxedHandler::Get();
|
||||
return signal_handler->Initialize(client_sock_.get());
|
||||
return signal_handler->Initialize(client_sock_.get(), sanitize_);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -278,8 +285,9 @@ class StartHandlerForClientTest {
|
||||
return instance;
|
||||
}
|
||||
|
||||
bool Initialize(FileHandle client_sock) {
|
||||
bool Initialize(FileHandle client_sock, bool sanitize) {
|
||||
client_sock_ = client_sock;
|
||||
sanitize_ = sanitize;
|
||||
return Signals::InstallCrashHandlers(HandleCrash, 0, nullptr);
|
||||
}
|
||||
|
||||
@ -302,11 +310,20 @@ class StartHandlerForClientTest {
|
||||
context);
|
||||
exception_information.thread_id = syscall(SYS_gettid);
|
||||
|
||||
ClientInformation info = {};
|
||||
ClientInformation info;
|
||||
info.exception_information_address =
|
||||
FromPointerCast<decltype(info.exception_information_address)>(
|
||||
&exception_information);
|
||||
|
||||
SanitizationInformation sanitization_info = {};
|
||||
if (state->sanitize_) {
|
||||
info.sanitization_information_address =
|
||||
FromPointerCast<VMAddress>(&sanitization_info);
|
||||
// Target a non-module address to prevent a crash dump.
|
||||
sanitization_info.target_module_address =
|
||||
FromPointerCast<VMAddress>(&sanitization_info);
|
||||
}
|
||||
|
||||
ExceptionHandlerClient handler_client(state->client_sock_);
|
||||
CHECK_EQ(handler_client.RequestCrashDump(info), 0);
|
||||
|
||||
@ -314,6 +331,7 @@ class StartHandlerForClientTest {
|
||||
}
|
||||
|
||||
FileHandle client_sock_;
|
||||
bool sanitize_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(SandboxedHandler);
|
||||
};
|
||||
@ -321,6 +339,7 @@ class StartHandlerForClientTest {
|
||||
ScopedTempDir temp_dir_;
|
||||
ScopedFileHandle client_sock_;
|
||||
ScopedFileHandle server_sock_;
|
||||
bool sanitize_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(StartHandlerForClientTest);
|
||||
};
|
||||
@ -331,9 +350,9 @@ class StartHandlerForChildTest : public Multiprocess {
|
||||
StartHandlerForChildTest() = default;
|
||||
~StartHandlerForChildTest() = default;
|
||||
|
||||
bool Initialize() {
|
||||
bool Initialize(bool sanitize) {
|
||||
SetExpectedChildTerminationBuiltinTrap();
|
||||
return test_state_.Initialize();
|
||||
return test_state_.Initialize(sanitize);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -361,7 +380,13 @@ class StartHandlerForChildTest : public Multiprocess {
|
||||
|
||||
TEST(CrashpadClient, StartHandlerForChild) {
|
||||
StartHandlerForChildTest test;
|
||||
ASSERT_TRUE(test.Initialize());
|
||||
ASSERT_TRUE(test.Initialize(/* sanitize= */ false));
|
||||
test.Run();
|
||||
}
|
||||
|
||||
TEST(CrashpadClient, SanitizedChild) {
|
||||
StartHandlerForChildTest test;
|
||||
ASSERT_TRUE(test.Initialize(/* sanitize= */ true));
|
||||
test.Run();
|
||||
}
|
||||
|
||||
|
@ -144,6 +144,8 @@ void Usage(const base::FilePath& me) {
|
||||
" --trace-parent-with-exception=EXCEPTION_INFORMATION_ADDRESS\n"
|
||||
" request a dump for the handler's parent process\n"
|
||||
" --initial-client-fd=FD a socket connected to a client.\n"
|
||||
" --sanitization_information=SANITIZATION_INFORMATION_ADDRESS\n"
|
||||
" the address of a SanitizationInformation struct.\n"
|
||||
#endif // OS_LINUX || OS_ANDROID
|
||||
" --url=URL send crash reports to this Breakpad server URL,\n"
|
||||
" only if uploads are enabled for the database\n"
|
||||
@ -167,6 +169,7 @@ struct Options {
|
||||
#elif defined(OS_LINUX) || defined(OS_ANDROID)
|
||||
VMAddress exception_information_address;
|
||||
int initial_client_fd;
|
||||
VMAddress sanitization_information_address;
|
||||
#elif defined(OS_WIN)
|
||||
std::string pipe_name;
|
||||
InitialClientData initial_client_data;
|
||||
@ -535,6 +538,7 @@ int HandlerMain(int argc,
|
||||
#if defined(OS_LINUX) || defined(OS_ANDROID)
|
||||
kOptionTraceParentWithException,
|
||||
kOptionInitialClientFD,
|
||||
kOptionSanitizationInformation,
|
||||
#endif
|
||||
kOptionURL,
|
||||
|
||||
@ -590,6 +594,10 @@ int HandlerMain(int argc,
|
||||
nullptr,
|
||||
kOptionTraceParentWithException},
|
||||
{"initial-client-fd", required_argument, nullptr, kOptionInitialClientFD},
|
||||
{"sanitization-information",
|
||||
required_argument,
|
||||
nullptr,
|
||||
kOptionSanitizationInformation},
|
||||
#endif // OS_LINUX || OS_ANDROID
|
||||
{"url", required_argument, nullptr, kOptionURL},
|
||||
{"help", no_argument, nullptr, kOptionHelp},
|
||||
@ -608,6 +616,7 @@ int HandlerMain(int argc,
|
||||
#if defined(OS_LINUX) || defined(OS_ANDROID)
|
||||
options.exception_information_address = 0;
|
||||
options.initial_client_fd = kInvalidFileHandle;
|
||||
options.sanitization_information_address = 0;
|
||||
#endif
|
||||
|
||||
int opt;
|
||||
@ -714,6 +723,15 @@ int HandlerMain(int argc,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kOptionSanitizationInformation: {
|
||||
if (!StringToNumber(optarg,
|
||||
&options.sanitization_information_address)) {
|
||||
ToolSupport::UsageHint(me,
|
||||
"failed to parse --sanitization-information");
|
||||
return ExitFailure();
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif // OS_LINUX || OS_ANDROID
|
||||
case kOptionURL: {
|
||||
options.url = optarg;
|
||||
@ -762,9 +780,15 @@ int HandlerMain(int argc,
|
||||
#elif defined(OS_LINUX) || defined(OS_ANDROID)
|
||||
if (!options.exception_information_address &&
|
||||
options.initial_client_fd == kInvalidFileHandle) {
|
||||
ToolSupport::UsageHint(
|
||||
me, "--trace-parent-with-exception or --initial_client_fd is required");
|
||||
return ExitFailure();
|
||||
}
|
||||
if (options.sanitization_information_address &&
|
||||
!options.exception_information_address) {
|
||||
ToolSupport::UsageHint(
|
||||
me,
|
||||
"--exception_information_address or --initial_client_fd is required");
|
||||
"--sanitization_information requires --trace-parent-with-exception");
|
||||
return ExitFailure();
|
||||
}
|
||||
#endif // OS_MACOSX
|
||||
@ -844,9 +868,12 @@ int HandlerMain(int argc,
|
||||
|
||||
#if defined(OS_LINUX) || defined(OS_ANDROID)
|
||||
if (options.exception_information_address) {
|
||||
return exception_handler.HandleException(getppid(),
|
||||
options.exception_information_address) ?
|
||||
EXIT_SUCCESS : ExitFailure();
|
||||
ClientInformation info;
|
||||
info.exception_information_address = options.exception_information_address;
|
||||
info.sanitization_information_address =
|
||||
options.sanitization_information_address;
|
||||
return exception_handler.HandleException(getppid(), info) ? EXIT_SUCCESS
|
||||
: ExitFailure();
|
||||
}
|
||||
#endif // OS_LINUX || OS_ANDROID
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "minidump/minidump_file_writer.h"
|
||||
#include "snapshot/crashpad_info_client_options.h"
|
||||
#include "snapshot/linux/process_snapshot_linux.h"
|
||||
#include "snapshot/sanitized/process_snapshot_sanitized.h"
|
||||
#include "snapshot/sanitized/sanitization_information.h"
|
||||
#include "util/linux/direct_ptrace_connection.h"
|
||||
#include "util/linux/ptrace_client.h"
|
||||
#include "util/misc/metrics.h"
|
||||
@ -43,7 +45,7 @@ CrashReportExceptionHandler::~CrashReportExceptionHandler() = default;
|
||||
|
||||
bool CrashReportExceptionHandler::HandleException(
|
||||
pid_t client_process_id,
|
||||
VMAddress exception_info_address) {
|
||||
const ClientInformation& info) {
|
||||
Metrics::ExceptionEncountered();
|
||||
|
||||
DirectPtraceConnection connection;
|
||||
@ -53,12 +55,12 @@ bool CrashReportExceptionHandler::HandleException(
|
||||
return false;
|
||||
}
|
||||
|
||||
return HandleExceptionWithConnection(&connection, exception_info_address);
|
||||
return HandleExceptionWithConnection(&connection, info);
|
||||
}
|
||||
|
||||
bool CrashReportExceptionHandler::HandleExceptionWithBroker(
|
||||
pid_t client_process_id,
|
||||
VMAddress exception_info_address,
|
||||
const ClientInformation& info,
|
||||
int broker_sock) {
|
||||
Metrics::ExceptionEncountered();
|
||||
|
||||
@ -69,19 +71,20 @@ bool CrashReportExceptionHandler::HandleExceptionWithBroker(
|
||||
return false;
|
||||
}
|
||||
|
||||
return HandleExceptionWithConnection(&client, exception_info_address);
|
||||
return HandleExceptionWithConnection(&client, info);
|
||||
}
|
||||
|
||||
bool CrashReportExceptionHandler::HandleExceptionWithConnection(
|
||||
PtraceConnection* connection,
|
||||
VMAddress exception_info_address) {
|
||||
const ClientInformation& info) {
|
||||
ProcessSnapshotLinux process_snapshot;
|
||||
if (!process_snapshot.Initialize(connection)) {
|
||||
Metrics::ExceptionCaptureResult(Metrics::CaptureResult::kSnapshotFailed);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!process_snapshot.InitializeException(exception_info_address)) {
|
||||
if (!process_snapshot.InitializeException(
|
||||
info.exception_information_address)) {
|
||||
Metrics::ExceptionCaptureResult(
|
||||
Metrics::CaptureResult::kExceptionInitializationFailed);
|
||||
return false;
|
||||
@ -116,10 +119,50 @@ bool CrashReportExceptionHandler::HandleExceptionWithConnection(
|
||||
|
||||
process_snapshot.SetReportID(new_report->ReportID());
|
||||
|
||||
ProcessSnapshot* snapshot = nullptr;
|
||||
ProcessSnapshotSanitized sanitized;
|
||||
std::vector<std::string> whitelist;
|
||||
if (info.sanitization_information_address) {
|
||||
SanitizationInformation sanitization_info;
|
||||
ProcessMemoryRange range;
|
||||
if (!range.Initialize(connection->Memory(), connection->Is64Bit()) ||
|
||||
!range.Read(info.sanitization_information_address,
|
||||
sizeof(sanitization_info),
|
||||
&sanitization_info)) {
|
||||
Metrics::ExceptionCaptureResult(
|
||||
Metrics::CaptureResult::kSanitizationInitializationFailed);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sanitization_info.annotations_whitelist_address &&
|
||||
!ReadAnnotationsWhitelist(
|
||||
range,
|
||||
sanitization_info.annotations_whitelist_address,
|
||||
&whitelist)) {
|
||||
Metrics::ExceptionCaptureResult(
|
||||
Metrics::CaptureResult::kSanitizationInitializationFailed);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sanitized.Initialize(&process_snapshot,
|
||||
sanitization_info.annotations_whitelist_address
|
||||
? &whitelist
|
||||
: nullptr,
|
||||
sanitization_info.target_module_address,
|
||||
sanitization_info.sanitize_stacks)) {
|
||||
Metrics::ExceptionCaptureResult(
|
||||
Metrics::CaptureResult::kSkippedDueToSanitization);
|
||||
return true;
|
||||
}
|
||||
|
||||
snapshot = &sanitized;
|
||||
} else {
|
||||
snapshot = &process_snapshot;
|
||||
}
|
||||
|
||||
MinidumpFileWriter minidump;
|
||||
minidump.InitializeFromSnapshot(&process_snapshot);
|
||||
AddUserExtensionStreams(
|
||||
user_stream_data_sources_, &process_snapshot, &minidump);
|
||||
minidump.InitializeFromSnapshot(snapshot);
|
||||
AddUserExtensionStreams(user_stream_data_sources_, snapshot, &minidump);
|
||||
|
||||
if (!minidump.WriteEverything(new_report->Writer())) {
|
||||
LOG(ERROR) << "WriteEverything failed";
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "handler/crash_report_upload_thread.h"
|
||||
#include "handler/linux/exception_handler_server.h"
|
||||
#include "handler/user_stream_data_source.h"
|
||||
#include "util/linux/exception_handler_protocol.h"
|
||||
#include "util/linux/ptrace_connection.h"
|
||||
#include "util/misc/address_types.h"
|
||||
|
||||
@ -63,15 +64,15 @@ class CrashReportExceptionHandler : public ExceptionHandlerServer::Delegate {
|
||||
// ExceptionHandlerServer::Delegate:
|
||||
|
||||
bool HandleException(pid_t client_process_id,
|
||||
VMAddress exception_info_address) override;
|
||||
const ClientInformation& info) override;
|
||||
|
||||
bool HandleExceptionWithBroker(pid_t client_process_id,
|
||||
VMAddress exception_info_address,
|
||||
const ClientInformation& info,
|
||||
int broker_sock) override;
|
||||
|
||||
private:
|
||||
bool HandleExceptionWithConnection(PtraceConnection* connection,
|
||||
VMAddress exception_info_address);
|
||||
const ClientInformation& info);
|
||||
|
||||
CrashReportDatabase* database_; // weak
|
||||
CrashReportUploadThread* upload_thread_; // weak
|
||||
|
@ -446,15 +446,12 @@ bool ExceptionHandlerServer::HandleCrashDumpRequest(
|
||||
ServerToClientMessage::kTypeCrashDumpFailed);
|
||||
|
||||
case PtraceStrategyDecider::Strategy::kDirectPtrace:
|
||||
delegate_->HandleException(client_process_id,
|
||||
client_info.exception_information_address);
|
||||
delegate_->HandleException(client_process_id, client_info);
|
||||
break;
|
||||
|
||||
case PtraceStrategyDecider::Strategy::kUseBroker:
|
||||
delegate_->HandleExceptionWithBroker(
|
||||
client_process_id,
|
||||
client_info.exception_information_address,
|
||||
client_sock);
|
||||
client_process_id, client_info, client_sock);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -71,23 +71,20 @@ class ExceptionHandlerServer {
|
||||
//! \brief Called on receipt of a crash dump request from a client.
|
||||
//!
|
||||
//! \param[in] client_process_id The process ID of the crashing client.
|
||||
//! \param[in] exception_information_address The address in the client's
|
||||
//! address space of an ExceptionInformation struct.
|
||||
//! \param[in] info Information on the client.
|
||||
//! \return `true` on success. `false` on failure with a message logged.
|
||||
virtual bool HandleException(pid_t client_process_id,
|
||||
VMAddress exception_information_address) = 0;
|
||||
const ClientInformation& info) = 0;
|
||||
|
||||
//! \brief Called on the receipt of a crash dump request from a client for a
|
||||
//! crash that should be mediated by a PtraceBroker.
|
||||
//!
|
||||
//! \param[in] client_process_id The process ID of the crashing client.
|
||||
//! \param[in] exception_information_address The address in the client's
|
||||
//! address space of an ExceptionInformation struct.
|
||||
//! \param[in] info Information on the client.
|
||||
//! \param[in] broker_sock A socket connected to the PtraceBroker.
|
||||
//! \return `true` on success. `false` on failure with a message logged.
|
||||
virtual bool HandleExceptionWithBroker(
|
||||
pid_t client_process_id,
|
||||
VMAddress exception_information_address,
|
||||
virtual bool HandleExceptionWithBroker(pid_t client_process_id,
|
||||
const ClientInformation& info,
|
||||
int broker_sock) = 0;
|
||||
|
||||
protected:
|
||||
|
@ -101,25 +101,25 @@ class TestDelegate : public ExceptionHandlerServer::Delegate {
|
||||
}
|
||||
|
||||
bool HandleException(pid_t client_process_id,
|
||||
VMAddress exception_information_address) override {
|
||||
const ClientInformation& info) override {
|
||||
DirectPtraceConnection connection;
|
||||
bool connected = connection.Initialize(client_process_id);
|
||||
EXPECT_TRUE(connected);
|
||||
|
||||
last_exception_address_ = exception_information_address;
|
||||
last_exception_address_ = info.exception_information_address;
|
||||
last_client_ = client_process_id;
|
||||
sem_.Signal();
|
||||
return connected;
|
||||
}
|
||||
|
||||
bool HandleExceptionWithBroker(pid_t client_process_id,
|
||||
VMAddress exception_information_address,
|
||||
const ClientInformation& info,
|
||||
int broker_sock) override {
|
||||
PtraceClient client;
|
||||
bool connected = client.Initialize(broker_sock, client_process_id);
|
||||
EXPECT_TRUE(connected);
|
||||
|
||||
last_exception_address_ = exception_information_address,
|
||||
last_exception_address_ = info.exception_information_address,
|
||||
last_client_ = client_process_id;
|
||||
sem_.Signal();
|
||||
return connected;
|
||||
|
@ -128,6 +128,8 @@ static_library("snapshot") {
|
||||
"sanitized/module_snapshot_sanitized.h",
|
||||
"sanitized/process_snapshot_sanitized.cc",
|
||||
"sanitized/process_snapshot_sanitized.h",
|
||||
"sanitized/sanitization_information.cc",
|
||||
"sanitized/sanitization_information.h",
|
||||
"sanitized/thread_snapshot_sanitized.cc",
|
||||
"sanitized/thread_snapshot_sanitized.h",
|
||||
]
|
||||
@ -338,6 +340,7 @@ source_set("snapshot_test") {
|
||||
"linux/process_reader_linux_test.cc",
|
||||
"linux/system_snapshot_linux_test.cc",
|
||||
"sanitized/process_snapshot_sanitized_test.cc",
|
||||
"sanitized/sanitization_information_test.cc",
|
||||
]
|
||||
} else {
|
||||
sources += [ "crashpad_info_client_options_test.cc" ]
|
||||
|
61
snapshot/sanitized/sanitization_information.cc
Normal file
61
snapshot/sanitized/sanitization_information.cc
Normal file
@ -0,0 +1,61 @@
|
||||
// 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 "snapshot/sanitized/sanitization_information.h"
|
||||
|
||||
#include "client/annotation.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename Pointer>
|
||||
bool ReadWhitelist(const ProcessMemoryRange& memory,
|
||||
VMAddress whitelist_address,
|
||||
std::vector<std::string>* whitelist) {
|
||||
if (!whitelist_address) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> local_whitelist;
|
||||
Pointer name_address;
|
||||
while (memory.Read(whitelist_address, sizeof(name_address), &name_address)) {
|
||||
if (!name_address) {
|
||||
whitelist->swap(local_whitelist);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string name;
|
||||
if (!memory.ReadCStringSizeLimited(
|
||||
name_address, Annotation::kNameMaxLength, &name)) {
|
||||
return false;
|
||||
}
|
||||
local_whitelist.push_back(name);
|
||||
whitelist_address += sizeof(Pointer);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory,
|
||||
VMAddress whitelist_address,
|
||||
std::vector<std::string>* whitelist) {
|
||||
return memory.Is64Bit()
|
||||
? ReadWhitelist<uint64_t>(memory, whitelist_address, whitelist)
|
||||
: ReadWhitelist<uint32_t>(memory, whitelist_address, whitelist);
|
||||
}
|
||||
|
||||
} // namespace crashpad
|
68
snapshot/sanitized/sanitization_information.h
Normal file
68
snapshot/sanitized/sanitization_information.h
Normal file
@ -0,0 +1,68 @@
|
||||
// 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.
|
||||
|
||||
#ifndef CRASHPAD_SNAPSHOT_SANITIZED_SANITIZATION_INFORMATION_H_
|
||||
#define CRASHPAD_SNAPSHOT_SANITIZED_SANITIZATION_INFORMATION_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "util/misc/address_types.h"
|
||||
#include "util/process/process_memory_range.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
//! \brief Struture containing information about how snapshots should be
|
||||
//! sanitized.
|
||||
//!
|
||||
//! \see ProcessSnapshotSanitized
|
||||
struct SanitizationInformation {
|
||||
//! \brief The address in the client process' address space of a nullptr
|
||||
//! terminated array of NUL-terminated strings. The string values are the
|
||||
//! names of whitelisted annotations. This value is 0 if there is no
|
||||
//! whitelist and all annotations are allowed.
|
||||
VMAddress annotations_whitelist_address;
|
||||
|
||||
//! \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
|
||||
//! the crashing thread's program counter or pointer-aligned values on the
|
||||
//! crashing thread's stack point into the target module. This value is 0
|
||||
//! if there is no target module.
|
||||
VMAddress target_module_address;
|
||||
|
||||
//! \brief Non-zero if stacks should be sanitized for possible PII.
|
||||
uint8_t sanitize_stacks;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
//! \brief Reads an annotations whitelist from another process.
|
||||
//!
|
||||
//! \param[in] memory A memory reader for the target process.
|
||||
//! \param[in] whitelist_address The address in the target process' address
|
||||
//! space of a nullptr terminated array of NUL-terminated strings.
|
||||
//! \param[out] whitelist The whitelist read, valid only if this function
|
||||
//! returns `true`.
|
||||
//! \return `true` on success, `false` on failure with a message logged.
|
||||
bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory,
|
||||
VMAddress whitelist_address,
|
||||
std::vector<std::string>* whitelist);
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
#endif // CRASHPAD_SNAPSHOT_SANITIZED_SANITIZATION_INFORMATION_H_
|
70
snapshot/sanitized/sanitization_information_test.cc
Normal file
70
snapshot/sanitized/sanitization_information_test.cc
Normal file
@ -0,0 +1,70 @@
|
||||
// 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 "snapshot/sanitized/sanitization_information.h"
|
||||
|
||||
#include "build/build_config.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "util/misc/from_pointer_cast.h"
|
||||
#include "util/process/process_memory_linux.h"
|
||||
|
||||
namespace crashpad {
|
||||
namespace test {
|
||||
namespace {
|
||||
|
||||
class WhitelistTest : public testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
ASSERT_TRUE(memory_.Initialize(getpid()));
|
||||
#if defined(ARCH_CPU_64_BITS)
|
||||
ASSERT_TRUE(range_.Initialize(&memory_, true));
|
||||
#else
|
||||
ASSERT_TRUE(range_.Initialize(&memory_, false));
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
bool ReadWhitelist(const char* const* address) {
|
||||
return ReadAnnotationsWhitelist(
|
||||
range_, FromPointerCast<VMAddress>(address), &whitelist_);
|
||||
}
|
||||
|
||||
ProcessMemoryLinux memory_;
|
||||
ProcessMemoryRange range_;
|
||||
std::vector<std::string> whitelist_;
|
||||
};
|
||||
|
||||
const char* const kEmptyWhitelist[] = {nullptr};
|
||||
|
||||
TEST_F(WhitelistTest, EmptyWhitelist) {
|
||||
ASSERT_TRUE(ReadWhitelist(kEmptyWhitelist));
|
||||
EXPECT_EQ(whitelist_, std::vector<std::string>());
|
||||
}
|
||||
|
||||
const char* const kNonEmptyWhitelist[] = {"string1",
|
||||
"another_string",
|
||||
"",
|
||||
nullptr};
|
||||
|
||||
TEST_F(WhitelistTest, NonEmptyWhitelist) {
|
||||
ASSERT_TRUE(ReadWhitelist(kNonEmptyWhitelist));
|
||||
ASSERT_EQ(whitelist_.size(), arraysize(kNonEmptyWhitelist) - 1);
|
||||
for (size_t index = 0; index < arraysize(kNonEmptyWhitelist) - 1; ++index) {
|
||||
EXPECT_EQ(whitelist_[index], kNonEmptyWhitelist[index]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace test
|
||||
} // namespace crashpad
|
@ -129,6 +129,8 @@
|
||||
'sanitized/module_snapshot_sanitized.h',
|
||||
'sanitized/process_snapshot_sanitized.cc',
|
||||
'sanitized/process_snapshot_sanitized.h',
|
||||
'sanitized/sanitization_information.cc',
|
||||
'sanitized/sanitization_information.h',
|
||||
'sanitized/thread_snapshot_sanitized.cc',
|
||||
'sanitized/thread_snapshot_sanitized.h',
|
||||
'snapshot_constants.h',
|
||||
|
@ -93,6 +93,7 @@
|
||||
'minidump/process_snapshot_minidump_test.cc',
|
||||
'posix/timezone_test.cc',
|
||||
'sanitized/process_snapshot_sanitized_test.cc',
|
||||
'sanitized/sanitization_information_test.cc',
|
||||
'win/cpu_context_win_test.cc',
|
||||
'win/exception_snapshot_win_test.cc',
|
||||
'win/extra_memory_ranges_test.cc',
|
||||
|
@ -281,6 +281,7 @@ static_library("util") {
|
||||
"linux/direct_ptrace_connection.h",
|
||||
"linux/exception_handler_client.cc",
|
||||
"linux/exception_handler_client.h",
|
||||
"linux/exception_handler_protocol.cc",
|
||||
"linux/exception_handler_protocol.h",
|
||||
"linux/exception_information.h",
|
||||
"linux/memory_map.cc",
|
||||
|
25
util/linux/exception_handler_protocol.cc
Normal file
25
util/linux/exception_handler_protocol.cc
Normal file
@ -0,0 +1,25 @@
|
||||
// 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 "util/linux/exception_handler_protocol.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
ClientInformation::ClientInformation()
|
||||
: exception_information_address(0), sanitization_information_address(0) {}
|
||||
|
||||
ClientToServerMessage::ClientToServerMessage()
|
||||
: version(kVersion), type(kCrashDumpRequest), client_info() {}
|
||||
|
||||
} // namespace crashpad
|
@ -35,17 +35,27 @@ enum Bool : char { kBoolFalse, kBoolTrue };
|
||||
|
||||
//! \brief Information about a client registered with an ExceptionHandlerServer.
|
||||
struct ClientInformation {
|
||||
//! \brief Constructs this object.
|
||||
ClientInformation();
|
||||
|
||||
//! \brief The address in the client's address space of an
|
||||
//! ExceptionInformation struct.
|
||||
VMAddress exception_information_address;
|
||||
|
||||
//! \brief The address in the client's address space of a
|
||||
//! SanitizationInformation struct, or 0 if there is no such struct.
|
||||
VMAddress sanitization_information_address;
|
||||
};
|
||||
|
||||
//! \brief The message passed from client to server.
|
||||
struct ClientToServerMessage {
|
||||
static constexpr int32_t kVersion = 1;
|
||||
|
||||
//! \brief Constructs this object.
|
||||
ClientToServerMessage();
|
||||
|
||||
//! \brief Indicates what message version is being used.
|
||||
int32_t version = kVersion;
|
||||
int32_t version;
|
||||
|
||||
enum Type : uint32_t {
|
||||
//! \brief Used to request a crash dump for the sending client.
|
||||
|
@ -129,6 +129,12 @@ class Metrics {
|
||||
//! This value is only used on Linux/Android.
|
||||
kBrokeredPtraceFailed = 9,
|
||||
|
||||
//! \brief Sanitization was requested but could not be initialized.
|
||||
kSanitizationInitializationFailed = 10,
|
||||
|
||||
//! \brief Sanitization caused this crash dump to be skipped.
|
||||
kSkippedDueToSanitization = 11,
|
||||
|
||||
//! \brief The number of values in this enumeration; not a valid value.
|
||||
kMaxValue
|
||||
};
|
||||
|
@ -60,6 +60,7 @@
|
||||
'linux/direct_ptrace_connection.h',
|
||||
'linux/exception_handler_client.cc',
|
||||
'linux/exception_handler_client.h',
|
||||
'linux/exception_handler_protocol.cc',
|
||||
'linux/exception_handler_protocol.h',
|
||||
'linux/exception_information.h',
|
||||
'linux/memory_map.cc',
|
||||
|
Loading…
x
Reference in New Issue
Block a user