1 // Copyright 2010 Google LLC
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 // * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 // * Neither the name of Google LLC nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 #ifdef HAVE_CONFIG_H
30 #include <config.h> // Must come first
31 #endif
32
33 #include <stdlib.h>
34 #include <unistd.h>
35
36 #include <type_traits>
37 #include <string>
38
39 #include "breakpad_googletest_includes.h"
40 #include "common/using_std_string.h"
41 #include "google_breakpad/processor/basic_source_line_resolver.h"
42 #include "google_breakpad/processor/minidump_processor.h"
43 #include "google_breakpad/processor/process_state.h"
44 #ifdef __linux__
45 #include "processor/exploitability_linux.h"
46 #endif // __linux__
47 #include "processor/simple_symbol_supplier.h"
48
49 #ifdef __linux__
50 namespace google_breakpad {
51 class ExploitabilityLinuxTestMinidumpContext : public MinidumpContext {
52 public:
ExploitabilityLinuxTestMinidumpContext(const MDRawContextAMD64 & context)53 explicit ExploitabilityLinuxTestMinidumpContext(
54 const MDRawContextAMD64& context) : MinidumpContext(NULL) {
55 valid_ = true;
56 SetContextAMD64(new MDRawContextAMD64(context));
57 SetContextFlags(MD_CONTEXT_AMD64);
58 }
59 };
60
61 } // namespace google_breakpad
62 #endif // __linux__
63
64 namespace {
65
66 using google_breakpad::BasicSourceLineResolver;
67 #ifdef __linux__
68 using google_breakpad::ExploitabilityLinuxTestMinidumpContext;
69 #endif // __linux__
70 using google_breakpad::MinidumpProcessor;
71 using google_breakpad::ProcessState;
72 using google_breakpad::SimpleSymbolSupplier;
73
TestDataDir()74 string TestDataDir() {
75 return string(getenv("srcdir") ? getenv("srcdir") : ".") +
76 "/src/processor/testdata";
77 }
78
79 // Find the given dump file in <srcdir>/src/processor/testdata, process it,
80 // and get the exploitability rating. Returns EXPLOITABILITY_ERR_PROCESSING
81 // if the crash dump can't be processed.
82 google_breakpad::ExploitabilityRating
ExploitabilityFor(const string & filename)83 ExploitabilityFor(const string& filename) {
84 SimpleSymbolSupplier supplier(TestDataDir() + "/symbols");
85 BasicSourceLineResolver resolver;
86 MinidumpProcessor processor(&supplier, &resolver, true);
87 processor.set_enable_objdump_for_exploitability(true);
88 ProcessState state;
89
90 string minidump_file = TestDataDir() + "/" + filename;
91
92 if (processor.Process(minidump_file, &state) !=
93 google_breakpad::PROCESS_OK) {
94 return google_breakpad::EXPLOITABILITY_ERR_PROCESSING;
95 }
96
97 return state.exploitability();
98 }
99
TEST(ExploitabilityTest,TestWindowsEngine)100 TEST(ExploitabilityTest, TestWindowsEngine) {
101 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
102 ExploitabilityFor("ascii_read_av.dmp"));
103 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
104 ExploitabilityFor("ascii_read_av_block_write.dmp"));
105 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
106 ExploitabilityFor("ascii_read_av_clobber_write.dmp"));
107 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
108 ExploitabilityFor("ascii_read_av_conditional.dmp"));
109 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
110 ExploitabilityFor("ascii_read_av_then_jmp.dmp"));
111 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
112 ExploitabilityFor("ascii_read_av_xchg_write.dmp"));
113 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
114 ExploitabilityFor("ascii_write_av.dmp"));
115 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
116 ExploitabilityFor("ascii_write_av_arg_to_call.dmp"));
117 ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE,
118 ExploitabilityFor("null_read_av.dmp"));
119 ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE,
120 ExploitabilityFor("null_write_av.dmp"));
121 ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE,
122 ExploitabilityFor("stack_exhaustion.dmp"));
123 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
124 ExploitabilityFor("exec_av_on_stack.dmp"));
125 ASSERT_EQ(google_breakpad::EXPLOITABILITY_MEDIUM,
126 ExploitabilityFor("write_av_non_null.dmp"));
127 ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW,
128 ExploitabilityFor("read_av_non_null.dmp"));
129 ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW,
130 ExploitabilityFor("read_av_clobber_write.dmp"));
131 ASSERT_EQ(google_breakpad::EXPLOITABILITY_LOW,
132 ExploitabilityFor("read_av_conditional.dmp"));
133 }
134
TEST(ExploitabilityTest,TestLinuxEngine)135 TEST(ExploitabilityTest, TestLinuxEngine) {
136 ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING,
137 ExploitabilityFor("linux_null_read_av.dmp"));
138 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
139 ExploitabilityFor("linux_overflow.dmp"));
140 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
141 ExploitabilityFor("linux_stacksmash.dmp"));
142 ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE,
143 ExploitabilityFor("linux_divide_by_zero.dmp"));
144 ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING,
145 ExploitabilityFor("linux_null_dereference.dmp"));
146 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
147 ExploitabilityFor("linux_jmp_to_0.dmp"));
148 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
149 ExploitabilityFor("linux_outside_module.dmp"));
150 ASSERT_EQ(google_breakpad::EXPLOITABILITY_NONE,
151 ExploitabilityFor("linux_raise_sigabrt.dmp"));
152 ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING,
153 ExploitabilityFor("linux_inside_module_exe_region1.dmp"));
154 ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING,
155 ExploitabilityFor("linux_inside_module_exe_region2.dmp"));
156 ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING,
157 ExploitabilityFor("linux_stack_pointer_in_stack.dmp"));
158 ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING,
159 ExploitabilityFor("linux_stack_pointer_in_stack_alt_name.dmp"));
160 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
161 ExploitabilityFor("linux_stack_pointer_in_module.dmp"));
162 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
163 ExploitabilityFor("linux_executable_stack.dmp"));
164 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
165 ExploitabilityFor("linux_executable_heap.dmp"));
166 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
167 ExploitabilityFor("linux_jmp_to_module_not_exe_region.dmp"));
168 #ifdef __linux__
169 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
170 ExploitabilityFor("linux_write_to_nonwritable_module.dmp"));
171 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
172 ExploitabilityFor("linux_write_to_nonwritable_region_math.dmp"));
173 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
174 ExploitabilityFor("linux_write_to_outside_module.dmp"));
175 ASSERT_EQ(google_breakpad::EXPLOITABILITY_HIGH,
176 ExploitabilityFor("linux_write_to_outside_module_via_math.dmp"));
177 ASSERT_EQ(google_breakpad::EXPLOITABILITY_INTERESTING,
178 ExploitabilityFor("linux_write_to_under_4k.dmp"));
179 #endif // __linux__
180 }
181
182 } // namespace
183