Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 Google Inc. | 1 // Copyright (c) 2013 Google Inc. |
| 2 // All rights reserved. | 2 // All rights reserved. |
| 3 // | 3 // |
| 4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
| 5 // modification, are permitted provided that the following conditions are | 5 // modification, are permitted provided that the following conditions are |
| 6 // met: | 6 // met: |
| 7 // | 7 // |
| 8 // * Redistributions of source code must retain the above copyright | 8 // * Redistributions of source code must retain the above copyright |
| 9 // notice, this list of conditions and the following disclaimer. | 9 // notice, this list of conditions and the following disclaimer. |
| 10 // * Redistributions in binary form must reproduce the above | 10 // * Redistributions in binary form must reproduce the above |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 32 // Provides a guess at the exploitability of the crash for the Linux | 32 // Provides a guess at the exploitability of the crash for the Linux |
| 33 // platform given a minidump and process_state. | 33 // platform given a minidump and process_state. |
| 34 // | 34 // |
| 35 // Author: Matthew Riley | 35 // Author: Matthew Riley |
| 36 | 36 |
| 37 #include "processor/exploitability_linux.h" | 37 #include "processor/exploitability_linux.h" |
| 38 | 38 |
| 39 #include "google_breakpad/processor/process_state.h" | 39 #include "google_breakpad/processor/process_state.h" |
| 40 #include "google_breakpad/processor/call_stack.h" | 40 #include "google_breakpad/processor/call_stack.h" |
| 41 #include "google_breakpad/processor/stack_frame.h" | 41 #include "google_breakpad/processor/stack_frame.h" |
| 42 #include "processor/logging.h" | |
| 42 | 43 |
| 43 namespace { | 44 namespace { |
| 44 | 45 |
| 45 // This function in libc is called if the program was compiled with | 46 // This function in libc is called if the program was compiled with |
| 46 // -fstack-protector and a function's stack canary changes. | 47 // -fstack-protector and a function's stack canary changes. |
| 47 const char kStackCheckFailureFunction[] = "__stack_chk_fail"; | 48 const char kStackCheckFailureFunction[] = "__stack_chk_fail"; |
| 48 | 49 |
| 49 // This function in libc is called if the program was compiled with | 50 // This function in libc is called if the program was compiled with |
| 50 // -D_FORTIFY_SOURCE=2, a function like strcpy() is called, and the runtime | 51 // -D_FORTIFY_SOURCE=2, a function like strcpy() is called, and the runtime |
| 51 // can determine that the call would overflow the target buffer. | 52 // can determine that the call would overflow the target buffer. |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 73 return EXPLOITABILITY_HIGH; | 74 return EXPLOITABILITY_HIGH; |
| 74 } | 75 } |
| 75 | 76 |
| 76 if (crashing_thread_frames[i]->function_name == | 77 if (crashing_thread_frames[i]->function_name == |
| 77 kBoundsCheckFailureFunction) { | 78 kBoundsCheckFailureFunction) { |
| 78 return EXPLOITABILITY_HIGH; | 79 return EXPLOITABILITY_HIGH; |
| 79 } | 80 } |
| 80 } | 81 } |
| 81 } | 82 } |
| 82 | 83 |
| 84 // Check if the instruction pointer is in a valid instruction region | |
| 85 // by finding if it maps to an executable part of memory | |
| 86 uint64_t instruction_ptr = 0; | |
| 87 | |
| 88 // get exception data (should exist for all minidumps) | |
| 89 MinidumpException *exception = dump_->GetException(); | |
| 90 if (exception == NULL) { | |
| 91 BPLOG(INFO) << "No exception record."; | |
| 92 return EXPLOITABILITY_ERR_PROCESSING; | |
| 93 } | |
| 94 const MinidumpContext *context = exception->GetContext(); | |
| 95 if (context == NULL) { | |
| 96 BPLOG(INFO) << "No exception context."; | |
| 97 return EXPLOITABILITY_ERR_PROCESSING; | |
| 98 } | |
| 99 | |
| 100 // get instruction pointer based off architecture | |
| 101 uint32_t architecture = context->GetContextCPU(); | |
| 102 switch (architecture) { | |
| 103 case MD_CONTEXT_X86: | |
| 104 instruction_ptr = context->GetContextX86()->eip; | |
| 105 break; | |
| 106 case MD_CONTEXT_AMD64: | |
| 107 instruction_ptr = context->GetContextAMD64()->rip; | |
| 108 break; | |
| 109 default: | |
| 110 // TODO(liuandrew) support ARM and arm64 architectures | |
|
ivanpe
2015/06/25 20:58:39
The style should be:
// TODO(liuandrew): Add supp
| |
| 111 BPLOG(INFO) << "Unsupported architecture."; | |
| 112 return EXPLOITABILITY_ERR_PROCESSING; | |
| 113 } | |
| 114 | |
| 115 if (!this->InstructionPointerInCode(instruction_ptr)) { | |
| 116 return EXPLOITABILITY_HIGH; | |
| 117 } | |
| 118 | |
| 83 return EXPLOITABILITY_NONE; | 119 return EXPLOITABILITY_NONE; |
| 84 } | 120 } |
| 85 | 121 |
| 122 bool ExploitabilityLinux::InstructionPointerInCode(uint64_t instruction_ptr) { | |
| 123 // get memory mapping | |
|
ivanpe
2015/06/25 20:58:38
same
| |
| 124 // most minidumps will not contain a memory mapping, so we will commonly | |
| 125 // resort to stack pointer approximation and checking modules | |
| 126 MinidumpMemoryInfoList *mem_info_list = dump_->GetMemoryInfoList(); | |
| 127 const MinidumpMemoryInfo *mem_info = | |
| 128 mem_info_list ? | |
| 129 mem_info_list->GetMemoryInfoForAddress(instruction_ptr) : NULL; | |
| 130 | |
| 131 // check if the memory mapping at the instruction pointer is executable | |
|
ivanpe
2015/06/25 20:58:38
same
| |
| 132 // if there is no memory mapping, we will use stack pointer approximation | |
| 133 // and the modules as reference | |
| 134 if (mem_info != NULL) { | |
| 135 return mem_info->IsExecutable(); | |
| 136 } | |
| 137 | |
| 138 // if the memory mapping retrieval fails, we will approximate check | |
|
ivanpe
2015/06/25 20:58:39
same
| |
| 139 // modules to see if the instruction pointer is inside a module | |
| 140 // TODO(liuandrew) the entirety of a module is not necessarily executable | |
|
ivanpe
2015/06/25 20:58:39
same:
TODO(liuandrew):
| |
| 141 // check if the instruction pointer lies in an executable region | |
| 142 MinidumpModuleList *minidump_module_list = dump_->GetModuleList(); | |
| 143 return !minidump_module_list || | |
| 144 minidump_module_list->GetModuleForAddress(instruction_ptr); | |
| 145 } | |
| 146 | |
| 86 } // namespace google_breakpad | 147 } // namespace google_breakpad |
| OLD | NEW |