aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/google_breakpad/processor/minidump.h3
-rw-r--r--src/processor/exploitability_linux.cc21
-rw-r--r--src/processor/exploitability_linux.h8
-rw-r--r--src/processor/exploitability_unittest.cc4
-rw-r--r--src/processor/testdata/linux_executable_heap.dmpbin0 -> 38761 bytes
-rw-r--r--src/processor/testdata/linux_executable_stack.dmpbin0 -> 38794 bytes
6 files changed, 33 insertions, 3 deletions
diff --git a/src/google_breakpad/processor/minidump.h b/src/google_breakpad/processor/minidump.h
index ce1af851..2b5025e4 100644
--- a/src/google_breakpad/processor/minidump.h
+++ b/src/google_breakpad/processor/minidump.h
@@ -916,6 +916,9 @@ class MinidumpLinuxMapsList : public MinidumpStream {
public:
virtual ~MinidumpLinuxMapsList();
+ // Get number of mappings.
+ unsigned int get_maps_count() const { return valid_ ? maps_count_ : 0; }
+
// Get mapping at the given memory address. The caller owns the pointer.
const MinidumpLinuxMaps *GetLinuxMapsForAddress(uint64_t address) const;
// Get mapping at the given index. The caller owns the pointer.
diff --git a/src/processor/exploitability_linux.cc b/src/processor/exploitability_linux.cc
index 0fae727c..46cad318 100644
--- a/src/processor/exploitability_linux.cc
+++ b/src/processor/exploitability_linux.cc
@@ -124,7 +124,8 @@ ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() {
// Checking for the instruction pointer in a valid instruction region.
if (!this->InstructionPointerInCode(instruction_ptr) ||
- this->StackPointerOffStack(stack_ptr)) {
+ this->StackPointerOffStack(stack_ptr) ||
+ this->ExecutableStackOrHeap()) {
return EXPLOITABILITY_HIGH;
}
@@ -149,6 +150,24 @@ bool ExploitabilityLinux::StackPointerOffStack(uint64_t stack_ptr) {
linux_maps->GetPathname().compare("[stack]"));
}
+bool ExploitabilityLinux::ExecutableStackOrHeap() {
+ MinidumpLinuxMapsList *linux_maps_list = dump_->GetLinuxMapsList();
+ if (linux_maps_list) {
+ for (size_t i = 0; i < linux_maps_list->get_maps_count(); i++) {
+ const MinidumpLinuxMaps *linux_maps =
+ linux_maps_list->GetLinuxMapsAtIndex(i);
+ // Check for executable stack or heap for each mapping.
+ if (linux_maps &&
+ (!linux_maps->GetPathname().compare("[stack]") ||
+ !linux_maps->GetPathname().compare("[heap]")) &&
+ linux_maps->IsExecutable()) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
bool ExploitabilityLinux::InstructionPointerInCode(uint64_t instruction_ptr) {
// Get Linux memory mapping from /proc/self/maps. Checking whether the
// region the instruction pointer is in has executable permission can tell
diff --git a/src/processor/exploitability_linux.h b/src/processor/exploitability_linux.h
index 9d9fa695..857185b4 100644
--- a/src/processor/exploitability_linux.h
+++ b/src/processor/exploitability_linux.h
@@ -51,17 +51,21 @@ class ExploitabilityLinux : public Exploitability {
virtual ExploitabilityRating CheckPlatformExploitability();
private:
- // This method takes the address of the instruction pointer and returns
+ // Takes the address of the instruction pointer and returns
// whether the instruction pointer lies in a valid instruction region.
bool InstructionPointerInCode(uint64_t instruction_ptr);
- // This method checks the exception that triggered the creation of the
+ // Checks the exception that triggered the creation of the
// minidump and reports whether the exception suggests no exploitability.
bool BenignCrashTrigger(const MDRawExceptionStream *raw_exception_stream);
// Checks if the stack pointer points to a memory mapping that is not
// labelled as the stack.
bool StackPointerOffStack(uint64_t stack_ptr);
+
+ // Checks if the stack or heap are marked executable according
+ // to the memory mappings.
+ bool ExecutableStackOrHeap();
};
} // namespace google_breakpad
diff --git a/src/processor/exploitability_unittest.cc b/src/processor/exploitability_unittest.cc
index db668d80..db7f1cb0 100644
--- a/src/processor/exploitability_unittest.cc
+++ b/src/processor/exploitability_unittest.cc
@@ -131,6 +131,10 @@ TEST(ExploitabilityTest, TestLinuxEngine) {
ExploitabilityFor("linux_stack_pointer_in_stack.dmp"));
ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
ExploitabilityFor("linux_stack_pointer_in_module.dmp"));
+ ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
+ ExploitabilityFor("linux_executable_stack.dmp"));
+ ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
+ ExploitabilityFor("linux_executable_heap.dmp"));
}
}
diff --git a/src/processor/testdata/linux_executable_heap.dmp b/src/processor/testdata/linux_executable_heap.dmp
new file mode 100644
index 00000000..f8c807fa
--- /dev/null
+++ b/src/processor/testdata/linux_executable_heap.dmp
Binary files differ
diff --git a/src/processor/testdata/linux_executable_stack.dmp b/src/processor/testdata/linux_executable_stack.dmp
new file mode 100644
index 00000000..c424cb20
--- /dev/null
+++ b/src/processor/testdata/linux_executable_stack.dmp
Binary files differ