aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/processor/exploitability_linux.cc59
-rw-r--r--src/processor/exploitability_linux.h5
-rw-r--r--src/processor/exploitability_unittest.cc7
-rw-r--r--src/processor/testdata/linux_divide_by_zero.dmpbin0 -> 38760 bytes
-rw-r--r--src/processor/testdata/linux_jmp_to_0.dmpbin0 -> 38544 bytes
-rw-r--r--src/processor/testdata/linux_null_dereference.dmpbin0 -> 38760 bytes
6 files changed, 71 insertions, 0 deletions
diff --git a/src/processor/exploitability_linux.cc b/src/processor/exploitability_linux.cc
index 13ebad12..c11aed4c 100644
--- a/src/processor/exploitability_linux.cc
+++ b/src/processor/exploitability_linux.cc
@@ -39,6 +39,7 @@
#include "google_breakpad/processor/process_state.h"
#include "google_breakpad/processor/call_stack.h"
#include "google_breakpad/processor/stack_frame.h"
+#include "processor/logging.h"
namespace {
@@ -80,7 +81,65 @@ 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;
+
+ // Getting exception data. (It should exist for all minidumps.)
+ MinidumpException *exception = dump_->GetException();
+ if (exception == NULL) {
+ BPLOG(INFO) << "No exception record.";
+ return EXPLOITABILITY_ERR_PROCESSING;
+ }
+ const MinidumpContext *context = exception->GetContext();
+ if (context == NULL) {
+ BPLOG(INFO) << "No exception context.";
+ return EXPLOITABILITY_ERR_PROCESSING;
+ }
+
+ // Getting instruction pointer based off architecture.
+ uint32_t architecture = context->GetContextCPU();
+ switch (architecture) {
+ case MD_CONTEXT_X86:
+ instruction_ptr = context->GetContextX86()->eip;
+ break;
+ case MD_CONTEXT_AMD64:
+ instruction_ptr = context->GetContextAMD64()->rip;
+ break;
+ default:
+ // TODO(liuandrew): Add support ARM and arm64 architectures.
+ BPLOG(INFO) << "Unsupported architecture.";
+ return EXPLOITABILITY_ERR_PROCESSING;
+ }
+
+ if (!this->InstructionPointerInCode(instruction_ptr)) {
+ return EXPLOITABILITY_HIGH;
+ }
+
return EXPLOITABILITY_NONE;
}
+bool ExploitabilityLinux::InstructionPointerInCode(uint64_t instruction_ptr) {
+ // Here we get memory mapping. Most minidumps will not contain a memory
+ // mapping, so we will commonly resort to checking modules.
+ MinidumpMemoryInfoList *mem_info_list = dump_->GetMemoryInfoList();
+ const MinidumpMemoryInfo *mem_info =
+ mem_info_list ?
+ mem_info_list->GetMemoryInfoForAddress(instruction_ptr) : NULL;
+
+ // Checking if the memory mapping at the instruction pointer is executable.
+ // If there is no memory mapping, we will use the modules as reference.
+ if (mem_info != NULL) {
+ return mem_info->IsExecutable();
+ }
+
+ // If the memory mapping retrieval fails, we will check the modules
+ // to see if the instruction pointer is inside a module.
+ // TODO(liuandrew): Check if the instruction pointer lies in an executable
+ // region within the module.
+ MinidumpModuleList *minidump_module_list = dump_->GetModuleList();
+ return !minidump_module_list ||
+ minidump_module_list->GetModuleForAddress(instruction_ptr);
+}
+
} // namespace google_breakpad
diff --git a/src/processor/exploitability_linux.h b/src/processor/exploitability_linux.h
index c63c0457..95607602 100644
--- a/src/processor/exploitability_linux.h
+++ b/src/processor/exploitability_linux.h
@@ -48,6 +48,11 @@ class ExploitabilityLinux : public Exploitability {
ProcessState *process_state);
virtual ExploitabilityRating CheckPlatformExploitability();
+
+ private:
+ // This method 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);
};
} // namespace google_breakpad
diff --git a/src/processor/exploitability_unittest.cc b/src/processor/exploitability_unittest.cc
index 72994d5a..509ae230 100644
--- a/src/processor/exploitability_unittest.cc
+++ b/src/processor/exploitability_unittest.cc
@@ -113,5 +113,12 @@ TEST(ExploitabilityTest, TestLinuxEngine) {
ExploitabilityFor("linux_overflow.dmp"));
ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
ExploitabilityFor("linux_stacksmash.dmp"));
+ ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE,
+ ExploitabilityFor("linux_divide_by_zero.dmp"));
+ ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE,
+ ExploitabilityFor("linux_null_dereference.dmp"));
+ ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
+ ExploitabilityFor("linux_jmp_to_0.dmp"));
+
}
}
diff --git a/src/processor/testdata/linux_divide_by_zero.dmp b/src/processor/testdata/linux_divide_by_zero.dmp
new file mode 100644
index 00000000..e7b37cf2
--- /dev/null
+++ b/src/processor/testdata/linux_divide_by_zero.dmp
Binary files differ
diff --git a/src/processor/testdata/linux_jmp_to_0.dmp b/src/processor/testdata/linux_jmp_to_0.dmp
new file mode 100644
index 00000000..40e4b15f
--- /dev/null
+++ b/src/processor/testdata/linux_jmp_to_0.dmp
Binary files differ
diff --git a/src/processor/testdata/linux_null_dereference.dmp b/src/processor/testdata/linux_null_dereference.dmp
new file mode 100644
index 00000000..d216a802
--- /dev/null
+++ b/src/processor/testdata/linux_null_dereference.dmp
Binary files differ