summaryrefslogtreecommitdiffstats
path: root/toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.cc
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.cc')
-rw-r--r--toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.cc625
1 files changed, 0 insertions, 625 deletions
diff --git a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.cc b/toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.cc
deleted file mode 100644
index 63056c438..000000000
--- a/toolkit/crashreporter/google-breakpad/src/processor/exploitability_linux.cc
+++ /dev/null
@@ -1,625 +0,0 @@
-// Copyright (c) 2013 Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// exploitability_linux.cc: Linux specific exploitability engine.
-//
-// Provides a guess at the exploitability of the crash for the Linux
-// platform given a minidump and process_state.
-//
-// Author: Matthew Riley
-
-#include "processor/exploitability_linux.h"
-
-#ifndef _WIN32
-#include <regex.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <sstream>
-#include <iterator>
-#endif // _WIN32
-
-#include "google_breakpad/common/minidump_exception_linux.h"
-#include "google_breakpad/processor/call_stack.h"
-#include "google_breakpad/processor/process_state.h"
-#include "google_breakpad/processor/stack_frame.h"
-#include "processor/logging.h"
-
-namespace {
-
-// Prefixes for memory mapping names.
-constexpr char kHeapPrefix[] = "[heap";
-constexpr char kStackPrefix[] = "[stack";
-
-// This function in libc is called if the program was compiled with
-// -fstack-protector and a function's stack canary changes.
-constexpr char kStackCheckFailureFunction[] = "__stack_chk_fail";
-
-// This function in libc is called if the program was compiled with
-// -D_FORTIFY_SOURCE=2, a function like strcpy() is called, and the runtime
-// can determine that the call would overflow the target buffer.
-constexpr char kBoundsCheckFailureFunction[] = "__chk_fail";
-
-#ifndef _WIN32
-const unsigned int MAX_INSTRUCTION_LEN = 15;
-const unsigned int MAX_OBJDUMP_BUFFER_LEN = 4096;
-#endif // _WIN32
-
-} // namespace
-
-namespace google_breakpad {
-
-ExploitabilityLinux::ExploitabilityLinux(Minidump *dump,
- ProcessState *process_state)
- : Exploitability(dump, process_state),
- enable_objdump_(false) { }
-
-ExploitabilityLinux::ExploitabilityLinux(Minidump *dump,
- ProcessState *process_state,
- bool enable_objdump)
- : Exploitability(dump, process_state),
- enable_objdump_(enable_objdump) { }
-
-
-ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() {
- // Check the crashing thread for functions suggesting a buffer overflow or
- // stack smash.
- if (process_state_->requesting_thread() != -1) {
- CallStack* crashing_thread =
- process_state_->threads()->at(process_state_->requesting_thread());
- const vector<StackFrame*>& crashing_thread_frames =
- *crashing_thread->frames();
- for (size_t i = 0; i < crashing_thread_frames.size(); ++i) {
- if (crashing_thread_frames[i]->function_name ==
- kStackCheckFailureFunction) {
- return EXPLOITABILITY_HIGH;
- }
-
- if (crashing_thread_frames[i]->function_name ==
- kBoundsCheckFailureFunction) {
- return EXPLOITABILITY_HIGH;
- }
- }
- }
-
- // 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 MDRawExceptionStream *raw_exception_stream = exception->exception();
- if (raw_exception_stream == NULL) {
- BPLOG(INFO) << "No raw exception stream.";
- return EXPLOITABILITY_ERR_PROCESSING;
- }
-
- // Checking for benign exceptions that caused the crash.
- if (this->BenignCrashTrigger(raw_exception_stream)) {
- return EXPLOITABILITY_NONE;
- }
-
- // 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) {
- BPLOG(INFO) << "No exception context.";
- return EXPLOITABILITY_ERR_PROCESSING;
- }
-
- // Getting the instruction pointer.
- if (!context->GetInstructionPointer(&instruction_ptr)) {
- BPLOG(INFO) << "Failed to retrieve instruction pointer.";
- 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,
- // a misplaced stack pointer, and an executable stack or heap.
- if (!this->InstructionPointerInCode(instruction_ptr) ||
- this->StackPointerOffStack(stack_ptr) ||
- this->ExecutableStackOrHeap()) {
- return EXPLOITABILITY_HIGH;
- }
-
- // Check for write to read only memory or invalid memory, shelling out
- // to objdump is enabled.
- if (enable_objdump_ && this->EndedOnIllegalWrite(instruction_ptr)) {
- return EXPLOITABILITY_HIGH;
- }
-
- // There was no strong evidence suggesting exploitability, but the minidump
- // does not appear totally benign either.
- return EXPLOITABILITY_INTERESTING;
-}
-
-bool ExploitabilityLinux::EndedOnIllegalWrite(uint64_t instruction_ptr) {
-#ifdef _WIN32
- BPLOG(INFO) << "MinGW does not support fork and exec. Terminating method.";
-#else
- // Get memory region containing instruction pointer.
- MinidumpMemoryList *memory_list = dump_->GetMemoryList();
- MinidumpMemoryRegion *memory_region =
- memory_list ?
- memory_list->GetMemoryRegionForAddress(instruction_ptr) : NULL;
- if (!memory_region) {
- BPLOG(INFO) << "No memory region around instruction pointer.";
- return false;
- }
-
- // Get exception data to find architecture.
- string architecture = "";
- MinidumpException *exception = dump_->GetException();
- // This should never evaluate to true, since this should not be reachable
- // without checking for exception data earlier.
- if (!exception) {
- BPLOG(INFO) << "No exception data.";
- return false;
- }
- const MDRawExceptionStream *raw_exception_stream = exception->exception();
- const MinidumpContext *context = exception->GetContext();
- // This should not evaluate to true, for the same reason mentioned above.
- if (!raw_exception_stream || !context) {
- BPLOG(INFO) << "No exception or architecture data.";
- return false;
- }
- // Check architecture and set architecture variable to corresponding flag
- // in objdump.
- switch (context->GetContextCPU()) {
- case MD_CONTEXT_X86:
- architecture = "i386";
- break;
- case MD_CONTEXT_AMD64:
- architecture = "i386:x86-64";
- break;
- default:
- // Unsupported architecture. Note that ARM architectures are not
- // supported because objdump does not support ARM.
- return false;
- break;
- }
-
- // Get memory region around instruction pointer and the number of bytes
- // before and after the instruction pointer in the memory region.
- const uint8_t *raw_memory = memory_region->GetMemory();
- const uint64_t base = memory_region->GetBase();
- if (base > instruction_ptr) {
- BPLOG(ERROR) << "Memory region base value exceeds instruction pointer.";
- return false;
- }
- const uint64_t offset = instruction_ptr - base;
- if (memory_region->GetSize() < MAX_INSTRUCTION_LEN + offset) {
- BPLOG(INFO) << "Not enough bytes left to guarantee complete instruction.";
- return false;
- }
-
- // Convert bytes into objdump output.
- char objdump_output_buffer[MAX_OBJDUMP_BUFFER_LEN] = {0};
- DisassembleBytes(architecture,
- raw_memory + offset,
- MAX_OBJDUMP_BUFFER_LEN,
- objdump_output_buffer);
-
- string line;
- if (!GetObjdumpInstructionLine(objdump_output_buffer, &line)) {
- return false;
- }
-
- // Convert objdump instruction line into the operation and operands.
- string instruction = "";
- string dest = "";
- string src = "";
- TokenizeObjdumpInstruction(line, &instruction, &dest, &src);
-
- // Check if the operation is a write to memory. First, the instruction
- // must one that can write to memory. Second, the write destination
- // must be a spot in memory rather than a register. Since there are no
- // symbols from objdump, the destination will be enclosed by brackets.
- if (dest.size() > 2 && dest.at(0) == '[' && dest.at(dest.size() - 1) == ']' &&
- (!instruction.compare("mov") || !instruction.compare("inc") ||
- !instruction.compare("dec") || !instruction.compare("and") ||
- !instruction.compare("or") || !instruction.compare("xor") ||
- !instruction.compare("not") || !instruction.compare("neg") ||
- !instruction.compare("add") || !instruction.compare("sub") ||
- !instruction.compare("shl") || !instruction.compare("shr"))) {
- // Strip away enclosing brackets from the destination address.
- dest = dest.substr(1, dest.size() - 2);
- uint64_t write_address = 0;
- CalculateAddress(dest, *context, &write_address);
-
- // If the program crashed as a result of a write, the destination of
- // the write must have been an address that did not permit writing.
- // However, if the address is under 4k, due to program protections,
- // the crash does not suggest exploitability for writes with such a
- // low target address.
- return write_address > 4096;
- }
-#endif // _WIN32
- return false;
-}
-
-#ifndef _WIN32
-bool ExploitabilityLinux::CalculateAddress(const string &address_expression,
- const DumpContext &context,
- uint64_t *write_address) {
- // The destination should be the format reg+a or reg-a, where reg
- // is a register and a is a hexadecimal constant. Although more complex
- // expressions can make valid instructions, objdump's disassembly outputs
- // it in this simpler format.
- // TODO(liuandrew): Handle more complex formats, should they arise.
-
- if (!write_address) {
- BPLOG(ERROR) << "Null parameter.";
- return false;
- }
-
- // Clone parameter into a non-const string.
- string expression = address_expression;
-
- // Parse out the constant that is added to the address (if it exists).
- size_t delim = expression.find('+');
- bool positive_add_constant = true;
- // Check if constant is subtracted instead of added.
- if (delim == string::npos) {
- positive_add_constant = false;
- delim = expression.find('-');
- }
- uint32_t add_constant = 0;
- // Save constant and remove it from the expression.
- if (delim != string::npos) {
- if (!sscanf(expression.substr(delim + 1).c_str(), "%x", &add_constant)) {
- BPLOG(ERROR) << "Failed to scan constant.";
- return false;
- }
- expression = expression.substr(0, delim);
- }
-
- // Set the the write address to the corresponding register.
- // TODO(liuandrew): Add support for partial registers, such as
- // the rax/eax/ax/ah/al chain.
- switch (context.GetContextCPU()) {
- case MD_CONTEXT_X86:
- if (!expression.compare("eax")) {
- *write_address = context.GetContextX86()->eax;
- } else if (!expression.compare("ebx")) {
- *write_address = context.GetContextX86()->ebx;
- } else if (!expression.compare("ecx")) {
- *write_address = context.GetContextX86()->ecx;
- } else if (!expression.compare("edx")) {
- *write_address = context.GetContextX86()->edx;
- } else if (!expression.compare("edi")) {
- *write_address = context.GetContextX86()->edi;
- } else if (!expression.compare("esi")) {
- *write_address = context.GetContextX86()->esi;
- } else if (!expression.compare("ebp")) {
- *write_address = context.GetContextX86()->ebp;
- } else if (!expression.compare("esp")) {
- *write_address = context.GetContextX86()->esp;
- } else if (!expression.compare("eip")) {
- *write_address = context.GetContextX86()->eip;
- } else {
- BPLOG(ERROR) << "Unsupported register";
- return false;
- }
- break;
- case MD_CONTEXT_AMD64:
- if (!expression.compare("rax")) {
- *write_address = context.GetContextAMD64()->rax;
- } else if (!expression.compare("rbx")) {
- *write_address = context.GetContextAMD64()->rbx;
- } else if (!expression.compare("rcx")) {
- *write_address = context.GetContextAMD64()->rcx;
- } else if (!expression.compare("rdx")) {
- *write_address = context.GetContextAMD64()->rdx;
- } else if (!expression.compare("rdi")) {
- *write_address = context.GetContextAMD64()->rdi;
- } else if (!expression.compare("rsi")) {
- *write_address = context.GetContextAMD64()->rsi;
- } else if (!expression.compare("rbp")) {
- *write_address = context.GetContextAMD64()->rbp;
- } else if (!expression.compare("rsp")) {
- *write_address = context.GetContextAMD64()->rsp;
- } else if (!expression.compare("rip")) {
- *write_address = context.GetContextAMD64()->rip;
- } else if (!expression.compare("r8")) {
- *write_address = context.GetContextAMD64()->r8;
- } else if (!expression.compare("r9")) {
- *write_address = context.GetContextAMD64()->r9;
- } else if (!expression.compare("r10")) {
- *write_address = context.GetContextAMD64()->r10;
- } else if (!expression.compare("r11")) {
- *write_address = context.GetContextAMD64()->r11;
- } else if (!expression.compare("r12")) {
- *write_address = context.GetContextAMD64()->r12;
- } else if (!expression.compare("r13")) {
- *write_address = context.GetContextAMD64()->r13;
- } else if (!expression.compare("r14")) {
- *write_address = context.GetContextAMD64()->r14;
- } else if (!expression.compare("r15")) {
- *write_address = context.GetContextAMD64()->r15;
- } else {
- BPLOG(ERROR) << "Unsupported register";
- return false;
- }
- break;
- default:
- // This should not occur since the same switch condition
- // should have terminated this method.
- return false;
- break;
- }
-
- // Add or subtract constant from write address (if applicable).
- *write_address =
- positive_add_constant ?
- *write_address + add_constant : *write_address - add_constant;
-
- return true;
-}
-
-// static
-bool ExploitabilityLinux::GetObjdumpInstructionLine(
- const char *objdump_output_buffer,
- string *instruction_line) {
- // Put buffer data into stream to output line-by-line.
- std::stringstream objdump_stream;
- objdump_stream.str(string(objdump_output_buffer));
-
- // Pipe each output line into the string until the string contains the first
- // instruction from objdump. All lines before the "<.data>:" section are
- // skipped. Loop until the line shows the first instruction or there are no
- // lines left.
- bool data_section_seen = false;
- do {
- if (!getline(objdump_stream, *instruction_line)) {
- BPLOG(INFO) << "Objdump instructions not found";
- return false;
- }
- if (instruction_line->find("<.data>:") != string::npos) {
- data_section_seen = true;
- }
- } while (!data_section_seen || instruction_line->find("0:") == string::npos);
- // This first instruction contains the above substring.
-
- return true;
-}
-
-bool ExploitabilityLinux::TokenizeObjdumpInstruction(const string &line,
- string *operation,
- string *dest,
- string *src) {
- if (!operation || !dest || !src) {
- BPLOG(ERROR) << "Null parameters passed.";
- return false;
- }
-
- // Set all pointer values to empty strings.
- *operation = "";
- *dest = "";
- *src = "";
-
- // Tokenize the objdump line.
- vector<string> tokens;
- std::istringstream line_stream(line);
- copy(std::istream_iterator<string>(line_stream),
- std::istream_iterator<string>(),
- std::back_inserter(tokens));
-
- // Regex for the data in hex form. Each byte is two hex digits.
- regex_t regex;
- regcomp(&regex, "^[[:xdigit:]]{2}$", REG_EXTENDED | REG_NOSUB);
-
- // Find and set the location of the operator. The operator appears
- // directly after the chain of bytes that define the instruction. The
- // operands will be the last token, given that the instruction has operands.
- // If not, the operator is the last token. The loop skips the first token
- // because the first token is the instruction number (namely "0:").
- string operands = "";
- for (size_t i = 1; i < tokens.size(); i++) {
- // Check if current token no longer is in byte format.
- if (regexec(&regex, tokens[i].c_str(), 0, NULL, 0)) {
- // instruction = tokens[i];
- *operation = tokens[i];
- // If the operator is the last token, there are no operands.
- if (i != tokens.size() - 1) {
- operands = tokens[tokens.size() - 1];
- }
- break;
- }
- }
- regfree(&regex);
-
- if (operation->empty()) {
- BPLOG(ERROR) << "Failed to parse out operation from objdump instruction.";
- return false;
- }
-
- // Split operands into source and destination (if applicable).
- if (!operands.empty()) {
- size_t delim = operands.find(',');
- if (delim == string::npos) {
- *dest = operands;
- } else {
- *dest = operands.substr(0, delim);
- *src = operands.substr(delim + 1);
- }
- }
- return true;
-}
-
-bool ExploitabilityLinux::DisassembleBytes(const string &architecture,
- const uint8_t *raw_bytes,
- const unsigned int buffer_len,
- char *objdump_output_buffer) {
- if (!raw_bytes || !objdump_output_buffer) {
- BPLOG(ERROR) << "Bad input parameters.";
- return false;
- }
-
- // Write raw bytes around instruction pointer to a temporary file to
- // pass as an argument to objdump.
- char raw_bytes_tmpfile[] = "/tmp/breakpad_mem_region-raw_bytes-XXXXXX";
- int raw_bytes_fd = mkstemp(raw_bytes_tmpfile);
- if (raw_bytes_fd < 0) {
- BPLOG(ERROR) << "Failed to create tempfile.";
- unlink(raw_bytes_tmpfile);
- return false;
- }
- if (write(raw_bytes_fd, raw_bytes, MAX_INSTRUCTION_LEN)
- != MAX_INSTRUCTION_LEN) {
- BPLOG(ERROR) << "Writing of raw bytes failed.";
- unlink(raw_bytes_tmpfile);
- return false;
- }
-
- char cmd[1024] = {0};
- snprintf(cmd,
- 1024,
- "objdump -D -b binary -M intel -m %s %s",
- architecture.c_str(),
- raw_bytes_tmpfile);
- FILE *objdump_fp = popen(cmd, "r");
- if (!objdump_fp) {
- fclose(objdump_fp);
- unlink(raw_bytes_tmpfile);
- BPLOG(ERROR) << "Failed to call objdump.";
- return false;
- }
- if (fread(objdump_output_buffer, 1, buffer_len, objdump_fp) <= 0) {
- fclose(objdump_fp);
- unlink(raw_bytes_tmpfile);
- BPLOG(ERROR) << "Failed to read objdump output.";
- return false;
- }
- fclose(objdump_fp);
- unlink(raw_bytes_tmpfile);
- return true;
-}
-#endif // _WIN32
-
-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(
- 0, strlen(kStackPrefix), kStackPrefix));
-}
-
-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(
- 0, strlen(kStackPrefix), kStackPrefix) ||
- !linux_maps->GetPathname().compare(
- 0, strlen(kHeapPrefix), kHeapPrefix)) &&
- 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
- // whether it is in a valid code region. If there is no mapping for the
- // instruction pointer, it is indicative that the instruction pointer is
- // not within a module, which implies that it is outside a valid area.
- MinidumpLinuxMapsList *linux_maps_list = dump_->GetLinuxMapsList();
- const MinidumpLinuxMaps *linux_maps =
- linux_maps_list ?
- linux_maps_list->GetLinuxMapsForAddress(instruction_ptr) : NULL;
- return linux_maps ? linux_maps->IsExecutable() : false;
-}
-
-bool ExploitabilityLinux::BenignCrashTrigger(const MDRawExceptionStream
- *raw_exception_stream) {
- // Check the cause of crash.
- // If the exception of the crash is a benign exception,
- // it is probably not exploitable.
- switch (raw_exception_stream->exception_record.exception_code) {
- case MD_EXCEPTION_CODE_LIN_SIGHUP:
- case MD_EXCEPTION_CODE_LIN_SIGINT:
- case MD_EXCEPTION_CODE_LIN_SIGQUIT:
- case MD_EXCEPTION_CODE_LIN_SIGTRAP:
- case MD_EXCEPTION_CODE_LIN_SIGABRT:
- case MD_EXCEPTION_CODE_LIN_SIGFPE:
- case MD_EXCEPTION_CODE_LIN_SIGKILL:
- case MD_EXCEPTION_CODE_LIN_SIGUSR1:
- case MD_EXCEPTION_CODE_LIN_SIGUSR2:
- case MD_EXCEPTION_CODE_LIN_SIGPIPE:
- case MD_EXCEPTION_CODE_LIN_SIGALRM:
- case MD_EXCEPTION_CODE_LIN_SIGTERM:
- case MD_EXCEPTION_CODE_LIN_SIGCHLD:
- case MD_EXCEPTION_CODE_LIN_SIGCONT:
- case MD_EXCEPTION_CODE_LIN_SIGSTOP:
- case MD_EXCEPTION_CODE_LIN_SIGTSTP:
- case MD_EXCEPTION_CODE_LIN_SIGTTIN:
- case MD_EXCEPTION_CODE_LIN_SIGTTOU:
- case MD_EXCEPTION_CODE_LIN_SIGURG:
- case MD_EXCEPTION_CODE_LIN_SIGXCPU:
- case MD_EXCEPTION_CODE_LIN_SIGXFSZ:
- case MD_EXCEPTION_CODE_LIN_SIGVTALRM:
- case MD_EXCEPTION_CODE_LIN_SIGPROF:
- case MD_EXCEPTION_CODE_LIN_SIGWINCH:
- case MD_EXCEPTION_CODE_LIN_SIGIO:
- case MD_EXCEPTION_CODE_LIN_SIGPWR:
- case MD_EXCEPTION_CODE_LIN_SIGSYS:
- case MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED:
- return true;
- break;
- default:
- return false;
- break;
- }
-}
-
-} // namespace google_breakpad