Chromium Code Reviews| Index: src/processor/exploitability_linux.cc |
| =================================================================== |
| --- src/processor/exploitability_linux.cc (revision 1462) |
| +++ src/processor/exploitability_linux.cc (working copy) |
| @@ -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,81 @@ |
| } |
| } |
| + // 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; |
| + |
| + // get exception data (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; |
| + } |
| + |
| + // get instruction pointer based off architecture |
| + uint32_t architecture = context->GetContextCPU(); |
| + switch (architecture) { |
| + case MD_CONTEXT_X86: |
| + stack_ptr = context->GetContextX86()->esp; |
| + instruction_ptr = context->GetContextX86()->eip; |
| + break; |
| + case MD_CONTEXT_AMD64: |
| + stack_ptr = context->GetContextAMD64()->rsp; |
| + instruction_ptr = context->GetContextAMD64()->rip; |
| + break; |
| + default: |
|
ivanpe
2015/06/24 19:14:06
Please, add a TODO to handle ARM and arm64.
liuandrew
2015/06/24 20:59:36
Done.
|
| + BPLOG(INFO) << "Unsupported architecture."; |
| + return EXPLOITABILITY_ERR_PROCESSING; |
| + } |
| + |
| + if (!this->InstructionPointerInCode(instruction_ptr, stack_ptr)) { |
| + return EXPLOITABILITY_HIGH; |
|
ivanpe
2015/06/24 19:14:06
Please, check with Cris Neckar or other security f
liuandrew
2015/06/24 20:59:36
Based off an automatic email response that I recei
|
| + } |
| + |
| return EXPLOITABILITY_NONE; |
| } |
| +bool ExploitabilityLinux::InstructionPointerInCode(uint64_t instruction_ptr, |
| + uint64_t stack_ptr) { |
| + // get memory mapping |
| + // most minidumps will not contain a memory mapping, so we will commonly |
| + // resort to stack pointer approximation and checking modules |
| + MinidumpMemoryInfoList *mem_info_list = dump_->GetMemoryInfoList(); |
| + const MinidumpMemoryInfo *mem_info = |
| + mem_info_list ? |
| + mem_info_list->GetMemoryInfoForAddress(instruction_ptr) : NULL; |
| + |
| + // check if the memory mapping at the instruction pointer is executable |
| + // if there is no memory mapping, we will use stack pointer approximation |
| + // and the modules as reference |
| + if (mem_info != NULL) { |
| + return mem_info->IsExecutable(); |
| + } |
| + |
| + // if the memory mapping retrieval fails, we will approximate |
| + // the results by using the stack pointer, and we will check modules |
| + // to see if the instruction pointer is inside a module |
| + |
| + // approximating if the instruction pointer is on the stack via |
|
ivanpe
2015/06/24 19:14:06
As discussed offline, please remove this check, si
liuandrew
2015/06/24 20:59:36
Done.
|
| + // stack pointer offset |
| + const uint64_t offset = 0x2000; |
| + if (stack_ptr + offset >= instruction_ptr && |
| + stack_ptr - offset <= instruction_ptr) { |
| + return false; |
| + } |
| + |
| + // checking modules for instruction pointer inside any known module |
| + // TODO(liuandrew) the entirety of a module is not necessarily executable |
| + // check if the instruction pointer lies in an executable region |
| + MinidumpModuleList *minidump_module_list = dump_->GetModuleList(); |
| + return !minidump_module_list || |
| + minidump_module_list->GetModuleForAddress(instruction_ptr); |
| +} |
| + |
| } // namespace google_breakpad |