From ab5ffb8b6cb5863f15153184e5ca33de2f47321d Mon Sep 17 00:00:00 2001 From: "Liu.andrew.x@gmail.com" Date: Sat, 15 Aug 2015 00:27:27 +0000 Subject: [PATCH] Add check to see if stack pointer is off the stack according to the memory mappings when rating Linux exploitability. R=ivanpe@chromium.org Review URL: https://codereview.chromium.org/1286033002 git-svn-id: http://google-breakpad.googlecode.com/svn/trunk@1487 4c0a9323-5329-0410-9bdc-e9ce6186880e --- src/processor/exploitability_linux.cc | 26 +++++++++++++++++- src/processor/exploitability_linux.h | 4 +++ src/processor/exploitability_unittest.cc | 4 +++ .../linux_stack_pointer_in_module.dmp | Bin 0 -> 38761 bytes .../testdata/linux_stack_pointer_in_stack.dmp | Bin 0 -> 38761 bytes 5 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 src/processor/testdata/linux_stack_pointer_in_module.dmp create mode 100644 src/processor/testdata/linux_stack_pointer_in_stack.dmp diff --git a/src/processor/exploitability_linux.cc b/src/processor/exploitability_linux.cc index 3e99f89e..0fae727c 100644 --- a/src/processor/exploitability_linux.cc +++ b/src/processor/exploitability_linux.cc @@ -102,6 +102,7 @@ ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() { // Check if the instruction pointer is in a valid instruction region // by finding if it maps to an executable part of memory. uint64_t instruction_ptr = 0; + uint64_t stack_ptr = 0; const MinidumpContext *context = exception->GetContext(); if (context == NULL) { @@ -115,8 +116,15 @@ ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() { return EXPLOITABILITY_ERR_PROCESSING; } + // Getting the stack pointer. + if (!context->GetStackPointer(&stack_ptr)) { + BPLOG(INFO) << "Failed to retrieve stack pointer."; + return EXPLOITABILITY_ERR_PROCESSING; + } + // Checking for the instruction pointer in a valid instruction region. - if (!this->InstructionPointerInCode(instruction_ptr)) { + if (!this->InstructionPointerInCode(instruction_ptr) || + this->StackPointerOffStack(stack_ptr)) { return EXPLOITABILITY_HIGH; } @@ -125,6 +133,22 @@ ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() { return EXPLOITABILITY_INTERESTING; } +bool ExploitabilityLinux::StackPointerOffStack(uint64_t stack_ptr) { + MinidumpLinuxMapsList *linux_maps_list = dump_->GetLinuxMapsList(); + // Inconclusive if there are no mappings available. + if (!linux_maps_list) { + return false; + } + const MinidumpLinuxMaps *linux_maps = + linux_maps_list->GetLinuxMapsForAddress(stack_ptr); + // Checks if the stack pointer maps to a valid mapping and if the mapping + // is not the stack. If the mapping has no name, it is inconclusive whether + // it is off the stack. + return !linux_maps || + (linux_maps->GetPathname().compare("") && + linux_maps->GetPathname().compare("[stack]")); +} + 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 6332b074..9d9fa695 100644 --- a/src/processor/exploitability_linux.h +++ b/src/processor/exploitability_linux.h @@ -58,6 +58,10 @@ class ExploitabilityLinux : public Exploitability { // This method 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); }; } // namespace google_breakpad diff --git a/src/processor/exploitability_unittest.cc b/src/processor/exploitability_unittest.cc index 8a42baa0..db668d80 100644 --- a/src/processor/exploitability_unittest.cc +++ b/src/processor/exploitability_unittest.cc @@ -127,6 +127,10 @@ TEST(ExploitabilityTest, TestLinuxEngine) { ExploitabilityFor("linux_inside_module_exe_region1.dmp")); ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, ExploitabilityFor("linux_inside_module_exe_region2.dmp")); + ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING, + ExploitabilityFor("linux_stack_pointer_in_stack.dmp")); + ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH, + ExploitabilityFor("linux_stack_pointer_in_module.dmp")); } } diff --git a/src/processor/testdata/linux_stack_pointer_in_module.dmp b/src/processor/testdata/linux_stack_pointer_in_module.dmp new file mode 100644 index 0000000000000000000000000000000000000000..92b6c21a539f0847b71d351837c838b826f8db7f GIT binary patch literal 38761 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 literal 0 HcmV?d00001 diff --git a/src/processor/testdata/linux_stack_pointer_in_stack.dmp b/src/processor/testdata/linux_stack_pointer_in_stack.dmp new file mode 100644 index 0000000000000000000000000000000000000000..f70b881f21f582c35160bc989c0e624ee98c3531 GIT binary patch literal 38761 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 literal 0 HcmV?d00001