1*9712c20fSFrederick Mayle // Copyright 2013 Google LLC
2*9712c20fSFrederick Mayle //
3*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without
4*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are
5*9712c20fSFrederick Mayle // met:
6*9712c20fSFrederick Mayle //
7*9712c20fSFrederick Mayle // * Redistributions of source code must retain the above copyright
8*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer.
9*9712c20fSFrederick Mayle // * Redistributions in binary form must reproduce the above
10*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer
11*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the
12*9712c20fSFrederick Mayle // distribution.
13*9712c20fSFrederick Mayle // * Neither the name of Google LLC nor the names of its
14*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from
15*9712c20fSFrederick Mayle // this software without specific prior written permission.
16*9712c20fSFrederick Mayle //
17*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*9712c20fSFrederick Mayle
29*9712c20fSFrederick Mayle // exploitability_linux.cc: Linux specific exploitability engine.
30*9712c20fSFrederick Mayle //
31*9712c20fSFrederick Mayle // Provides a guess at the exploitability of the crash for the Linux
32*9712c20fSFrederick Mayle // platform given a minidump and process_state.
33*9712c20fSFrederick Mayle //
34*9712c20fSFrederick Mayle // Author: Matthew Riley
35*9712c20fSFrederick Mayle
36*9712c20fSFrederick Mayle #ifdef HAVE_CONFIG_H
37*9712c20fSFrederick Mayle #include <config.h> // Must come first
38*9712c20fSFrederick Mayle #endif
39*9712c20fSFrederick Mayle
40*9712c20fSFrederick Mayle #include "processor/exploitability_linux.h"
41*9712c20fSFrederick Mayle
42*9712c20fSFrederick Mayle #include <string.h>
43*9712c20fSFrederick Mayle
44*9712c20fSFrederick Mayle #include "google_breakpad/common/minidump_exception_linux.h"
45*9712c20fSFrederick Mayle #include "google_breakpad/processor/call_stack.h"
46*9712c20fSFrederick Mayle #include "google_breakpad/processor/process_state.h"
47*9712c20fSFrederick Mayle #include "google_breakpad/processor/stack_frame.h"
48*9712c20fSFrederick Mayle #ifdef __linux__
49*9712c20fSFrederick Mayle #include "processor/disassembler_objdump.h"
50*9712c20fSFrederick Mayle #endif
51*9712c20fSFrederick Mayle #include "processor/logging.h"
52*9712c20fSFrederick Mayle
53*9712c20fSFrederick Mayle namespace {
54*9712c20fSFrederick Mayle
55*9712c20fSFrederick Mayle // Prefixes for memory mapping names.
56*9712c20fSFrederick Mayle constexpr char kHeapPrefix[] = "[heap";
57*9712c20fSFrederick Mayle constexpr char kStackPrefix[] = "[stack";
58*9712c20fSFrederick Mayle
59*9712c20fSFrederick Mayle // This function in libc is called if the program was compiled with
60*9712c20fSFrederick Mayle // -fstack-protector and a function's stack canary changes.
61*9712c20fSFrederick Mayle constexpr char kStackCheckFailureFunction[] = "__stack_chk_fail";
62*9712c20fSFrederick Mayle
63*9712c20fSFrederick Mayle // This function in libc is called if the program was compiled with
64*9712c20fSFrederick Mayle // -D_FORTIFY_SOURCE=2, a function like strcpy() is called, and the runtime
65*9712c20fSFrederick Mayle // can determine that the call would overflow the target buffer.
66*9712c20fSFrederick Mayle constexpr char kBoundsCheckFailureFunction[] = "__chk_fail";
67*9712c20fSFrederick Mayle
68*9712c20fSFrederick Mayle } // namespace
69*9712c20fSFrederick Mayle
70*9712c20fSFrederick Mayle namespace google_breakpad {
71*9712c20fSFrederick Mayle
ExploitabilityLinux(Minidump * dump,ProcessState * process_state)72*9712c20fSFrederick Mayle ExploitabilityLinux::ExploitabilityLinux(Minidump* dump,
73*9712c20fSFrederick Mayle ProcessState* process_state)
74*9712c20fSFrederick Mayle : Exploitability(dump, process_state),
75*9712c20fSFrederick Mayle enable_objdump_(false) { }
76*9712c20fSFrederick Mayle
ExploitabilityLinux(Minidump * dump,ProcessState * process_state,bool enable_objdump)77*9712c20fSFrederick Mayle ExploitabilityLinux::ExploitabilityLinux(Minidump* dump,
78*9712c20fSFrederick Mayle ProcessState* process_state,
79*9712c20fSFrederick Mayle bool enable_objdump)
80*9712c20fSFrederick Mayle : Exploitability(dump, process_state),
81*9712c20fSFrederick Mayle enable_objdump_(enable_objdump) { }
82*9712c20fSFrederick Mayle
83*9712c20fSFrederick Mayle
CheckPlatformExploitability()84*9712c20fSFrederick Mayle ExploitabilityRating ExploitabilityLinux::CheckPlatformExploitability() {
85*9712c20fSFrederick Mayle // Check the crashing thread for functions suggesting a buffer overflow or
86*9712c20fSFrederick Mayle // stack smash.
87*9712c20fSFrederick Mayle if (process_state_->requesting_thread() != -1) {
88*9712c20fSFrederick Mayle CallStack* crashing_thread =
89*9712c20fSFrederick Mayle process_state_->threads()->at(process_state_->requesting_thread());
90*9712c20fSFrederick Mayle const vector<StackFrame*>& crashing_thread_frames =
91*9712c20fSFrederick Mayle *crashing_thread->frames();
92*9712c20fSFrederick Mayle for (size_t i = 0; i < crashing_thread_frames.size(); ++i) {
93*9712c20fSFrederick Mayle if (crashing_thread_frames[i]->function_name ==
94*9712c20fSFrederick Mayle kStackCheckFailureFunction) {
95*9712c20fSFrederick Mayle return EXPLOITABILITY_HIGH;
96*9712c20fSFrederick Mayle }
97*9712c20fSFrederick Mayle
98*9712c20fSFrederick Mayle if (crashing_thread_frames[i]->function_name ==
99*9712c20fSFrederick Mayle kBoundsCheckFailureFunction) {
100*9712c20fSFrederick Mayle return EXPLOITABILITY_HIGH;
101*9712c20fSFrederick Mayle }
102*9712c20fSFrederick Mayle }
103*9712c20fSFrederick Mayle }
104*9712c20fSFrederick Mayle
105*9712c20fSFrederick Mayle // Getting exception data. (It should exist for all minidumps.)
106*9712c20fSFrederick Mayle MinidumpException* exception = dump_->GetException();
107*9712c20fSFrederick Mayle if (exception == NULL) {
108*9712c20fSFrederick Mayle BPLOG(INFO) << "No exception record.";
109*9712c20fSFrederick Mayle return EXPLOITABILITY_ERR_PROCESSING;
110*9712c20fSFrederick Mayle }
111*9712c20fSFrederick Mayle const MDRawExceptionStream* raw_exception_stream = exception->exception();
112*9712c20fSFrederick Mayle if (raw_exception_stream == NULL) {
113*9712c20fSFrederick Mayle BPLOG(INFO) << "No raw exception stream.";
114*9712c20fSFrederick Mayle return EXPLOITABILITY_ERR_PROCESSING;
115*9712c20fSFrederick Mayle }
116*9712c20fSFrederick Mayle
117*9712c20fSFrederick Mayle // Checking for benign exceptions that caused the crash.
118*9712c20fSFrederick Mayle if (this->BenignCrashTrigger(raw_exception_stream)) {
119*9712c20fSFrederick Mayle return EXPLOITABILITY_NONE;
120*9712c20fSFrederick Mayle }
121*9712c20fSFrederick Mayle
122*9712c20fSFrederick Mayle // Check if the instruction pointer is in a valid instruction region
123*9712c20fSFrederick Mayle // by finding if it maps to an executable part of memory.
124*9712c20fSFrederick Mayle uint64_t instruction_ptr = 0;
125*9712c20fSFrederick Mayle uint64_t stack_ptr = 0;
126*9712c20fSFrederick Mayle
127*9712c20fSFrederick Mayle const MinidumpContext* context = exception->GetContext();
128*9712c20fSFrederick Mayle if (context == NULL) {
129*9712c20fSFrederick Mayle BPLOG(INFO) << "No exception context.";
130*9712c20fSFrederick Mayle return EXPLOITABILITY_ERR_PROCESSING;
131*9712c20fSFrederick Mayle }
132*9712c20fSFrederick Mayle
133*9712c20fSFrederick Mayle // Getting the instruction pointer.
134*9712c20fSFrederick Mayle if (!context->GetInstructionPointer(&instruction_ptr)) {
135*9712c20fSFrederick Mayle BPLOG(INFO) << "Failed to retrieve instruction pointer.";
136*9712c20fSFrederick Mayle return EXPLOITABILITY_ERR_PROCESSING;
137*9712c20fSFrederick Mayle }
138*9712c20fSFrederick Mayle
139*9712c20fSFrederick Mayle // Getting the stack pointer.
140*9712c20fSFrederick Mayle if (!context->GetStackPointer(&stack_ptr)) {
141*9712c20fSFrederick Mayle BPLOG(INFO) << "Failed to retrieve stack pointer.";
142*9712c20fSFrederick Mayle return EXPLOITABILITY_ERR_PROCESSING;
143*9712c20fSFrederick Mayle }
144*9712c20fSFrederick Mayle
145*9712c20fSFrederick Mayle // Checking for the instruction pointer in a valid instruction region,
146*9712c20fSFrederick Mayle // a misplaced stack pointer, and an executable stack or heap.
147*9712c20fSFrederick Mayle if (!this->InstructionPointerInCode(instruction_ptr) ||
148*9712c20fSFrederick Mayle this->StackPointerOffStack(stack_ptr) ||
149*9712c20fSFrederick Mayle this->ExecutableStackOrHeap()) {
150*9712c20fSFrederick Mayle return EXPLOITABILITY_HIGH;
151*9712c20fSFrederick Mayle }
152*9712c20fSFrederick Mayle
153*9712c20fSFrederick Mayle // Check for write to read only memory or invalid memory, shelling out
154*9712c20fSFrederick Mayle // to objdump is enabled.
155*9712c20fSFrederick Mayle if (enable_objdump_ && this->EndedOnIllegalWrite(instruction_ptr)) {
156*9712c20fSFrederick Mayle return EXPLOITABILITY_HIGH;
157*9712c20fSFrederick Mayle }
158*9712c20fSFrederick Mayle
159*9712c20fSFrederick Mayle // There was no strong evidence suggesting exploitability, but the minidump
160*9712c20fSFrederick Mayle // does not appear totally benign either.
161*9712c20fSFrederick Mayle return EXPLOITABILITY_INTERESTING;
162*9712c20fSFrederick Mayle }
163*9712c20fSFrederick Mayle
EndedOnIllegalWrite(uint64_t instruction_ptr)164*9712c20fSFrederick Mayle bool ExploitabilityLinux::EndedOnIllegalWrite(uint64_t instruction_ptr) {
165*9712c20fSFrederick Mayle #ifndef __linux__
166*9712c20fSFrederick Mayle BPLOG(INFO) << "MinGW does not support fork and exec. Terminating method.";
167*9712c20fSFrederick Mayle return false;
168*9712c20fSFrederick Mayle #else
169*9712c20fSFrederick Mayle // Get memory region containing instruction pointer.
170*9712c20fSFrederick Mayle MinidumpMemoryList* memory_list = dump_->GetMemoryList();
171*9712c20fSFrederick Mayle MinidumpMemoryRegion* memory_region =
172*9712c20fSFrederick Mayle memory_list ?
173*9712c20fSFrederick Mayle memory_list->GetMemoryRegionForAddress(instruction_ptr) : NULL;
174*9712c20fSFrederick Mayle if (!memory_region) {
175*9712c20fSFrederick Mayle BPLOG(INFO) << "No memory region around instruction pointer.";
176*9712c20fSFrederick Mayle return false;
177*9712c20fSFrederick Mayle }
178*9712c20fSFrederick Mayle
179*9712c20fSFrederick Mayle // Get exception data to find architecture.
180*9712c20fSFrederick Mayle string architecture = "";
181*9712c20fSFrederick Mayle MinidumpException* exception = dump_->GetException();
182*9712c20fSFrederick Mayle // This should never evaluate to true, since this should not be reachable
183*9712c20fSFrederick Mayle // without checking for exception data earlier.
184*9712c20fSFrederick Mayle if (!exception) {
185*9712c20fSFrederick Mayle BPLOG(INFO) << "No exception data.";
186*9712c20fSFrederick Mayle return false;
187*9712c20fSFrederick Mayle }
188*9712c20fSFrederick Mayle const MDRawExceptionStream* raw_exception_stream = exception->exception();
189*9712c20fSFrederick Mayle const MinidumpContext* context = exception->GetContext();
190*9712c20fSFrederick Mayle // This should not evaluate to true, for the same reason mentioned above.
191*9712c20fSFrederick Mayle if (!raw_exception_stream || !context) {
192*9712c20fSFrederick Mayle BPLOG(INFO) << "No exception or architecture data.";
193*9712c20fSFrederick Mayle return false;
194*9712c20fSFrederick Mayle }
195*9712c20fSFrederick Mayle
196*9712c20fSFrederick Mayle DisassemblerObjdump disassembler(context->GetContextCPU(), memory_region,
197*9712c20fSFrederick Mayle instruction_ptr);
198*9712c20fSFrederick Mayle if (!disassembler.IsValid()) {
199*9712c20fSFrederick Mayle BPLOG(INFO) << "Disassembling fault instruction failed.";
200*9712c20fSFrederick Mayle return false;
201*9712c20fSFrederick Mayle }
202*9712c20fSFrederick Mayle
203*9712c20fSFrederick Mayle // Check if the operation is a write to memory.
204*9712c20fSFrederick Mayle // First, the instruction must one that can write to memory.
205*9712c20fSFrederick Mayle auto instruction = disassembler.operation();
206*9712c20fSFrederick Mayle if (!instruction.compare("mov") || !instruction.compare("inc") ||
207*9712c20fSFrederick Mayle !instruction.compare("dec") || !instruction.compare("and") ||
208*9712c20fSFrederick Mayle !instruction.compare("or") || !instruction.compare("xor") ||
209*9712c20fSFrederick Mayle !instruction.compare("not") || !instruction.compare("neg") ||
210*9712c20fSFrederick Mayle !instruction.compare("add") || !instruction.compare("sub") ||
211*9712c20fSFrederick Mayle !instruction.compare("shl") || !instruction.compare("shr")) {
212*9712c20fSFrederick Mayle uint64_t write_address = 0;
213*9712c20fSFrederick Mayle
214*9712c20fSFrederick Mayle // Check that the destination is a memory address. CalculateDestAddress will
215*9712c20fSFrederick Mayle // return false if the destination is not a memory address.
216*9712c20fSFrederick Mayle if (!disassembler.CalculateDestAddress(*context, write_address)) {
217*9712c20fSFrederick Mayle return false;
218*9712c20fSFrederick Mayle }
219*9712c20fSFrederick Mayle
220*9712c20fSFrederick Mayle // If the program crashed as a result of a write, the destination of
221*9712c20fSFrederick Mayle // the write must have been an address that did not permit writing.
222*9712c20fSFrederick Mayle // However, if the address is under 4k, due to program protections,
223*9712c20fSFrederick Mayle // the crash does not suggest exploitability for writes with such a
224*9712c20fSFrederick Mayle // low target address.
225*9712c20fSFrederick Mayle return write_address > 4096;
226*9712c20fSFrederick Mayle } else {
227*9712c20fSFrederick Mayle return false;
228*9712c20fSFrederick Mayle }
229*9712c20fSFrederick Mayle #endif // __linux__
230*9712c20fSFrederick Mayle }
231*9712c20fSFrederick Mayle
StackPointerOffStack(uint64_t stack_ptr)232*9712c20fSFrederick Mayle bool ExploitabilityLinux::StackPointerOffStack(uint64_t stack_ptr) {
233*9712c20fSFrederick Mayle MinidumpLinuxMapsList* linux_maps_list = dump_->GetLinuxMapsList();
234*9712c20fSFrederick Mayle // Inconclusive if there are no mappings available.
235*9712c20fSFrederick Mayle if (!linux_maps_list) {
236*9712c20fSFrederick Mayle return false;
237*9712c20fSFrederick Mayle }
238*9712c20fSFrederick Mayle const MinidumpLinuxMaps* linux_maps =
239*9712c20fSFrederick Mayle linux_maps_list->GetLinuxMapsForAddress(stack_ptr);
240*9712c20fSFrederick Mayle // Checks if the stack pointer maps to a valid mapping and if the mapping
241*9712c20fSFrederick Mayle // is not the stack. If the mapping has no name, it is inconclusive whether
242*9712c20fSFrederick Mayle // it is off the stack.
243*9712c20fSFrederick Mayle return !linux_maps || (linux_maps->GetPathname().compare("") &&
244*9712c20fSFrederick Mayle linux_maps->GetPathname().compare(
245*9712c20fSFrederick Mayle 0, strlen(kStackPrefix), kStackPrefix));
246*9712c20fSFrederick Mayle }
247*9712c20fSFrederick Mayle
ExecutableStackOrHeap()248*9712c20fSFrederick Mayle bool ExploitabilityLinux::ExecutableStackOrHeap() {
249*9712c20fSFrederick Mayle MinidumpLinuxMapsList* linux_maps_list = dump_->GetLinuxMapsList();
250*9712c20fSFrederick Mayle if (linux_maps_list) {
251*9712c20fSFrederick Mayle for (size_t i = 0; i < linux_maps_list->get_maps_count(); i++) {
252*9712c20fSFrederick Mayle const MinidumpLinuxMaps* linux_maps =
253*9712c20fSFrederick Mayle linux_maps_list->GetLinuxMapsAtIndex(i);
254*9712c20fSFrederick Mayle // Check for executable stack or heap for each mapping.
255*9712c20fSFrederick Mayle if (linux_maps && (!linux_maps->GetPathname().compare(
256*9712c20fSFrederick Mayle 0, strlen(kStackPrefix), kStackPrefix) ||
257*9712c20fSFrederick Mayle !linux_maps->GetPathname().compare(
258*9712c20fSFrederick Mayle 0, strlen(kHeapPrefix), kHeapPrefix)) &&
259*9712c20fSFrederick Mayle linux_maps->IsExecutable()) {
260*9712c20fSFrederick Mayle return true;
261*9712c20fSFrederick Mayle }
262*9712c20fSFrederick Mayle }
263*9712c20fSFrederick Mayle }
264*9712c20fSFrederick Mayle return false;
265*9712c20fSFrederick Mayle }
266*9712c20fSFrederick Mayle
InstructionPointerInCode(uint64_t instruction_ptr)267*9712c20fSFrederick Mayle bool ExploitabilityLinux::InstructionPointerInCode(uint64_t instruction_ptr) {
268*9712c20fSFrederick Mayle // Get Linux memory mapping from /proc/self/maps. Checking whether the
269*9712c20fSFrederick Mayle // region the instruction pointer is in has executable permission can tell
270*9712c20fSFrederick Mayle // whether it is in a valid code region. If there is no mapping for the
271*9712c20fSFrederick Mayle // instruction pointer, it is indicative that the instruction pointer is
272*9712c20fSFrederick Mayle // not within a module, which implies that it is outside a valid area.
273*9712c20fSFrederick Mayle MinidumpLinuxMapsList* linux_maps_list = dump_->GetLinuxMapsList();
274*9712c20fSFrederick Mayle const MinidumpLinuxMaps* linux_maps =
275*9712c20fSFrederick Mayle linux_maps_list ?
276*9712c20fSFrederick Mayle linux_maps_list->GetLinuxMapsForAddress(instruction_ptr) : NULL;
277*9712c20fSFrederick Mayle return linux_maps ? linux_maps->IsExecutable() : false;
278*9712c20fSFrederick Mayle }
279*9712c20fSFrederick Mayle
BenignCrashTrigger(const MDRawExceptionStream * raw_exception_stream)280*9712c20fSFrederick Mayle bool ExploitabilityLinux::BenignCrashTrigger(
281*9712c20fSFrederick Mayle const MDRawExceptionStream* raw_exception_stream) {
282*9712c20fSFrederick Mayle // Check the cause of crash.
283*9712c20fSFrederick Mayle // If the exception of the crash is a benign exception,
284*9712c20fSFrederick Mayle // it is probably not exploitable.
285*9712c20fSFrederick Mayle switch (raw_exception_stream->exception_record.exception_code) {
286*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGHUP:
287*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGINT:
288*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGQUIT:
289*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGTRAP:
290*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGABRT:
291*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGFPE:
292*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGKILL:
293*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGUSR1:
294*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGUSR2:
295*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGPIPE:
296*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGALRM:
297*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGTERM:
298*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGCHLD:
299*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGCONT:
300*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGSTOP:
301*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGTSTP:
302*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGTTIN:
303*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGTTOU:
304*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGURG:
305*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGXCPU:
306*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGXFSZ:
307*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGVTALRM:
308*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGPROF:
309*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGWINCH:
310*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGIO:
311*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGPWR:
312*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_SIGSYS:
313*9712c20fSFrederick Mayle case MD_EXCEPTION_CODE_LIN_DUMP_REQUESTED:
314*9712c20fSFrederick Mayle return true;
315*9712c20fSFrederick Mayle default:
316*9712c20fSFrederick Mayle return false;
317*9712c20fSFrederick Mayle }
318*9712c20fSFrederick Mayle }
319*9712c20fSFrederick Mayle
320*9712c20fSFrederick Mayle } // namespace google_breakpad
321