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:
Joshua Peraza 2020-08-06 13:48:45 -07:00 committed by Commit Bot
parent 94b7e45210
commit 2f66eefb79
14 changed files with 169 additions and 172 deletions

View File

@ -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 Tests own logic for deciding whether to
# enable color by checking this scripts own standard output connection.
# The whitelist of TERM values comes from Google Tests
# The list of TERM values comes from Google Tests
# googletest/src/gtest.cc testing::internal::ShouldUseColor().
env = {'CRASHPAD_TEST_DATA_ROOT': device_temp_dir}
gtest_color = os.environ.get('GTEST_COLOR')

View File

@ -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(

View File

@ -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,

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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();
}

View File

@ -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_;

View File

@ -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));

View File

@ -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;
}

View File

@ -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

View File

@ -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]);
}
}

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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));