mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 14:06:33 +00:00
Update language to eliminate 'whitelist'
Change-Id: I6afe27313093c6867d0276274e6b17b195d9d263 Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2339536 Commit-Queue: Joshua Peraza <jperaza@chromium.org> Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
parent
94b7e45210
commit
2f66eefb79
@ -292,7 +292,7 @@ def _RunOnAndroidTarget(binary_dir, test, android_device, extra_command_line):
|
||||
# pseudo-terminal device, Google Test will not normally enable colored
|
||||
# output, so mimic Google Test’s own logic for deciding whether to
|
||||
# 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().
|
||||
env = {'CRASHPAD_TEST_DATA_ROOT': device_temp_dir}
|
||||
gtest_color = os.environ.get('GTEST_COLOR')
|
||||
|
@ -80,17 +80,16 @@ bool CaptureSnapshot(
|
||||
return false;
|
||||
}
|
||||
|
||||
auto annotations_whitelist = std::make_unique<std::vector<std::string>>();
|
||||
auto memory_range_whitelist =
|
||||
auto allowed_annotations = std::make_unique<std::vector<std::string>>();
|
||||
auto allowed_memory_ranges =
|
||||
std::make_unique<std::vector<std::pair<VMAddress, VMAddress>>>();
|
||||
if (!ReadAnnotationsWhitelist(
|
||||
if (!ReadAllowedAnnotations(range,
|
||||
sanitization_info.allowed_annotations_address,
|
||||
allowed_annotations.get()) ||
|
||||
!ReadAllowedMemoryRanges(
|
||||
range,
|
||||
sanitization_info.annotations_whitelist_address,
|
||||
annotations_whitelist.get()) ||
|
||||
!ReadMemoryRangeWhitelist(
|
||||
range,
|
||||
sanitization_info.memory_range_whitelist_address,
|
||||
memory_range_whitelist.get())) {
|
||||
sanitization_info.allowed_memory_ranges_address,
|
||||
allowed_memory_ranges.get())) {
|
||||
Metrics::ExceptionCaptureResult(
|
||||
Metrics::CaptureResult::kSanitizationInitializationFailed);
|
||||
return false;
|
||||
@ -99,10 +98,10 @@ bool CaptureSnapshot(
|
||||
std::unique_ptr<ProcessSnapshotSanitized> sanitized(
|
||||
new ProcessSnapshotSanitized());
|
||||
if (!sanitized->Initialize(process_snapshot.get(),
|
||||
sanitization_info.annotations_whitelist_address
|
||||
? std::move(annotations_whitelist)
|
||||
sanitization_info.allowed_annotations_address
|
||||
? std::move(allowed_annotations)
|
||||
: nullptr,
|
||||
std::move(memory_range_whitelist),
|
||||
std::move(allowed_memory_ranges),
|
||||
sanitization_info.target_module_address,
|
||||
sanitization_info.sanitize_stacks)) {
|
||||
Metrics::ExceptionCaptureResult(
|
||||
|
@ -27,7 +27,7 @@ namespace internal {
|
||||
//! another MemorySnapshot.
|
||||
//!
|
||||
//! 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.
|
||||
class MemorySnapshotSanitized final : public MemorySnapshot {
|
||||
public:
|
||||
@ -41,7 +41,7 @@ class MemorySnapshotSanitized final : public MemorySnapshot {
|
||||
//! \brief Constructs this object.
|
||||
//!
|
||||
//! \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.
|
||||
MemorySnapshotSanitized(const MemorySnapshot* snapshot,
|
||||
RangeSet* ranges,
|
||||
|
@ -19,9 +19,9 @@ namespace internal {
|
||||
|
||||
namespace {
|
||||
|
||||
bool KeyIsInWhitelist(const std::string& name,
|
||||
const std::vector<std::string>& whitelist) {
|
||||
for (const auto& key : whitelist) {
|
||||
bool KeyIsAllowed(const std::string& name,
|
||||
const std::vector<std::string>& allowed_keys) {
|
||||
for (const auto& key : allowed_keys) {
|
||||
if (name == key) {
|
||||
return true;
|
||||
}
|
||||
@ -33,8 +33,8 @@ bool KeyIsInWhitelist(const std::string& name,
|
||||
|
||||
ModuleSnapshotSanitized::ModuleSnapshotSanitized(
|
||||
const ModuleSnapshot* snapshot,
|
||||
const std::vector<std::string>* annotations_whitelist)
|
||||
: snapshot_(snapshot), annotations_whitelist_(annotations_whitelist) {}
|
||||
const std::vector<std::string>* allowed_annotations)
|
||||
: snapshot_(snapshot), allowed_annotations_(allowed_annotations) {}
|
||||
|
||||
ModuleSnapshotSanitized::~ModuleSnapshotSanitized() = default;
|
||||
|
||||
@ -96,9 +96,9 @@ std::map<std::string, std::string>
|
||||
ModuleSnapshotSanitized::AnnotationsSimpleMap() const {
|
||||
std::map<std::string, std::string> annotations =
|
||||
snapshot_->AnnotationsSimpleMap();
|
||||
if (annotations_whitelist_) {
|
||||
if (allowed_annotations_) {
|
||||
for (auto kv = annotations.begin(); kv != annotations.end(); ++kv) {
|
||||
if (!KeyIsInWhitelist(kv->first, *annotations_whitelist_)) {
|
||||
if (!KeyIsAllowed(kv->first, *allowed_annotations_)) {
|
||||
annotations.erase(kv);
|
||||
}
|
||||
}
|
||||
@ -109,14 +109,14 @@ ModuleSnapshotSanitized::AnnotationsSimpleMap() const {
|
||||
std::vector<AnnotationSnapshot> ModuleSnapshotSanitized::AnnotationObjects()
|
||||
const {
|
||||
std::vector<AnnotationSnapshot> annotations = snapshot_->AnnotationObjects();
|
||||
if (annotations_whitelist_) {
|
||||
std::vector<AnnotationSnapshot> whitelisted;
|
||||
if (allowed_annotations_) {
|
||||
std::vector<AnnotationSnapshot> allowed;
|
||||
for (const auto& anno : annotations) {
|
||||
if (KeyIsInWhitelist(anno.name, *annotations_whitelist_)) {
|
||||
whitelisted.push_back(anno);
|
||||
if (KeyIsAllowed(anno.name, *allowed_annotations_)) {
|
||||
allowed.push_back(anno);
|
||||
}
|
||||
}
|
||||
annotations.swap(whitelisted);
|
||||
annotations.swap(allowed);
|
||||
}
|
||||
return annotations;
|
||||
}
|
||||
|
@ -31,12 +31,11 @@ class ModuleSnapshotSanitized final : public ModuleSnapshot {
|
||||
//! \brief Constructs this object.
|
||||
//!
|
||||
//! \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
|
||||
//! `nullptr`, all annotations will be returned.
|
||||
ModuleSnapshotSanitized(
|
||||
const ModuleSnapshot* snapshot,
|
||||
const std::vector<std::string>* annotations_whitelist);
|
||||
ModuleSnapshotSanitized(const ModuleSnapshot* snapshot,
|
||||
const std::vector<std::string>* allowed_annotations);
|
||||
~ModuleSnapshotSanitized() override;
|
||||
|
||||
// ModuleSnapshot:
|
||||
@ -65,7 +64,7 @@ class ModuleSnapshotSanitized final : public ModuleSnapshot {
|
||||
|
||||
private:
|
||||
const ModuleSnapshot* snapshot_;
|
||||
const std::vector<std::string>* annotations_whitelist_;
|
||||
const std::vector<std::string>* allowed_annotations_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ModuleSnapshotSanitized);
|
||||
};
|
||||
|
@ -84,14 +84,14 @@ ProcessSnapshotSanitized::~ProcessSnapshotSanitized() = default;
|
||||
|
||||
bool ProcessSnapshotSanitized::Initialize(
|
||||
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>>>
|
||||
memory_range_whitelist,
|
||||
allowed_memory_ranges,
|
||||
VMAddress target_module_address,
|
||||
bool sanitize_stacks) {
|
||||
INITIALIZATION_STATE_SET_INITIALIZING(initialized_);
|
||||
snapshot_ = snapshot;
|
||||
annotations_whitelist_ = std::move(annotations_whitelist);
|
||||
allowed_annotations_ = std::move(allowed_annotations);
|
||||
sanitize_stacks_ = sanitize_stacks;
|
||||
|
||||
if (target_module_address) {
|
||||
@ -139,10 +139,10 @@ bool ProcessSnapshotSanitized::Initialize(
|
||||
}
|
||||
}
|
||||
|
||||
if (annotations_whitelist_) {
|
||||
if (allowed_annotations_) {
|
||||
for (const auto module : snapshot_->Modules()) {
|
||||
modules_.emplace_back(std::make_unique<internal::ModuleSnapshotSanitized>(
|
||||
module, annotations_whitelist_.get()));
|
||||
module, allowed_annotations_.get()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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_);
|
||||
return true;
|
||||
@ -227,7 +227,7 @@ std::vector<const ThreadSnapshot*> ProcessSnapshotSanitized::Threads() const {
|
||||
|
||||
std::vector<const ModuleSnapshot*> ProcessSnapshotSanitized::Modules() const {
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
if (!annotations_whitelist_) {
|
||||
if (!allowed_annotations_) {
|
||||
return snapshot_->Modules();
|
||||
}
|
||||
|
||||
|
@ -47,10 +47,10 @@ class ProcessSnapshotSanitized final : public ProcessSnapshot {
|
||||
//! this object.
|
||||
//!
|
||||
//! \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
|
||||
//! 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.
|
||||
//! \param[in] target_module_address An address in the target process'
|
||||
//! address space within the bounds of a module to target. If the
|
||||
@ -65,9 +65,9 @@ class ProcessSnapshotSanitized final : public ProcessSnapshot {
|
||||
//! should be filtered entirely. Otherwise `true`.
|
||||
bool Initialize(
|
||||
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>>>
|
||||
memory_range_whitelist,
|
||||
allowed_memory_ranges,
|
||||
VMAddress target_module_address,
|
||||
bool sanitize_stacks);
|
||||
|
||||
@ -93,7 +93,7 @@ class ProcessSnapshotSanitized final : public ProcessSnapshot {
|
||||
const ProcessMemory* Memory() const override;
|
||||
|
||||
private:
|
||||
// Only used when annotations_whitelist_ != nullptr.
|
||||
// Only used when allowed_annotations_ != nullptr.
|
||||
std::vector<std::unique_ptr<internal::ModuleSnapshotSanitized>> modules_;
|
||||
|
||||
// Only used when sanitize_stacks_ == true.
|
||||
@ -102,7 +102,7 @@ class ProcessSnapshotSanitized final : public ProcessSnapshot {
|
||||
RangeSet address_ranges_;
|
||||
const ProcessSnapshot* snapshot_;
|
||||
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_;
|
||||
InitializationStateDcheck initialized_;
|
||||
|
||||
|
@ -74,10 +74,10 @@ class ExceptionGenerator {
|
||||
DISALLOW_COPY_AND_ASSIGN(ExceptionGenerator);
|
||||
};
|
||||
|
||||
constexpr char kWhitelistedAnnotationName[] = "name_of_whitelisted_anno";
|
||||
constexpr char kWhitelistedAnnotationValue[] = "some_value";
|
||||
constexpr char kNonWhitelistedAnnotationName[] = "non_whitelisted_anno";
|
||||
constexpr char kNonWhitelistedAnnotationValue[] = "private_annotation";
|
||||
constexpr char kAllowedAnnotationName[] = "name_of_allowed_anno";
|
||||
constexpr char kAllowedAnnotationValue[] = "some_value";
|
||||
constexpr char kNonAllowedAnnotationName[] = "non_allowed_anno";
|
||||
constexpr char kNonAllowedAnnotationValue[] = "private_annotation";
|
||||
constexpr char kSensitiveStackData[] = "sensitive_stack_data";
|
||||
|
||||
struct ChildTestAddresses {
|
||||
@ -92,13 +92,11 @@ void ChildTestFunction() {
|
||||
FileHandle in = StdioFileHandle(StdioStream::kStandardInput);
|
||||
FileHandle out = StdioFileHandle(StdioStream::kStandardOutput);
|
||||
|
||||
static StringAnnotation<32> whitelisted_annotation(
|
||||
kWhitelistedAnnotationName);
|
||||
whitelisted_annotation.Set(kWhitelistedAnnotationValue);
|
||||
static StringAnnotation<32> allowed_annotation(kAllowedAnnotationName);
|
||||
allowed_annotation.Set(kAllowedAnnotationValue);
|
||||
|
||||
static StringAnnotation<32> non_whitelisted_annotation(
|
||||
kNonWhitelistedAnnotationName);
|
||||
non_whitelisted_annotation.Set(kNonWhitelistedAnnotationValue);
|
||||
static StringAnnotation<32> non_allowed_annotation(kNonAllowedAnnotationName);
|
||||
non_allowed_annotation.Set(kNonAllowedAnnotationValue);
|
||||
|
||||
char string_data[strlen(kSensitiveStackData) + 1];
|
||||
strcpy(string_data, kSensitiveStackData);
|
||||
@ -126,39 +124,39 @@ CRASHPAD_CHILD_TEST_MAIN(ChildToBeSanitized) {
|
||||
}
|
||||
|
||||
void ExpectAnnotations(ProcessSnapshot* snapshot, bool sanitized) {
|
||||
bool found_whitelisted = false;
|
||||
bool found_non_whitelisted = false;
|
||||
bool found_allowed = false;
|
||||
bool found_non_allowed = false;
|
||||
for (auto module : snapshot->Modules()) {
|
||||
for (const auto& anno : module->AnnotationObjects()) {
|
||||
if (anno.name == kWhitelistedAnnotationName) {
|
||||
found_whitelisted = true;
|
||||
} else if (anno.name == kNonWhitelistedAnnotationName) {
|
||||
found_non_whitelisted = true;
|
||||
if (anno.name == kAllowedAnnotationName) {
|
||||
found_allowed = true;
|
||||
} else if (anno.name == kNonAllowedAnnotationName) {
|
||||
found_non_allowed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EXPECT_TRUE(found_whitelisted);
|
||||
EXPECT_TRUE(found_allowed);
|
||||
if (sanitized) {
|
||||
EXPECT_FALSE(found_non_whitelisted);
|
||||
EXPECT_FALSE(found_non_allowed);
|
||||
} else {
|
||||
EXPECT_TRUE(found_non_whitelisted);
|
||||
EXPECT_TRUE(found_non_allowed);
|
||||
}
|
||||
}
|
||||
|
||||
void ExpectProcessMemory(ProcessSnapshot* snapshot,
|
||||
VMAddress whitelisted_byte,
|
||||
VMAddress allowed_byte,
|
||||
bool sanitized) {
|
||||
auto memory = snapshot->Memory();
|
||||
|
||||
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) {
|
||||
EXPECT_FALSE(unwhitelisted_read);
|
||||
EXPECT_FALSE(disallowed_read);
|
||||
} else {
|
||||
EXPECT_TRUE(unwhitelisted_read);
|
||||
EXPECT_TRUE(disallowed_read);
|
||||
}
|
||||
}
|
||||
|
||||
@ -272,18 +270,18 @@ class SanitizeTest : public MultiprocessExec {
|
||||
addrs.string_address,
|
||||
/* sanitized= */ false);
|
||||
|
||||
auto annotations_whitelist = std::make_unique<std::vector<std::string>>();
|
||||
annotations_whitelist->push_back(kWhitelistedAnnotationName);
|
||||
auto allowed_annotations = std::make_unique<std::vector<std::string>>();
|
||||
allowed_annotations->push_back(kAllowedAnnotationName);
|
||||
|
||||
auto memory_ranges_whitelist =
|
||||
auto allowed_memory_ranges =
|
||||
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));
|
||||
|
||||
ProcessSnapshotSanitized sanitized;
|
||||
ASSERT_TRUE(sanitized.Initialize(&snapshot,
|
||||
std::move(annotations_whitelist),
|
||||
std::move(memory_ranges_whitelist),
|
||||
std::move(allowed_annotations),
|
||||
std::move(allowed_memory_ranges),
|
||||
addrs.module_address,
|
||||
true));
|
||||
|
||||
|
@ -24,18 +24,18 @@ namespace crashpad {
|
||||
namespace {
|
||||
|
||||
template <typename Pointer>
|
||||
bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory,
|
||||
VMAddress whitelist_address,
|
||||
std::vector<std::string>* whitelist) {
|
||||
if (!whitelist_address) {
|
||||
bool ReadAllowedAnnotations(const ProcessMemoryRange& memory,
|
||||
VMAddress list_address,
|
||||
std::vector<std::string>* allowed_annotations) {
|
||||
if (!list_address) {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> local_whitelist;
|
||||
std::vector<std::string> local_allowed_annotations;
|
||||
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) {
|
||||
whitelist->swap(local_whitelist);
|
||||
allowed_annotations->swap(local_allowed_annotations);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -44,8 +44,8 @@ bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory,
|
||||
name_address, Annotation::kNameMaxLength, &name)) {
|
||||
return false;
|
||||
}
|
||||
local_whitelist.push_back(name);
|
||||
whitelist_address += sizeof(Pointer);
|
||||
local_allowed_annotations.push_back(name);
|
||||
list_address += sizeof(Pointer);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -53,27 +53,27 @@ bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory,
|
||||
|
||||
} // namespace
|
||||
|
||||
bool ReadAnnotationsWhitelist(const ProcessMemoryRange& memory,
|
||||
VMAddress whitelist_address,
|
||||
std::vector<std::string>* whitelist) {
|
||||
return memory.Is64Bit() ? ReadAnnotationsWhitelist<uint64_t>(
|
||||
memory, whitelist_address, whitelist)
|
||||
: ReadAnnotationsWhitelist<uint32_t>(
|
||||
memory, whitelist_address, whitelist);
|
||||
bool ReadAllowedAnnotations(const ProcessMemoryRange& memory,
|
||||
VMAddress list_address,
|
||||
std::vector<std::string>* allowed_annotations) {
|
||||
return memory.Is64Bit() ? ReadAllowedAnnotations<uint64_t>(
|
||||
memory, list_address, allowed_annotations)
|
||||
: ReadAllowedAnnotations<uint32_t>(
|
||||
memory, list_address, allowed_annotations);
|
||||
}
|
||||
|
||||
bool ReadMemoryRangeWhitelist(
|
||||
bool ReadAllowedMemoryRanges(
|
||||
const ProcessMemoryRange& memory,
|
||||
VMAddress whitelist_address,
|
||||
std::vector<std::pair<VMAddress, VMAddress>>* whitelist) {
|
||||
whitelist->clear();
|
||||
if (!whitelist_address) {
|
||||
VMAddress list_address,
|
||||
std::vector<std::pair<VMAddress, VMAddress>>* allowed_memory_ranges) {
|
||||
allowed_memory_ranges->clear();
|
||||
if (!list_address) {
|
||||
return true;
|
||||
}
|
||||
|
||||
SanitizationMemoryRangeWhitelist list;
|
||||
if (!memory.Read(whitelist_address, sizeof(list), &list)) {
|
||||
LOG(ERROR) << "Failed to read memory range whitelist.";
|
||||
SanitizationAllowedMemoryRanges list;
|
||||
if (!memory.Read(list_address, sizeof(list), &list)) {
|
||||
LOG(ERROR) << "Failed to read allowed memory ranges";
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -84,32 +84,32 @@ bool ReadMemoryRangeWhitelist(
|
||||
// An upper bound of entries that we never expect to see more than.
|
||||
constexpr size_t kMaxListSize = 256;
|
||||
if (list.size > kMaxListSize) {
|
||||
LOG(ERROR) << "Whitelist exceeded maximum, size=" << list.size;
|
||||
LOG(ERROR) << "list exceeded maximum, size=" << list.size;
|
||||
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,
|
||||
ranges.data())) {
|
||||
LOG(ERROR) << "Failed to read memory range whitelist entries.";
|
||||
LOG(ERROR) << "Failed to read allowed memory ranges";
|
||||
return false;
|
||||
}
|
||||
|
||||
const VMAddress vm_max = memory.Is64Bit()
|
||||
? std::numeric_limits<uint64_t>::max()
|
||||
: std::numeric_limits<uint32_t>::max();
|
||||
std::vector<std::pair<VMAddress, VMAddress>> local_whitelist;
|
||||
for (size_t i = 0; i < list.size; i++) {
|
||||
std::vector<std::pair<VMAddress, VMAddress>> local_allowed_memory_ranges;
|
||||
for (size_t i = 0; i < list.size; ++i) {
|
||||
if (ranges[i].base > vm_max || ranges[i].length > vm_max - ranges[i].base) {
|
||||
LOG(ERROR) << "Invalid memory range whitelist entry base="
|
||||
<< ranges[i].base << " length=" << ranges[i].length;
|
||||
LOG(ERROR) << "Invalid range: base=" << ranges[i].base
|
||||
<< " length=" << ranges[i].length;
|
||||
return false;
|
||||
}
|
||||
local_whitelist.emplace_back(ranges[i].base,
|
||||
ranges[i].base + ranges[i].length);
|
||||
local_allowed_memory_ranges.emplace_back(ranges[i].base,
|
||||
ranges[i].base + ranges[i].length);
|
||||
}
|
||||
|
||||
whitelist->swap(local_whitelist);
|
||||
allowed_memory_ranges->swap(local_allowed_memory_ranges);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,9 @@ namespace crashpad {
|
||||
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;
|
||||
//! names of allowed annotations. This value is 0 if all annotations are
|
||||
//! allowed.
|
||||
VMAddress allowed_annotations_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
|
||||
@ -47,17 +47,17 @@ struct SanitizationInformation {
|
||||
VMAddress target_module_address;
|
||||
|
||||
//! \brief The address in the client process' address space of a
|
||||
//! a \a SanitizationMemoryRangeWhitelist, a list of whitelisted address
|
||||
//! ranges allowed to be accessed by ProcessMemorySanitized. This value
|
||||
//! is 0 if no memory is allowed to be read using ProcessMemorySanitized.
|
||||
VMAddress memory_range_whitelist_address;
|
||||
//! \a SanitizationAllowedMemoryRanges, a list of address ranges allowed
|
||||
//! to be accessed by ProcessMemorySanitized. This value is 0 if no memory
|
||||
//! is allowed to be read using ProcessMemorySanitized.
|
||||
VMAddress allowed_memory_ranges_address;
|
||||
|
||||
//! \brief Non-zero if stacks should be sanitized for possible PII.
|
||||
uint8_t sanitize_stacks;
|
||||
};
|
||||
|
||||
//! \brief Describes a list of white listed memory ranges.
|
||||
struct SanitizationMemoryRangeWhitelist {
|
||||
//! \brief Describes a list of allowed memory ranges.
|
||||
struct SanitizationAllowedMemoryRanges {
|
||||
//! \brief Describes a range of memory.
|
||||
struct Range {
|
||||
VMAddress base;
|
||||
@ -71,30 +71,30 @@ struct SanitizationMemoryRangeWhitelist {
|
||||
|
||||
#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] 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
|
||||
//! \param[in] list_address The address in the target process' address space of
|
||||
//! a nullptr terminated array of NUL-terminated strings.
|
||||
//! \param[out] allowed_annotations The list 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);
|
||||
bool ReadAllowedAnnotations(const ProcessMemoryRange& memory,
|
||||
VMAddress list_address,
|
||||
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] whitelist_address The address in the target process' address
|
||||
//! space of a nullptr terminated array of NUL-terminated strings.
|
||||
//! \param[out] whitelist A list of whitelisted memory regions, valid only if
|
||||
//! this function returns `true`.
|
||||
//! \param[in] list_address The address in the target process' address space of
|
||||
//! a nullptr terminated array of NUL-terminated strings.
|
||||
//! \param[out] allowed_memory_ranges A list of allowed memory regions, valid
|
||||
//! only if this function returns `true`.
|
||||
//! \return `true` on success, `false` on failure with a message logged.
|
||||
bool ReadMemoryRangeWhitelist(
|
||||
bool ReadAllowedMemoryRanges(
|
||||
const ProcessMemoryRange& memory,
|
||||
VMAddress whitelist_address,
|
||||
std::vector<std::pair<VMAddress, VMAddress>>* whitelist);
|
||||
VMAddress list_address,
|
||||
std::vector<std::pair<VMAddress, VMAddress>>* allowed_memory_ranges);
|
||||
|
||||
} // namespace crashpad
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace crashpad {
|
||||
namespace test {
|
||||
namespace {
|
||||
|
||||
class WhitelistTest : public testing::Test {
|
||||
class AllowedAnnotationsTest : public testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
ASSERT_TRUE(memory_.Initialize(getpid()));
|
||||
@ -36,33 +36,34 @@ class WhitelistTest : public testing::Test {
|
||||
}
|
||||
|
||||
protected:
|
||||
bool ReadWhitelist(const char* const* address) {
|
||||
return ReadAnnotationsWhitelist(
|
||||
range_, FromPointerCast<VMAddress>(address), &whitelist_);
|
||||
bool DoReadAllowedAnnotations(const char* const* address) {
|
||||
return ReadAllowedAnnotations(
|
||||
range_, FromPointerCast<VMAddress>(address), &allowed_annotations_);
|
||||
}
|
||||
|
||||
ProcessMemoryLinux memory_;
|
||||
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) {
|
||||
ASSERT_TRUE(ReadWhitelist(kEmptyWhitelist));
|
||||
EXPECT_EQ(whitelist_, std::vector<std::string>());
|
||||
TEST_F(AllowedAnnotationsTest, EmptyAllowedAnnotations) {
|
||||
ASSERT_TRUE(DoReadAllowedAnnotations(kEmptyAllowedAnnotations));
|
||||
EXPECT_EQ(allowed_annotations_, std::vector<std::string>());
|
||||
}
|
||||
|
||||
const char* const kNonEmptyWhitelist[] = {"string1",
|
||||
"another_string",
|
||||
"",
|
||||
nullptr};
|
||||
const char* const kNonEmptyAllowedAnnotations[] = {"string1",
|
||||
"another_string",
|
||||
"",
|
||||
nullptr};
|
||||
|
||||
TEST_F(WhitelistTest, NonEmptyWhitelist) {
|
||||
ASSERT_TRUE(ReadWhitelist(kNonEmptyWhitelist));
|
||||
ASSERT_EQ(whitelist_.size(), base::size(kNonEmptyWhitelist) - 1);
|
||||
for (size_t index = 0; index < base::size(kNonEmptyWhitelist) - 1; ++index) {
|
||||
EXPECT_EQ(whitelist_[index], kNonEmptyWhitelist[index]);
|
||||
TEST_F(AllowedAnnotationsTest, NonEmptyAllowedAnnotations) {
|
||||
ASSERT_TRUE(DoReadAllowedAnnotations(kNonEmptyAllowedAnnotations));
|
||||
ASSERT_EQ(allowed_annotations_.size(),
|
||||
base::size(kNonEmptyAllowedAnnotations) - 1);
|
||||
for (size_t index = 0; index < allowed_annotations_.size(); ++index) {
|
||||
EXPECT_EQ(allowed_annotations_[index], kNonEmptyAllowedAnnotations[index]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,17 +28,17 @@
|
||||
namespace crashpad {
|
||||
|
||||
ProcessMemorySanitized::ProcessMemorySanitized()
|
||||
: ProcessMemory(), memory_(nullptr), whitelist_() {}
|
||||
: ProcessMemory(), memory_(nullptr), allowed_ranges_() {}
|
||||
|
||||
ProcessMemorySanitized::~ProcessMemorySanitized() {}
|
||||
|
||||
bool ProcessMemorySanitized::Initialize(
|
||||
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_);
|
||||
memory_ = memory;
|
||||
if (whitelist)
|
||||
whitelist_ = *whitelist;
|
||||
if (allowed_ranges)
|
||||
allowed_ranges_ = *allowed_ranges;
|
||||
INITIALIZATION_STATE_SET_VALID(initialized_);
|
||||
return true;
|
||||
}
|
||||
@ -49,7 +49,7 @@ ssize_t ProcessMemorySanitized::ReadUpTo(VMAddress address,
|
||||
INITIALIZATION_STATE_DCHECK_VALID(initialized_);
|
||||
|
||||
VMAddress end = address + size;
|
||||
for (auto&& entry : whitelist_) {
|
||||
for (auto&& entry : allowed_ranges_) {
|
||||
if (address >= entry.first && address < entry.second &&
|
||||
end >= entry.first && end <= entry.second) {
|
||||
return memory_->ReadUpTo(address, size, buffer);
|
||||
@ -57,7 +57,7 @@ ssize_t ProcessMemorySanitized::ReadUpTo(VMAddress address,
|
||||
}
|
||||
|
||||
DLOG(ERROR)
|
||||
<< "ProcessMemorySanitized failed to read unwhitelisted region. address="
|
||||
<< "ProcessMemorySanitized failed to read disallowed region. address="
|
||||
<< address << " size=" << size;
|
||||
return 0;
|
||||
}
|
||||
|
@ -34,25 +34,25 @@ class ProcessMemorySanitized final : public ProcessMemory {
|
||||
~ProcessMemorySanitized();
|
||||
|
||||
//! \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
|
||||
//! in this class.
|
||||
//!
|
||||
//! \param[in] memory The memory object to read whitelisted regions from.
|
||||
//! \param[in] whitelist A whitelist of memory regions.
|
||||
//! \param[in] memory The memory object to read memory from.
|
||||
//! \param[in] allowed_ranges A list of allowed memory ranges.
|
||||
//!
|
||||
//! \return `true` on success, `false` on failure with a message logged.
|
||||
bool Initialize(
|
||||
const ProcessMemory* memory,
|
||||
const std::vector<std::pair<VMAddress, VMAddress>>* whitelist);
|
||||
const std::vector<std::pair<VMAddress, VMAddress>>* allowed_ranges);
|
||||
|
||||
private:
|
||||
ssize_t ReadUpTo(VMAddress address, size_t size, void* buffer) const override;
|
||||
|
||||
const ProcessMemory* memory_;
|
||||
InitializationStateDcheck initialized_;
|
||||
std::vector<std::pair<VMAddress, VMAddress>> whitelist_;
|
||||
std::vector<std::pair<VMAddress, VMAddress>> allowed_ranges_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(ProcessMemorySanitized);
|
||||
};
|
||||
|
@ -23,7 +23,7 @@ namespace crashpad {
|
||||
namespace test {
|
||||
namespace {
|
||||
|
||||
TEST(ProcessMemorySanitized, DenyOnEmptyWhitelist) {
|
||||
TEST(ProcessMemorySanitized, DenyDisallowedMemory) {
|
||||
ProcessMemoryNative memory;
|
||||
ASSERT_TRUE(memory.Initialize(GetSelfProcess()));
|
||||
|
||||
@ -34,25 +34,25 @@ TEST(ProcessMemorySanitized, DenyOnEmptyWhitelist) {
|
||||
san_null.Initialize(&memory, nullptr);
|
||||
EXPECT_FALSE(san_null.Read(FromPointerCast<VMAddress>(&c), 1, &out));
|
||||
|
||||
std::vector<std::pair<VMAddress, VMAddress>> whitelist;
|
||||
ProcessMemorySanitized san_blank;
|
||||
san_blank.Initialize(&memory, &whitelist);
|
||||
EXPECT_FALSE(san_blank.Read(FromPointerCast<VMAddress>(&c), 1, &out));
|
||||
std::vector<std::pair<VMAddress, VMAddress>> allowed_memory;
|
||||
ProcessMemorySanitized san_empty;
|
||||
san_empty.Initialize(&memory, &allowed_memory);
|
||||
EXPECT_FALSE(san_empty.Read(FromPointerCast<VMAddress>(&c), 1, &out));
|
||||
}
|
||||
|
||||
TEST(ProcessMemorySanitized, WhitelistingWorks) {
|
||||
TEST(ProcessMemorySanitized, AllowedMemory) {
|
||||
ProcessMemoryNative memory;
|
||||
ASSERT_TRUE(memory.Initialize(GetSelfProcess()));
|
||||
|
||||
char str[4] = "ABC";
|
||||
char out[4];
|
||||
|
||||
std::vector<std::pair<VMAddress, VMAddress>> whitelist;
|
||||
whitelist.push_back(std::make_pair(FromPointerCast<VMAddress>(str + 1),
|
||||
FromPointerCast<VMAddress>(str + 2)));
|
||||
std::vector<std::pair<VMAddress, VMAddress>> allowed_memory;
|
||||
allowed_memory.push_back(std::make_pair(FromPointerCast<VMAddress>(str + 1),
|
||||
FromPointerCast<VMAddress>(str + 2)));
|
||||
|
||||
ProcessMemorySanitized sanitized;
|
||||
sanitized.Initialize(&memory, &whitelist);
|
||||
sanitized.Initialize(&memory, &allowed_memory);
|
||||
|
||||
EXPECT_FALSE(sanitized.Read(FromPointerCast<VMAddress>(str), 1, &out));
|
||||
EXPECT_TRUE(sanitized.Read(FromPointerCast<VMAddress>(str + 1), 1, &out));
|
||||
|
Loading…
x
Reference in New Issue
Block a user