From 4a7e088a278e26ab6c5f0972fd053ec610deb5bb Mon Sep 17 00:00:00 2001 From: Tobias Sargeant Date: Thu, 23 Feb 2017 14:22:36 +0000 Subject: [PATCH] Make stack sanitization elide pointers to non-executable mappings. The address space of every Android Java process is approximately 50% mapped, which means that sanitization tends to be ineffective because most string fragments are plausibly pointers into some mapping. For example, the zygote on 32 bit devices has the following mappings made by dalvik and this covers all 4 byte strings starting with a character between 0x13 and 0x52 (which includes all uppercase characters up to and including 'R'). 12c00000-12d16000 12d16000-32c00000 32c00000-32c01000 32c01000-52c00000 In order to perform stack unwinding we only need pointers into the stack of the thread in question, and pointers to executable mappings. If we reduce the set of considered mappings to those mappings alone, then only ~2% of the address space is left unelided. BUG=664460 Change-Id: I1cc27821659acfb91d658f42a83a24c176505a88 Reviewed-on: https://chromium-review.googlesource.com/446500 Reviewed-by: Robert Sesek --- src/client/linux/minidump_writer/linux_dumper.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/linux/minidump_writer/linux_dumper.cc b/src/client/linux/minidump_writer/linux_dumper.cc index e1e7b49c..3b8c80ab 100644 --- a/src/client/linux/minidump_writer/linux_dumper.cc +++ b/src/client/linux/minidump_writer/linux_dumper.cc @@ -752,6 +752,7 @@ void LinuxDumper::SanitizeStackCopy(uint8_t* stack_copy, size_t stack_len, // bit, modulo the bitfield size, is not set then there does not // exist a mapping in mappings_ that would contain that pointer. for (size_t i = 0; i < mappings_.size(); ++i) { + if (!mappings_[i]->exec) continue; // For each mapping, work out the (unmodulo'ed) range of bits to // set. uintptr_t start = mappings_[i]->start_addr; @@ -791,7 +792,8 @@ void LinuxDumper::SanitizeStackCopy(uint8_t* stack_copy, size_t stack_len, } uintptr_t test = addr >> shift; if (could_hit_mapping[(test >> 3) & array_mask] & (1 << (test & 7)) && - (hit_mapping = FindMappingNoBias(addr)) != nullptr) { + (hit_mapping = FindMappingNoBias(addr)) != nullptr && + hit_mapping->exec) { last_hit_mapping = hit_mapping; continue; }