1 : // Copyright 2013 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "base/environment.h"
16 : #include "base/files/file_enumerator.h"
17 : #include "base/files/file_path.h"
18 : #include "base/process/kill.h"
19 : #include "base/strings/string_util.h"
20 : #include "base/strings/stringprintf.h"
21 : #include "base/strings/utf_string_conversions.h"
22 : #include "base/win/pe_image.h"
23 : #include "base/win/scoped_com_initializer.h"
24 : #include "gmock/gmock.h"
25 : #include "gtest/gtest.h"
26 : #include "pcrecpp.h" // NOLINT
27 : #include "syzygy/agent/asan/asan_rtl_impl.h"
28 : #include "syzygy/agent/asan/asan_runtime.h"
29 : #include "syzygy/block_graph/transforms/chained_basic_block_transforms.h"
30 : #include "syzygy/common/asan_parameters.h"
31 : #include "syzygy/common/indexed_frequency_data.h"
32 : #include "syzygy/common/unittest_util.h"
33 : #include "syzygy/core/disassembler_util.h"
34 : #include "syzygy/core/unittest_util.h"
35 : #include "syzygy/grinder/basic_block_util.h"
36 : #include "syzygy/grinder/grinder.h"
37 : #include "syzygy/grinder/grinders/coverage_grinder.h"
38 : #include "syzygy/grinder/grinders/indexed_frequency_data_grinder.h"
39 : #include "syzygy/grinder/grinders/profile_grinder.h"
40 : #include "syzygy/instrument/instrument_app.h"
41 : #include "syzygy/instrument/transforms/asan_transform.h"
42 : #include "syzygy/integration_tests/asan_page_protection_tests.h"
43 : #include "syzygy/integration_tests/integration_tests_dll.h"
44 : #include "syzygy/pe/decomposer.h"
45 : #include "syzygy/pe/pe_transform_policy.h"
46 : #include "syzygy/pe/unittest_util.h"
47 : #include "syzygy/trace/agent_logger/agent_logger.h"
48 : #include "syzygy/trace/common/unittest_util.h"
49 :
50 : namespace integration_tests {
51 :
52 : namespace {
53 :
54 : // The exit code used by report_crash_with_protobuf_harness if the
55 : // exception was appropriately dispatched but did not contain a valid protobuf.
56 : const int kExeReportCrashWithProtobufExitCodeBadProtobuf = 97;
57 :
58 : // The exit code used by report_crash_with_protobuf_harness if the
59 : // exception was appropriately dispatched and contained a valid protobuf.
60 : const int kExeReportCrashWithProtobufExitCode = 98;
61 :
62 : // The exit code used by crash_for_exception_harness if the exception
63 : // was appropriately dispatched.
64 : const int kExeCrashForExceptionExitCode = 99;
65 :
66 : using grinder::basic_block_util::IndexedFrequencyInformation;
67 : using grinder::basic_block_util::IndexedFrequencyMap;
68 : using grinder::basic_block_util::ModuleIndexedFrequencyMap;
69 : using instrument::InstrumentApp;
70 : using trace::parser::Parser;
71 : typedef block_graph::BlockGraph::Block Block;
72 : typedef block_graph::BlockGraph::BlockMap BlockMap;
73 : typedef application::Application<InstrumentApp> TestApp;
74 : typedef grinder::CoverageData::LineExecutionCountMap LineExecutionCountMap;
75 : typedef grinder::CoverageData::SourceFileCoverageData SourceFileCoverageData;
76 : typedef grinder::CoverageData::SourceFileCoverageDataMap
77 : SourceFileCoverageDataMap;
78 :
79 : #define _STRINGIFY(s) #s
80 : #define STRINGIFY(s) _STRINGIFY(s)
81 :
82 : const char kAsanAccessViolationLog[] =
83 : "SyzyASAN: Caught an invalid access via an access violation exception.";
84 : const char kAsanHandlingException[] = "SyzyASAN: Handling an exception.";
85 : const char kAsanHeapBufferOverflow[] = "SyzyASAN error: heap-buffer-overflow ";
86 : const char kAsanCorruptHeap[] = "SyzyASAN error: corrupt-heap ";
87 : const char kAsanHeapUseAfterFree[] = "SyzyASAN error: heap-use-after-free ";
88 :
89 : // A convenience class for controlling an out of process agent_logger instance,
90 : // and getting the contents of its log file. Not thread safe.
91 : struct ScopedAgentLogger {
92 E : explicit ScopedAgentLogger(base::FilePath temp_dir)
93 : : handle_(NULL), nul_(NULL), temp_dir_(temp_dir) {
94 : agent_logger_ = testing::GetOutputRelativePath(
95 E : L"agent_logger.exe");
96 E : instance_id_ = base::StringPrintf("integra%08X", ::GetCurrentProcessId());
97 E : }
98 :
99 E : ~ScopedAgentLogger() {
100 : // Clean up the temp directory if we created one.
101 E : if (!temp_dir_.empty())
102 E : base::DeleteFile(temp_dir_, true);
103 :
104 E : if (nul_) {
105 E : ::CloseHandle(nul_);
106 E : nul_ = NULL;
107 : }
108 E : }
109 :
110 E : void RunAction(const char* action, base::ProcessHandle* handle) {
111 E : DCHECK_NE(reinterpret_cast<const char*>(NULL), action);
112 E : DCHECK_NE(reinterpret_cast<base::ProcessHandle*>(NULL), handle);
113 :
114 E : CommandLine cmd_line(agent_logger_);
115 E : cmd_line.AppendSwitchASCII("instance-id", instance_id_);
116 E : cmd_line.AppendSwitchPath("minidump-dir", temp_dir_);
117 E : cmd_line.AppendSwitchPath("output-file", log_file_);
118 E : cmd_line.AppendArg(action);
119 E : base::LaunchOptions options;
120 E : options.stderr_handle = nul_;
121 E : options.stdin_handle = nul_;
122 E : options.stdout_handle = nul_;
123 E : CHECK(base::LaunchProcess(cmd_line, options, handle));
124 E : }
125 :
126 E : void Start() {
127 E : DCHECK(!handle_);
128 :
129 E : if (nul_ == NULL) {
130 : nul_ = CreateFile(L"NUL", GENERIC_READ | GENERIC_WRITE, 0, NULL,
131 E : OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
132 E : CHECK(nul_);
133 : }
134 :
135 E : log_file_ = temp_dir_.Append(L"integration_test.log");
136 :
137 E : std::wstring start_event_name(L"syzygy-logger-started-");
138 E : start_event_name += base::ASCIIToWide(instance_id_);
139 : base::win::ScopedHandle start_event(
140 E : ::CreateEvent(NULL, FALSE, FALSE, start_event_name.c_str()));
141 :
142 E : RunAction("start", &handle_);
143 :
144 E : ::WaitForSingleObject(start_event.Get(), INFINITE);
145 E : }
146 :
147 E : void Stop() {
148 E : DCHECK(handle_);
149 :
150 E : base::ProcessHandle handle = NULL;
151 E : RunAction("stop", &handle);
152 E : int exit_code = 0;
153 E : CHECK(base::WaitForExitCode(handle, &exit_code));
154 E : CHECK(base::WaitForExitCode(handle_, &exit_code));
155 E : handle_ = NULL;
156 :
157 : // Read the contents of the log file.
158 E : if (base::PathExists(log_file_))
159 E : CHECK(base::ReadFileToString(log_file_, &log_contents_));
160 E : }
161 :
162 E : void GetLog(std::string* log) {
163 E : DCHECK_NE(static_cast<std::string*>(nullptr), log);
164 E : *log = log_contents_;
165 E : }
166 :
167 : // Initialized at construction.
168 : base::FilePath agent_logger_;
169 : std::string instance_id_;
170 :
171 : // Modified by Start and Stop.
172 : base::FilePath temp_dir_;
173 : base::FilePath log_file_;
174 : base::ProcessHandle handle_;
175 : HANDLE nul_;
176 :
177 : // Modified by Stop.
178 : std::string log_contents_;
179 : };
180 :
181 : typedef void (WINAPI *AsanSetCallBack)(AsanErrorCallBack);
182 :
183 : enum AccessMode {
184 : ASAN_READ_ACCESS = agent::asan::ASAN_READ_ACCESS,
185 : ASAN_WRITE_ACCESS = agent::asan::ASAN_WRITE_ACCESS,
186 : ASAN_UNKNOWN_ACCESS = agent::asan::ASAN_UNKNOWN_ACCESS,
187 : };
188 :
189 : enum BadAccessKind {
190 : UNKNOWN_BAD_ACCESS = agent::asan::UNKNOWN_BAD_ACCESS,
191 : USE_AFTER_FREE = agent::asan::USE_AFTER_FREE,
192 : HEAP_BUFFER_OVERFLOW = agent::asan::HEAP_BUFFER_OVERFLOW,
193 : HEAP_BUFFER_UNDERFLOW = agent::asan::HEAP_BUFFER_UNDERFLOW,
194 : CORRUPT_BLOCK = agent::asan::CORRUPT_BLOCK,
195 : CORRUPT_HEAP = agent::asan::CORRUPT_HEAP,
196 : };
197 :
198 : // Contains the number of Asan errors reported with our callback.
199 : int asan_error_count;
200 : // Contains the last Asan error reported.
201 : agent::asan::AsanErrorInfo last_asan_error;
202 :
203 E : void AsanCallback(agent::asan::AsanErrorInfo* info) {
204 E : asan_error_count++;
205 E : last_asan_error = *info;
206 : // We want to prevent write errors from corrupting the underlying block hence
207 : // we stop the flow of execution by raising an exception. The faulty calls are
208 : // themselves wrapped in try/catch statements, and continue executing
209 : // afterwards. Thus, they clean up after themselves.
210 : //
211 : // In the case of block corruption we elect to allow the code to continue
212 : // executing so that the normal code path is taken. If we raise an exception
213 : // this actually prevents the AsanHeap cleanup code from continuing, and we
214 : // leak memory.
215 E : if (info->error_type != CORRUPT_BLOCK)
216 E : ::RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, NULL);
217 E : }
218 :
219 E : void ResetAsanErrors() {
220 E : asan_error_count = 0;
221 E : }
222 :
223 E : void SetAsanDefaultCallBack(AsanErrorCallBack callback) {
224 E : HMODULE asan_module = GetModuleHandle(L"syzyasan_rtl.dll");
225 E : DCHECK(asan_module != NULL);
226 : AsanSetCallBack set_callback = reinterpret_cast<AsanSetCallBack>(
227 E : ::GetProcAddress(asan_module, "asan_SetCallBack"));
228 E : DCHECK(set_callback != NULL);
229 :
230 E : set_callback(callback);
231 E : }
232 :
233 E : agent::asan::AsanRuntime* GetActiveAsanRuntime() {
234 E : HMODULE asan_module = GetModuleHandle(L"syzyasan_rtl.dll");
235 E : DCHECK(asan_module != NULL);
236 :
237 : typedef agent::asan::AsanRuntime* (WINAPI *AsanGetActiveRuntimePtr)();
238 : AsanGetActiveRuntimePtr asan_get_active_runtime =
239 : reinterpret_cast<AsanGetActiveRuntimePtr>(
240 E : ::GetProcAddress(asan_module, "asan_GetActiveRuntime"));
241 : DCHECK_NE(reinterpret_cast<AsanGetActiveRuntimePtr>(NULL),
242 E : asan_get_active_runtime);
243 :
244 E : return (*asan_get_active_runtime)();
245 E : }
246 :
247 : // Filters non-continuable exceptions in the given module.
248 : int FilterExceptionsInModule(HMODULE module,
249 : unsigned int code,
250 i : struct _EXCEPTION_POINTERS* ep) {
251 : // Do a basic sanity check on the input parameters.
252 : if (module == NULL ||
253 : code != EXCEPTION_NONCONTINUABLE_EXCEPTION ||
254 : ep == NULL ||
255 : ep->ContextRecord == NULL ||
256 i : ep->ExceptionRecord == NULL) {
257 i : return EXCEPTION_CONTINUE_SEARCH;
258 : }
259 :
260 : // Get the module extents in memory.
261 i : base::win::PEImage image(module);
262 i : uint8* module_start = reinterpret_cast<uint8*>(module);
263 : uint8* module_end = module_start +
264 i : image.GetNTHeaders()->OptionalHeader.SizeOfImage;
265 :
266 : // Filter exceptions where the return address originates from within the
267 : // instrumented module.
268 i : uint8** ebp = reinterpret_cast<uint8**>(ep->ContextRecord->Ebp);
269 i : uint8* ret = ebp[1];
270 i : if (ret >= module_start && ret < module_end)
271 i : return EXCEPTION_EXECUTE_HANDLER;
272 :
273 i : return EXCEPTION_CONTINUE_SEARCH;
274 i : }
275 :
276 : class TestingProfileGrinder : public grinder::grinders::ProfileGrinder {
277 : public:
278 : // Expose for testing.
279 : typedef grinder::grinders::ProfileGrinder::InvocationNodeMap
280 : InvocationNodeMap;
281 : typedef grinder::grinders::ProfileGrinder::ModuleInformationSet
282 : ModuleInformationSet;
283 :
284 : using grinder::grinders::ProfileGrinder::PartData;
285 : using grinder::grinders::ProfileGrinder::PartDataMap;
286 : using grinder::grinders::ProfileGrinder::PartKey;
287 :
288 : using grinder::grinders::ProfileGrinder::modules_;
289 : using grinder::grinders::ProfileGrinder::parts_;
290 : };
291 :
292 : class InstrumentAppIntegrationTest : public testing::PELibUnitTest {
293 : public:
294 : typedef testing::PELibUnitTest Super;
295 :
296 : InstrumentAppIntegrationTest()
297 : : cmd_line_(base::FilePath(L"instrument.exe")),
298 : test_impl_(test_app_.implementation()),
299 : image_layout_(&block_graph_),
300 E : get_my_rva_(NULL) {
301 E : }
302 :
303 E : void SetUp() {
304 E : Super::SetUp();
305 :
306 : // Several of the tests generate progress and (deliberate) error messages
307 : // that would otherwise clutter the unittest output.
308 E : logging::SetMinLogLevel(logging::LOG_FATAL);
309 :
310 : // Setup the IO streams.
311 E : this->CreateTemporaryDir(&temp_dir_);
312 E : stdin_path_ = temp_dir_.Append(L"NUL");
313 E : stdout_path_ = temp_dir_.Append(L"stdout.txt");
314 E : stderr_path_ = temp_dir_.Append(L"stderr.txt");
315 E : InitStreams(stdin_path_, stdout_path_, stderr_path_);
316 :
317 : // Initialize the (potential) input and output path values.
318 : base::FilePath abs_input_dll_path_ =
319 E : testing::GetExeRelativePath(testing::kIntegrationTestsDllName);
320 E : input_dll_path_ = testing::GetRelativePath(abs_input_dll_path_);
321 E : output_dll_path_ = temp_dir_.Append(input_dll_path_.BaseName());
322 :
323 : // Initialize call_service output directory for produced trace files.
324 E : traces_dir_ = temp_dir_.Append(L"traces");
325 :
326 : // Initialize call_service session id.
327 E : service_.SetEnvironment();
328 :
329 E : ASSERT_NO_FATAL_FAILURE(ConfigureTestApp(&test_app_));
330 E : }
331 :
332 E : void TearDown() {
333 : // We need to release the module handle before Super::TearDown, otherwise
334 : // the library file cannot be deleted.
335 E : module_.Release();
336 E : Super::TearDown();
337 E : }
338 :
339 : // Points the application at the fixture's command-line and IO streams.
340 : template<typename TestAppType>
341 E : void ConfigureTestApp(TestAppType* test_app) {
342 E : test_app->set_command_line(&cmd_line_);
343 E : test_app->set_in(in());
344 E : test_app->set_out(out());
345 E : test_app->set_err(err());
346 E : }
347 :
348 E : void StartService() {
349 E : service_.Start(traces_dir_);
350 E : }
351 :
352 E : void StopService() {
353 E : service_.Stop();
354 E : }
355 :
356 E : void UnloadDll() {
357 E : module_.Reset(NULL);
358 E : }
359 :
360 : // Runs an instrumentation pass in the given mode and validates that the
361 : // resulting output DLL loads.
362 E : void EndToEndTest(const std::string& mode) {
363 E : cmd_line_.AppendSwitchPath("input-image", input_dll_path_);
364 E : cmd_line_.AppendSwitchPath("output-image", output_dll_path_);
365 E : cmd_line_.AppendSwitchASCII("mode", mode);
366 :
367 : // Create the instrumented DLL.
368 E : application::Application<instrument::InstrumentApp> app;
369 E : ASSERT_NO_FATAL_FAILURE(ConfigureTestApp(&app));
370 E : ASSERT_EQ(0, app.Run());
371 :
372 : // Validate that the test dll loads post instrumentation.
373 E : ASSERT_NO_FATAL_FAILURE(LoadTestDll(output_dll_path_, &module_));
374 E : }
375 :
376 : // Invoke a test function inside test_dll by addressing it with a test id.
377 : // Returns the value resulting of test function execution.
378 E : unsigned int InvokeTestDllFunction(testing::EndToEndTestId test) {
379 : // Load the exported 'function_name' function.
380 : typedef unsigned int (CALLBACK* TestDllFuncs)(unsigned int);
381 : TestDllFuncs func = reinterpret_cast<TestDllFuncs>(
382 E : ::GetProcAddress(module_, "EndToEndTest"));
383 E : DCHECK(func != NULL);
384 :
385 : // Invoke it, and returns its value.
386 E : return func(test);
387 E : }
388 :
389 : int RunOutOfProcessFunction(const base::string16& harness_name,
390 : testing::EndToEndTestId test,
391 E : bool expect_exception) {
392 E : base::FilePath harness = testing::GetExeRelativePath(harness_name.c_str());
393 E : CommandLine cmd_line(harness);
394 E : cmd_line.AppendSwitchASCII("test", base::StringPrintf("%d", test));
395 E : cmd_line.AppendSwitchPath("dll", output_dll_path_);
396 E : if (expect_exception)
397 E : cmd_line.AppendSwitch("expect-exception");
398 :
399 E : base::LaunchOptions options;
400 : base::ProcessHandle handle;
401 E : EXPECT_TRUE(base::LaunchProcess(cmd_line, options, &handle));
402 :
403 E : int exit_code = 0;
404 E : EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code));
405 E : return exit_code;
406 E : }
407 :
408 : // Runs an asan error check in an external process, invoking the test via the
409 : // integration test harness.
410 : void OutOfProcessAsanErrorCheck(testing::EndToEndTestId test,
411 : bool expect_exception,
412 E : std::string* log) {
413 E : DCHECK_NE(static_cast<std::string*>(nullptr), log);
414 E : ScopedAgentLogger logger(temp_dir_);
415 E : logger.Start();
416 :
417 E : scoped_ptr<base::Environment> env(base::Environment::Create());
418 E : CHECK_NE(static_cast<base::Environment*>(nullptr), env.get());
419 :
420 : // Update the instance ID environment variable to specifically aim the
421 : // Asan RTL to the agent logger we are running. We have to be careful not
422 : // to influence other RPC settings so as not to break coverage support.
423 E : base::FilePath agent = testing::GetExeRelativePath(L"syzyasan_rtl.dll");
424 E : std::string instance_id = base::WideToUTF8(agent.value());
425 E : instance_id.append(",");
426 E : instance_id.append(logger.instance_id_);
427 E : bool had_instance_id = false;
428 E : std::string orig_instance_id;
429 : had_instance_id = env->GetVar(kSyzygyRpcInstanceIdEnvVar,
430 E : &orig_instance_id);
431 E : if (had_instance_id) {
432 E : instance_id.append(";");
433 E : instance_id.append(orig_instance_id);
434 : }
435 E : env->SetVar(kSyzygyRpcInstanceIdEnvVar, instance_id);
436 :
437 : int exit_code = RunOutOfProcessFunction(L"integration_tests_harness.exe",
438 E : test, expect_exception);
439 E : EXPECT_EQ(0, exit_code);
440 E : logger.Stop();
441 :
442 : // Restore the instance ID variable to its original state.
443 E : if (had_instance_id) {
444 E : env->SetVar(kSyzygyRpcInstanceIdEnvVar, orig_instance_id);
445 E : } else {
446 i : env->UnSetVar(kSyzygyRpcInstanceIdEnvVar);
447 : }
448 :
449 E : logger.GetLog(log);
450 E : }
451 :
452 : void OutOfProcessAsanErrorCheckAndValidateLog(
453 : testing::EndToEndTestId test,
454 : bool expect_exception,
455 : const base::StringPiece& log_message_1,
456 E : const base::StringPiece& log_message_2) {
457 E : std::string log;
458 E : OutOfProcessAsanErrorCheck(test, expect_exception, &log);
459 :
460 E : if (!expect_exception)
461 E : return;
462 : // Check the log for any messages that are expected.
463 E : if (!log_message_1.empty()) {
464 E : EXPECT_NE(std::string::npos, log.find(log_message_1.as_string()))
465 : << "Expected to find '" << log_message_1 << "' in logs: " << log;
466 : }
467 E : if (!log_message_2.empty()) {
468 E : EXPECT_NE(std::string::npos, log.find(log_message_2.as_string()))
469 : << "Expected to find '" << log_message_2 << "' in logs: " << log;
470 : }
471 E : }
472 :
473 E : void EndToEndCheckTestDll() {
474 : // Validate that behavior is unchanged after instrumentation.
475 E : EXPECT_EQ(0xfff80200, InvokeTestDllFunction(testing::kArrayComputation1));
476 E : EXPECT_EQ(0x00000200, InvokeTestDllFunction(testing::kArrayComputation2));
477 E : }
478 :
479 : bool AsanErrorCheck(testing::EndToEndTestId test,
480 : BadAccessKind kind,
481 : AccessMode mode,
482 : size_t size,
483 : size_t max_tries,
484 E : bool unload) {
485 E : ResetAsanErrors();
486 E : EXPECT_NO_FATAL_FAILURE(SetAsanDefaultCallBack(AsanCallback));
487 :
488 E : for (size_t i = 0; i < max_tries; ++i) {
489 E : InvokeTestDllFunction(test);
490 E : if (unload)
491 E : UnloadDll();
492 :
493 : // If this appears to have failed then retry it for all but the last
494 : // attempt. Some tests have a non-zero chance of failure, but their
495 : // chances of failing repeatedly are infinitesimally small.
496 E : if (asan_error_count == 0 && i + 1 < max_tries)
497 i : continue;
498 :
499 : if (asan_error_count == 0 ||
500 : last_asan_error.error_type != kind ||
501 : last_asan_error.access_mode != mode ||
502 E : last_asan_error.access_size != size) {
503 E : return false;
504 : }
505 E : break;
506 i : }
507 E : return true;
508 E : }
509 :
510 : bool FilteredAsanErrorCheck(testing::EndToEndTestId test,
511 : BadAccessKind kind,
512 : AccessMode mode,
513 : size_t size,
514 : size_t max_tries,
515 i : bool unload) {
516 i : __try {
517 i : return AsanErrorCheck(test, kind, mode, size, max_tries, unload);
518 i : } __except (FilterExceptionsInModule(module_, // NOLINT
519 : GetExceptionCode(),
520 i : GetExceptionInformation())) {
521 : // If the exception is of the expected type and originates from the
522 : // instrumented module, then we indicate that no Asan error was
523 : // detected.
524 i : return false;
525 i : }
526 i : }
527 :
528 E : void AsanErrorCheckTestDll() {
529 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead8BufferOverflow,
530 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
531 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead16BufferOverflow,
532 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 2, 1, false));
533 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead32BufferOverflow,
534 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 4, 1, false));
535 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead64BufferOverflow,
536 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 8, 1, false));
537 :
538 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead8BufferUnderflow,
539 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
540 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead16BufferUnderflow,
541 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 2, 1, false));
542 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead32BufferUnderflow,
543 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 4, 1, false));
544 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead64BufferUnderflow,
545 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 8, 1, false));
546 :
547 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite8BufferOverflow,
548 : HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
549 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite16BufferOverflow,
550 : HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 2, 1, false));
551 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite32BufferOverflow,
552 : HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 4, 1, false));
553 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite64BufferOverflow,
554 : HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 8, 1, false));
555 :
556 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite8BufferUnderflow,
557 : HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
558 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite16BufferUnderflow,
559 : HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 2, 1, false));
560 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite32BufferUnderflow,
561 : HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 4, 1, false));
562 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite64BufferUnderflow,
563 : HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 8, 1, false));
564 :
565 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead8UseAfterFree,
566 : USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
567 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead16UseAfterFree,
568 : USE_AFTER_FREE, ASAN_READ_ACCESS, 2, 1, false));
569 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead32UseAfterFree,
570 : USE_AFTER_FREE, ASAN_READ_ACCESS, 4, 1, false));
571 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanRead64UseAfterFree,
572 : USE_AFTER_FREE, ASAN_READ_ACCESS, 8, 1, false));
573 :
574 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite8UseAfterFree,
575 : USE_AFTER_FREE, ASAN_WRITE_ACCESS, 1, 1, false));
576 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite16UseAfterFree,
577 : USE_AFTER_FREE, ASAN_WRITE_ACCESS, 2, 1, false));
578 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite32UseAfterFree,
579 : USE_AFTER_FREE, ASAN_WRITE_ACCESS, 4, 1, false));
580 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWrite64UseAfterFree,
581 : USE_AFTER_FREE, ASAN_WRITE_ACCESS, 8, 1, false));
582 E : }
583 :
584 E : void AsanErrorCheckSampledAllocations() {
585 : // This assumes we have a 50% allocation sampling rate.
586 :
587 : // Run Asan tests over and over again until we've done enough of them. We
588 : // only check the read operations as the writes may actually cause
589 : // corruption if not caught.
590 E : size_t good = 0;
591 E : size_t test = 0;
592 E : while (test < 1000) {
593 : good += FilteredAsanErrorCheck(testing::kAsanRead8BufferOverflow,
594 E : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false) ? 1 : 0;
595 : good += FilteredAsanErrorCheck(testing::kAsanRead16BufferOverflow,
596 E : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 2, 1, false) ? 1 : 0;
597 : good += FilteredAsanErrorCheck(testing::kAsanRead32BufferOverflow,
598 E : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 4, 1, false) ? 1 : 0;
599 : good += FilteredAsanErrorCheck(testing::kAsanRead64BufferOverflow,
600 E : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 8, 1, false) ? 1 : 0;
601 E : test += 4;
602 :
603 : good += FilteredAsanErrorCheck(testing::kAsanRead8BufferUnderflow,
604 E : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false) ? 1 : 0;
605 : good += FilteredAsanErrorCheck(testing::kAsanRead16BufferUnderflow,
606 E : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 2, 1, false) ? 1 : 0;
607 : good += FilteredAsanErrorCheck(testing::kAsanRead32BufferUnderflow,
608 E : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 4, 1, false) ? 1 : 0;
609 : good += FilteredAsanErrorCheck(testing::kAsanRead64BufferUnderflow,
610 E : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 8, 1, false) ? 1 : 0;
611 E : test += 4;
612 E : }
613 :
614 : // We expect half of the bugs to have been found, as the allocations are
615 : // subsampled. With 1000 allocations this gives us 10 nines of confidence
616 : // that the detection rate will be within 50 +/- 10%.
617 E : EXPECT_LE(4 * test / 10, good);
618 E : EXPECT_GE(6 * test / 10, good);
619 E : }
620 :
621 E : void AsanErrorCheckInterceptedFunctions() {
622 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemsetOverflow,
623 : HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
624 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemsetUnderflow,
625 : HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
626 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemsetUseAfterFree,
627 : USE_AFTER_FREE, ASAN_WRITE_ACCESS, 1, 1, false));
628 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemchrOverflow,
629 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
630 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemchrUnderflow,
631 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
632 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemchrUseAfterFree,
633 : USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
634 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemmoveReadOverflow,
635 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
636 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemmoveReadUnderflow,
637 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
638 : // In this test both buffers passed to memmove have been freed, but as the
639 : // interceptor starts by checking the source buffer this use after free is
640 : // seen as an invalid read access.
641 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemmoveUseAfterFree,
642 : USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
643 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemmoveWriteOverflow,
644 : HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
645 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemmoveWriteUnderflow,
646 : HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
647 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemcpyReadOverflow,
648 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
649 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemcpyReadUnderflow,
650 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
651 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemcpyUseAfterFree,
652 : USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
653 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemcpyWriteOverflow,
654 : HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
655 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanMemcpyWriteUnderflow,
656 : HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
657 :
658 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrlenOverflow,
659 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
660 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrlenUnderflow,
661 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
662 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrlenUseAfterFree,
663 : USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
664 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrrchrOverflow,
665 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
666 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrrchrUnderflow,
667 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
668 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrrchrUseAfterFree,
669 : USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
670 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcsrchrOverflow,
671 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
672 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcsrchrUnderflow,
673 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
674 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcsrchrUseAfterFree,
675 : USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
676 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcschrOverflow,
677 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
678 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcschrUnderflow,
679 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
680 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcschrUseAfterFree,
681 : USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
682 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWcsstrKeysOverflow,
683 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
684 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncpySrcOverflow,
685 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
686 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncpySrcUnderflow,
687 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
688 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncpySrcUseAfterFree,
689 : USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
690 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncpyDstOverflow,
691 : HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
692 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncpyDstUnderflow,
693 : HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
694 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncpyDstUseAfterFree,
695 : USE_AFTER_FREE, ASAN_WRITE_ACCESS, 1, 1, false));
696 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncatSuffixOverflow,
697 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
698 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncatSuffixUnderflow,
699 : HEAP_BUFFER_UNDERFLOW, ASAN_READ_ACCESS, 1, 1, false));
700 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncatSuffixUseAfterFree,
701 : USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
702 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncatDstOverflow,
703 : HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
704 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncatDstUnderflow,
705 : HEAP_BUFFER_UNDERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
706 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanStrncatDstUseAfterFree,
707 : USE_AFTER_FREE, ASAN_WRITE_ACCESS, 1, 1, false));
708 :
709 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanReadFileOverflow,
710 : HEAP_BUFFER_OVERFLOW, ASAN_WRITE_ACCESS, 1, 1, false));
711 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanReadFileUseAfterFree,
712 : USE_AFTER_FREE, ASAN_WRITE_ACCESS, 1, 1, false));
713 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWriteFileOverflow,
714 : HEAP_BUFFER_OVERFLOW, ASAN_READ_ACCESS, 1, 1, false));
715 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanWriteFileUseAfterFree,
716 : USE_AFTER_FREE, ASAN_READ_ACCESS, 1, 1, false));
717 :
718 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanCorruptBlock,
719 : CORRUPT_BLOCK, ASAN_UNKNOWN_ACCESS, 0, 10, false));
720 :
721 : // We need to force the module to unload so that the quarantine gets
722 : // cleaned up and fires off the error we're looking for.
723 E : EXPECT_TRUE(AsanErrorCheck(testing::kAsanCorruptBlockInQuarantine,
724 : CORRUPT_BLOCK, ASAN_UNKNOWN_ACCESS, 0, 10, true));
725 :
726 : OutOfProcessAsanErrorCheckAndValidateLog(
727 : testing::kAsanMemcmpAccessViolation, true, kAsanHandlingException,
728 E : nullptr);
729 E : }
730 :
731 E : void AsanLargeBlockHeapTests(bool expect_exception) {
732 : OutOfProcessAsanErrorCheckAndValidateLog(
733 : testing::kAsanReadLargeAllocationTrailerBeforeFree, expect_exception,
734 E : kAsanAccessViolationLog, kAsanHeapBufferOverflow);
735 : OutOfProcessAsanErrorCheckAndValidateLog(
736 : testing::kAsanReadLargeAllocationBodyAfterFree, true,
737 E : kAsanAccessViolationLog, kAsanHeapUseAfterFree);
738 E : }
739 :
740 : void AsanZebraHeapTest(bool enabled);
741 :
742 E : void BBEntryInvokeTestDll() {
743 E : EXPECT_EQ(42, InvokeTestDllFunction(testing::kBBEntryCallOnce));
744 E : EXPECT_EQ(42, InvokeTestDllFunction(testing::kBBEntryCallTree));
745 E : EXPECT_EQ(42, InvokeTestDllFunction(testing::kBBEntryCallRecursive));
746 E : }
747 :
748 E : void ProfileInvokeTestDll() {
749 E : EXPECT_EQ(5, InvokeTestDllFunction(testing::kProfileCallExport));
750 : // Save the RVA of one of the invoked functions for testing later.
751 E : get_my_rva_ = InvokeTestDllFunction(testing::kProfileGetMyRVA);
752 :
753 : // The profiler will record the address of the first instruction of the
754 : // original function, which is six bytes past the start of the function
755 : // as seen by itself post-instrumentation.
756 E : get_my_rva_ += 6;
757 E : }
758 :
759 : uint32 ProfileInvokeGetRVA() {
760 : return InvokeTestDllFunction(testing::kProfileGetMyRVA);
761 : }
762 :
763 E : void QueueTraces(Parser* parser) {
764 E : DCHECK(parser != NULL);
765 :
766 : // Queue up the trace file(s) we engendered.
767 : base::FileEnumerator enumerator(traces_dir_,
768 : false,
769 E : base::FileEnumerator::FILES);
770 E : while (true) {
771 E : base::FilePath trace_file = enumerator.Next();
772 E : if (trace_file.empty())
773 E : break;
774 E : ASSERT_TRUE(parser->OpenTraceFile(trace_file));
775 E : }
776 E : }
777 :
778 E : const Block* FindBlockWithName(std::string name) {
779 E : const BlockMap& blocks = block_graph_.blocks();
780 E : BlockMap::const_iterator block_iter = blocks.begin();
781 E : for (; block_iter != blocks.end(); ++block_iter) {
782 E : const Block& block = block_iter->second;
783 E : if (block.type() != block_graph::BlockGraph::CODE_BLOCK)
784 E : continue;
785 E : if (block.name().compare(name) == 0)
786 E : return █
787 E : }
788 i : return NULL;
789 E : }
790 :
791 : int GetBlockFrequency(const IndexedFrequencyMap& frequencies,
792 E : const Block* block) {
793 E : DCHECK(block != NULL);
794 : IndexedFrequencyMap::const_iterator entry =
795 E : frequencies.find(std::make_pair(block->addr(), 0));
796 E : if (entry == frequencies.end())
797 i : return 0;
798 E : return entry->second;
799 E : }
800 :
801 : void ExpectFunctionFrequency(const IndexedFrequencyMap& frequencies,
802 : const char* function_name,
803 E : int expected_frequency) {
804 E : DCHECK(function_name != NULL);
805 E : const Block* block = FindBlockWithName(function_name);
806 E : ASSERT_TRUE(block != NULL);
807 E : int exec_frequency = GetBlockFrequency(frequencies, block);
808 E : EXPECT_EQ(expected_frequency, exec_frequency);
809 E : }
810 :
811 E : void DecomposeImage() {
812 : // Decompose the DLL.
813 E : pe_image_.Init(input_dll_path_);
814 E : pe::Decomposer decomposer(pe_image_);
815 E : ASSERT_TRUE(decomposer.Decompose(&image_layout_));
816 E : }
817 :
818 E : void BBEntryCheckTestDll() {
819 E : Parser parser;
820 E : grinder::grinders::IndexedFrequencyDataGrinder grinder;
821 :
822 : // Initialize trace parser.
823 E : ASSERT_TRUE(parser.Init(&grinder));
824 E : grinder.SetParser(&parser);
825 :
826 : // Add generated traces to the parser.
827 E : QueueTraces(&parser);
828 :
829 : // Parse all traces.
830 E : ASSERT_TRUE(parser.Consume());
831 E : ASSERT_FALSE(parser.error_occurred());
832 E : ASSERT_TRUE(grinder.Grind());
833 :
834 : // Retrieve basic block count information.
835 : const ModuleIndexedFrequencyMap& module_entry_count =
836 E : grinder.frequency_data_map();
837 E : ASSERT_EQ(1u, module_entry_count.size());
838 :
839 : ModuleIndexedFrequencyMap::const_iterator entry_iter =
840 E : module_entry_count.begin();
841 E : const IndexedFrequencyInformation& info = entry_iter->second;
842 E : const IndexedFrequencyMap& entry_count = info.frequency_map;
843 :
844 : // Decompose the output image.
845 E : ASSERT_NO_FATAL_FAILURE(DecomposeImage());
846 :
847 : // Validate function entry counts.
848 E : ASSERT_NO_FATAL_FAILURE(
849 : ExpectFunctionFrequency(entry_count, "BBEntryCallOnce", 1));
850 E : ASSERT_NO_FATAL_FAILURE(
851 : ExpectFunctionFrequency(entry_count, "BBEntryCallTree", 1));
852 E : ASSERT_NO_FATAL_FAILURE(
853 : ExpectFunctionFrequency(entry_count, "BBEntryFunction1", 4));
854 E : ASSERT_NO_FATAL_FAILURE(
855 : ExpectFunctionFrequency(entry_count, "BBEntryFunction2", 2));
856 E : ASSERT_NO_FATAL_FAILURE(
857 : ExpectFunctionFrequency(entry_count, "BBEntryFunction3", 1));
858 E : ASSERT_NO_FATAL_FAILURE(
859 : ExpectFunctionFrequency(entry_count, "BBEntryCallRecursive", 1));
860 E : ASSERT_NO_FATAL_FAILURE(
861 : ExpectFunctionFrequency(entry_count, "BBEntryFunctionRecursive", 42));
862 E : }
863 :
864 E : void BranchCheckTestDll() {
865 E : Parser parser;
866 E : grinder::grinders::IndexedFrequencyDataGrinder grinder;
867 :
868 : // Initialize trace parser.
869 E : ASSERT_TRUE(parser.Init(&grinder));
870 E : grinder.SetParser(&parser);
871 :
872 : // Add generated traces to the parser.
873 E : QueueTraces(&parser);
874 :
875 : // Parse all traces.
876 E : ASSERT_TRUE(parser.Consume());
877 E : ASSERT_FALSE(parser.error_occurred());
878 E : ASSERT_TRUE(grinder.Grind());
879 :
880 : // Retrieve basic block count information.
881 : const grinder::basic_block_util::ModuleIndexedFrequencyMap& module_map =
882 E : grinder.frequency_data_map();
883 E : ASSERT_EQ(1u, module_map.size());
884 :
885 E : ModuleIndexedFrequencyMap::const_iterator entry_iter = module_map.begin();
886 E : const IndexedFrequencyInformation& information = entry_iter->second;
887 E : const IndexedFrequencyMap& frequency_map = information.frequency_map;
888 :
889 : // Decompose the output image.
890 E : ASSERT_NO_FATAL_FAILURE(DecomposeImage());
891 :
892 : // Validate function entry counts.
893 E : ASSERT_NO_FATAL_FAILURE(
894 : ExpectFunctionFrequency(frequency_map, "BBEntryCallOnce", 1));
895 E : ASSERT_NO_FATAL_FAILURE(
896 : ExpectFunctionFrequency(frequency_map, "BBEntryCallTree", 1));
897 E : ASSERT_NO_FATAL_FAILURE(
898 : ExpectFunctionFrequency(frequency_map, "BBEntryFunction1", 4));
899 E : ASSERT_NO_FATAL_FAILURE(
900 : ExpectFunctionFrequency(frequency_map, "BBEntryFunction2", 2));
901 E : ASSERT_NO_FATAL_FAILURE(
902 : ExpectFunctionFrequency(frequency_map, "BBEntryFunction3", 1));
903 E : ASSERT_NO_FATAL_FAILURE(
904 : ExpectFunctionFrequency(frequency_map, "BBEntryCallRecursive", 1));
905 E : ASSERT_NO_FATAL_FAILURE(
906 : ExpectFunctionFrequency(frequency_map, "BBEntryFunctionRecursive", 42));
907 E : }
908 :
909 E : bool GetLineInfoExecution(const SourceFileCoverageData* data, size_t line) {
910 E : DCHECK(data != NULL);
911 :
912 E : const LineExecutionCountMap& lines = data->line_execution_count_map;
913 E : LineExecutionCountMap::const_iterator look = lines.find(line);
914 E : if (look != lines.end()) {
915 E : if (look->second != 0)
916 E : return true;
917 : }
918 :
919 E : return false;
920 E : }
921 :
922 E : void CoverageInvokeTestDll() {
923 E : EXPECT_EQ(182, InvokeTestDllFunction(testing::kCoverage1));
924 E : EXPECT_EQ(182, InvokeTestDllFunction(testing::kCoverage2));
925 E : EXPECT_EQ(2, InvokeTestDllFunction(testing::kCoverage3));
926 E : }
927 :
928 E : void CoverageCheckTestDll() {
929 E : Parser parser;
930 E : grinder::grinders::CoverageGrinder grinder;
931 :
932 : // Initialize trace parser.
933 E : ASSERT_TRUE(parser.Init(&grinder));
934 E : grinder.SetParser(&parser);
935 :
936 : // Add generated traces to the parser.
937 E : QueueTraces(&parser);
938 :
939 : // Parse all traces.
940 E : ASSERT_TRUE(parser.Consume());
941 E : ASSERT_FALSE(parser.error_occurred());
942 E : ASSERT_TRUE(grinder.Grind());
943 :
944 : // Retrieve coverage information.
945 E : const grinder::CoverageData& coverage_data = grinder.coverage_data();
946 : const SourceFileCoverageDataMap& files =
947 E : coverage_data.source_file_coverage_data_map();
948 :
949 : // Find file "coverage_tests.cc".
950 E : SourceFileCoverageDataMap::const_iterator file = files.begin();
951 E : const SourceFileCoverageData* data = NULL;
952 E : for (; file != files.end(); ++file) {
953 E : if (EndsWith(file->first, "coverage_tests.cc", true)) {
954 E : data = &file->second;
955 E : break;
956 : }
957 E : }
958 E : ASSERT_TRUE(data != NULL);
959 :
960 : // Validate function entry counts.
961 : // Function: coverage_func1.
962 E : EXPECT_TRUE(GetLineInfoExecution(data, 28));
963 E : EXPECT_TRUE(GetLineInfoExecution(data, 29));
964 :
965 : // Function: coverage_func2.
966 E : EXPECT_TRUE(GetLineInfoExecution(data, 35));
967 E : EXPECT_TRUE(GetLineInfoExecution(data, 36));
968 E : EXPECT_TRUE(GetLineInfoExecution(data, 37));
969 E : EXPECT_FALSE(GetLineInfoExecution(data, 40));
970 E : EXPECT_TRUE(GetLineInfoExecution(data, 42));
971 :
972 : // Function: coverage_func3.
973 E : EXPECT_TRUE(GetLineInfoExecution(data, 47));
974 E : EXPECT_FALSE(GetLineInfoExecution(data, 49));
975 E : EXPECT_FALSE(GetLineInfoExecution(data, 50));
976 E : EXPECT_TRUE(GetLineInfoExecution(data, 52));
977 E : EXPECT_TRUE(GetLineInfoExecution(data, 54));
978 E : }
979 :
980 : static bool ContainsString(const std::vector<std::wstring>& vec,
981 E : const wchar_t* str) {
982 E : return std::find(vec.begin(), vec.end(), str) != vec.end();
983 E : }
984 :
985 E : void ProfileCheckTestDll(bool thunk_imports) {
986 E : Parser parser;
987 E : TestingProfileGrinder grinder;
988 :
989 : // Have the grinder aggregate all data to a single part.
990 E : grinder.set_thread_parts(false);
991 :
992 : // Initialize trace parser.
993 E : ASSERT_TRUE(parser.Init(&grinder));
994 E : grinder.SetParser(&parser);
995 :
996 : // Add generated traces to the parser.
997 E : QueueTraces(&parser);
998 :
999 : // Parse all traces.
1000 E : ASSERT_TRUE(parser.Consume());
1001 E : ASSERT_FALSE(parser.error_occurred());
1002 E : ASSERT_TRUE(grinder.Grind());
1003 :
1004 : const TestingProfileGrinder::ModuleInformationSet& modules =
1005 E : grinder.modules_;
1006 E : TestingProfileGrinder::ModuleInformationSet::const_iterator mod_it;
1007 E : std::vector<std::wstring> module_names;
1008 E : for (mod_it = modules.begin(); mod_it != modules.end(); ++mod_it) {
1009 E : base::FilePath image_name(mod_it->path);
1010 E : module_names.push_back(image_name.BaseName().value());
1011 E : }
1012 :
1013 E : EXPECT_TRUE(ContainsString(module_names,
1014 : testing::kIntegrationTestsDllName));
1015 : // If imports are thunked, we expect to find a module entry for the export
1016 : // DLL - otherwise it shouldn't be in there at all.
1017 E : if (thunk_imports) {
1018 E : EXPECT_TRUE(ContainsString(module_names, L"export_dll.dll"));
1019 E : } else {
1020 E : EXPECT_FALSE(ContainsString(module_names, L"export_dll.dll"));
1021 : }
1022 :
1023 : // Make sure at least one function we know of was hit.
1024 E : ASSERT_EQ(1U, grinder.parts_.size());
1025 : const TestingProfileGrinder::PartData& data =
1026 E : grinder.parts_.begin()->second;
1027 :
1028 : TestingProfileGrinder::InvocationNodeMap::const_iterator node_it =
1029 E : data.nodes_.begin();
1030 E : for (; node_it != data.nodes_.end(); ++node_it) {
1031 E : if (node_it->second.function.rva() == get_my_rva_)
1032 E : return;
1033 E : }
1034 :
1035 i : FAIL() << "Didn't find GetMyRVA function entry.";
1036 E : }
1037 :
1038 : // Helper function to test the Asan symbolizer script.
1039 : //
1040 : // It starts by running a test with the '--minidump_on_failure' flag turned
1041 : // on and then verify that the generated minidump can be symbolized correctly.
1042 : //
1043 : // @param test_id The test to run.
1044 : // @param kind The expected bad access kind.
1045 : // @param mode The expected bad access mode.
1046 : // @param size The expected bad access size.
1047 : // @param expect_corrupt_heap Indicates if we expect the heap to be corrupt.
1048 : void AsanSymbolizerTest(testing::EndToEndTestId test_id,
1049 : const char* kind,
1050 : const char* mode,
1051 : size_t size,
1052 E : bool expect_corrupt_heap) {
1053 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1054 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1055 :
1056 : // Make sure that a minidump gets produced by the logger when a bug occurs.
1057 E : scoped_ptr<base::Environment> env(base::Environment::Create());
1058 E : ASSERT_NE(env.get(), nullptr);
1059 E : if (expect_corrupt_heap) {
1060 E : env->SetVar(::common::kSyzyAsanOptionsEnvVar, "--minidump_on_failure");
1061 E : } else {
1062 : env->SetVar(::common::kSyzyAsanOptionsEnvVar,
1063 E : "--minidump_on_failure --no_check_heap_on_failure");
1064 : }
1065 E : std::string log;
1066 :
1067 : // Run the test.
1068 E : OutOfProcessAsanErrorCheck(test_id, true, &log);
1069 :
1070 : // Look for the minidump path in the logger's output.
1071 E : pcrecpp::RE re("A minidump has been written to (.*\\.dmp)\\.\\n?");
1072 E : std::string minidump_path;
1073 E : EXPECT_TRUE(re.PartialMatch(log, &minidump_path));
1074 :
1075 : // Run the symbolizer tester script to make sure that the minidump gets
1076 : // symbolized correctly.
1077 :
1078 : base::CommandLine cmd_line(
1079 E : ::testing::GetSrcRelativePath(L"third_party/python_26/python.exe"));
1080 : cmd_line.AppendArgPath(::testing::GetSrcRelativePath(
1081 E : L"syzygy/scripts/asan/minidump_symbolizer_tester.py"));
1082 : cmd_line.AppendArg(base::StringPrintf("--minidump=%s",
1083 E : minidump_path.c_str()));
1084 E : cmd_line.AppendArg(base::StringPrintf("--bug-type=%s", kind));
1085 E : cmd_line.AppendArg(base::StringPrintf("--access-mode=%s", mode));
1086 E : cmd_line.AppendArg(base::StringPrintf("--access-size=%d", size));
1087 E : if (expect_corrupt_heap)
1088 E : cmd_line.AppendArg("--corrupt-heap");
1089 :
1090 E : base::LaunchOptions options;
1091 : base::ProcessHandle handle;
1092 E : options.inherit_handles = true;
1093 E : EXPECT_TRUE(base::LaunchProcess(cmd_line, options, &handle));
1094 :
1095 E : int exit_code = 0;
1096 E : EXPECT_TRUE(base::WaitForExitCode(handle, &exit_code));
1097 E : EXPECT_EQ(0u, exit_code);
1098 :
1099 E : env->UnSetVar(::common::kSyzyAsanOptionsEnvVar);
1100 E : }
1101 :
1102 : // Stashes the current log-level before each test instance and restores it
1103 : // after each test completes.
1104 : testing::ScopedLogLevelSaver log_level_saver;
1105 :
1106 : // @name The application under test.
1107 : // @{
1108 : TestApp test_app_;
1109 : TestApp::Implementation& test_impl_;
1110 : base::FilePath temp_dir_;
1111 : base::FilePath stdin_path_;
1112 : base::FilePath stdout_path_;
1113 : base::FilePath stderr_path_;
1114 : // @}
1115 :
1116 : // @name Command-line, parameters and outputs.
1117 : // @{
1118 : CommandLine cmd_line_;
1119 : base::FilePath input_dll_path_;
1120 : base::FilePath output_dll_path_;
1121 : base::FilePath traces_dir_;
1122 : // @}
1123 :
1124 : // The test_dll module.
1125 : testing::ScopedHMODULE module_;
1126 :
1127 : // Our call trace service process instance.
1128 : testing::CallTraceService service_;
1129 :
1130 : // Decomposed image.
1131 : pe::PEFile pe_image_;
1132 : pe::ImageLayout image_layout_;
1133 : block_graph::BlockGraph block_graph_;
1134 : uint32 get_my_rva_;
1135 : };
1136 :
1137 : typedef std::map<std::string, size_t> FunctionOffsetMap;
1138 :
1139 : // A utility transform for extracting call site offsets from blocks.
1140 : // Used by GetCallOffsets and ZebraBlockHeap tests.
1141 : class ExtractCallTransform
1142 : : public block_graph::BasicBlockSubGraphTransformInterface {
1143 : public:
1144 E : explicit ExtractCallTransform(FunctionOffsetMap* map) : map_(map) { }
1145 E : virtual ~ExtractCallTransform() { }
1146 i : virtual const char* name() const { return "ExtractCallTransform"; }
1147 :
1148 : virtual bool TransformBasicBlockSubGraph(
1149 : const block_graph::TransformPolicyInterface* policy,
1150 : block_graph::BlockGraph* block_graph,
1151 E : block_graph::BasicBlockSubGraph* basic_block_subgraph) {
1152 E : for (auto& desc : basic_block_subgraph->block_descriptions()) {
1153 E : auto map_it = map_->find(desc.name);
1154 E : if (map_it == map_->end())
1155 E : continue;
1156 :
1157 : // Set this to effectively 'infinite' to start with.
1158 E : map_it->second = static_cast<size_t>(-1);
1159 :
1160 E : for (auto& bb : desc.basic_block_order) {
1161 : block_graph::BasicCodeBlock* bcb =
1162 E : block_graph::BasicCodeBlock::Cast(bb);
1163 E : if (bcb == nullptr)
1164 E : continue;
1165 :
1166 E : size_t offset = bcb->offset();
1167 E : for (auto& inst : bcb->instructions()) {
1168 E : offset += inst.size();
1169 E : if (inst.IsCall()) {
1170 E : map_it->second = std::min(map_it->second, offset);
1171 : }
1172 : }
1173 : }
1174 : }
1175 :
1176 E : return true;
1177 E : }
1178 :
1179 : protected:
1180 : FunctionOffsetMap* map_;
1181 : };
1182 :
1183 : // Gets the offsets of the first call from each function named in |map|,
1184 : // as found in the image at |image_path|. Updates the map with the offsets.
1185 : void GetCallOffsets(const base::FilePath& image_path,
1186 E : FunctionOffsetMap* map) {
1187 E : pe::PEFile pe_file;
1188 E : ASSERT_TRUE(pe_file.Init(image_path));
1189 E : block_graph::BlockGraph bg;
1190 E : block_graph::BlockGraph::Block* header = NULL;
1191 :
1192 : // Decompose the image.
1193 : {
1194 E : pe::ImageLayout image_layout(&bg);
1195 E : pe::Decomposer decomposer(pe_file);
1196 E : ASSERT_TRUE(decomposer.Decompose(&image_layout));
1197 : header = image_layout.blocks.GetBlockByAddress(
1198 E : block_graph::BlockGraph::RelativeAddress(0));
1199 E : }
1200 :
1201 : // Apply the Asan transform.
1202 E : pe::PETransformPolicy policy;
1203 : {
1204 E : instrument::transforms::AsanTransform tx;
1205 : ASSERT_TRUE(block_graph::ApplyBlockGraphTransform(
1206 E : &tx, &policy, &bg, header));
1207 E : }
1208 :
1209 : // Apply our dummy transform which simply extracts call addresses.
1210 : {
1211 E : ExtractCallTransform bbtx(map);
1212 E : block_graph::transforms::ChainedBasicBlockTransforms tx;
1213 E : tx.AppendTransform(&bbtx);
1214 : ASSERT_TRUE(block_graph::ApplyBlockGraphTransform(
1215 E : &tx, &policy, &bg, header));
1216 E : }
1217 E : }
1218 :
1219 E : void InstrumentAppIntegrationTest::AsanZebraHeapTest(bool enabled) {
1220 : // Find the offset of the call we want to instrument.
1221 : static const char kTest1[] =
1222 : "testing::AsanReadPageAllocationTrailerBeforeFree";
1223 : static const char kTest2[] =
1224 : "testing::AsanWritePageAllocationBodyAfterFree";
1225 E : FunctionOffsetMap map({{kTest1, -1}, {kTest2, -1}});
1226 E : ASSERT_NO_FATAL_FAILURE(GetCallOffsets(input_dll_path_, &map));
1227 :
1228 : // Create an allocation filter.
1229 E : base::FilePath filter_path = temp_dir_.AppendASCII("allocation_filter.json");
1230 : std::string filter_contents = base::StringPrintf(
1231 : "{\"hooks\":{\"%s\":[%d],\"%s\":[%d]}}",
1232 E : kTest1, map[kTest1], kTest2, map[kTest2]);
1233 : base::WriteFile(
1234 E : filter_path, filter_contents.c_str(), filter_contents.size());
1235 :
1236 : // Configure the transform and test the binary.
1237 E : cmd_line_.AppendSwitchPath("allocation-filter-config-file", filter_path);
1238 E : std::string rtl_options = "--no_check_heap_on_failure";
1239 E : if (enabled)
1240 E : rtl_options += " --enable_zebra_block_heap --enable_allocation_filter";
1241 E : cmd_line_.AppendSwitchASCII("asan-rtl-options", rtl_options);
1242 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1243 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1244 :
1245 : // Run tests that are specific to the zebra block heap.
1246 : OutOfProcessAsanErrorCheckAndValidateLog(
1247 : testing::kAsanReadPageAllocationTrailerBeforeFreeAllocation, enabled,
1248 E : kAsanAccessViolationLog, kAsanHeapBufferOverflow);
1249 : OutOfProcessAsanErrorCheckAndValidateLog(
1250 : testing::kAsanWritePageAllocationBodyAfterFree, enabled,
1251 E : kAsanAccessViolationLog, kAsanHeapUseAfterFree);
1252 E : }
1253 :
1254 : } // namespace
1255 :
1256 E : TEST_F(InstrumentAppIntegrationTest, AsanEndToEnd) {
1257 : // Disable the heap checking as this is implies touching all the shadow bytes
1258 : // and this make those tests really slow.
1259 E : cmd_line_.AppendSwitchASCII("asan-rtl-options", "--no_check_heap_on_failure");
1260 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1261 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1262 E : ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1263 E : }
1264 :
1265 E : TEST_F(InstrumentAppIntegrationTest, AsanEndToEndNoLiveness) {
1266 : // Disable the heap checking as this is implies touching all the shadow bytes
1267 : // and this make those tests really slow.
1268 E : cmd_line_.AppendSwitchASCII("asan-rtl-options", "--no_check_heap_on_failure");
1269 E : cmd_line_.AppendSwitch("no-liveness-analysis");
1270 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1271 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1272 E : ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1273 E : }
1274 :
1275 E : TEST_F(InstrumentAppIntegrationTest, AsanEndToEndNoRedundancyAnalysis) {
1276 : // Disable the heap checking as this is implies touching all the shadow bytes
1277 : // and this make those tests really slow.
1278 E : cmd_line_.AppendSwitchASCII("asan-rtl-options", "--no_check_heap_on_failure");
1279 E : cmd_line_.AppendSwitch("no-redundancy-analysis");
1280 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1281 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1282 E : ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1283 E : }
1284 :
1285 E : TEST_F(InstrumentAppIntegrationTest, AsanEndToEndNoFunctionInterceptors) {
1286 : // Disable the heap checking as this is implies touching all the shadow bytes
1287 : // and this make those tests really slow.
1288 E : cmd_line_.AppendSwitchASCII("asan-rtl-options", "--no_check_heap_on_failure");
1289 E : cmd_line_.AppendSwitch("no-interceptors");
1290 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1291 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1292 E : ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1293 E : }
1294 :
1295 E : TEST_F(InstrumentAppIntegrationTest, AsanEndToEndWithRtlOptions) {
1296 : cmd_line_.AppendSwitchASCII(
1297 : "asan-rtl-options",
1298 : "--quarantine_size=20000000 --quarantine_block_size=1000000 "
1299 E : "--no_check_heap_on_failure");
1300 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1301 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1302 E : ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1303 :
1304 : // Get the active runtime and validate its parameters.
1305 E : agent::asan::AsanRuntime* runtime = GetActiveAsanRuntime();
1306 E : ASSERT_TRUE(runtime != NULL);
1307 E : ASSERT_EQ(20000000u, runtime->params().quarantine_size);
1308 E : ASSERT_EQ(1000000u, runtime->params().quarantine_block_size);
1309 E : }
1310 :
1311 : TEST_F(InstrumentAppIntegrationTest,
1312 E : AsanEndToEndWithRtlOptionsOverrideWithEnvironment) {
1313 E : scoped_ptr<base::Environment> env(base::Environment::Create());
1314 E : ASSERT_NE(env.get(), nullptr);
1315 : env->SetVar(::common::kSyzyAsanOptionsEnvVar,
1316 : "--quarantine_block_size=800000 --ignored_stack_ids=0x1 "
1317 E : "--no_check_heap_on_failure");
1318 : cmd_line_.AppendSwitchASCII(
1319 : "asan-rtl-options",
1320 : "--quarantine_size=20000000 --quarantine_block_size=1000000 "
1321 E : "--ignored_stack_ids=0x2");
1322 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1323 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1324 E : ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1325 :
1326 : // Get the active runtime and validate its parameters.
1327 E : agent::asan::AsanRuntime* runtime = GetActiveAsanRuntime();
1328 E : ASSERT_TRUE(runtime != NULL);
1329 E : ASSERT_EQ(20000000u, runtime->params().quarantine_size);
1330 E : ASSERT_EQ(800000u, runtime->params().quarantine_block_size);
1331 : ASSERT_THAT(runtime->params().ignored_stack_ids_set,
1332 E : testing::ElementsAre(0x1, 0x2));
1333 :
1334 E : env->UnSetVar(::common::kSyzyAsanOptionsEnvVar);
1335 E : }
1336 :
1337 E : TEST_F(InstrumentAppIntegrationTest, FullOptimizedAsanEndToEnd) {
1338 : // Disable the heap checking as this is implies touching all the shadow bytes
1339 : // and this make those tests really slow.
1340 E : cmd_line_.AppendSwitchASCII("asan-rtl-options", "--no_check_heap_on_failure");
1341 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1342 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1343 E : ASSERT_NO_FATAL_FAILURE(AsanErrorCheckTestDll());
1344 E : ASSERT_NO_FATAL_FAILURE(AsanErrorCheckInterceptedFunctions());
1345 E : }
1346 :
1347 : TEST_F(InstrumentAppIntegrationTest,
1348 E : AsanInvalidAccessWithCorruptAllocatedBlockHeader) {
1349 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1350 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1351 : OutOfProcessAsanErrorCheckAndValidateLog(
1352 : testing::kAsanInvalidAccessWithCorruptAllocatedBlockHeader, true,
1353 E : kAsanCorruptHeap, NULL);
1354 E : }
1355 :
1356 : TEST_F(InstrumentAppIntegrationTest,
1357 E : AsanHeapCheckerIgnoresCrashForException) {
1358 : // Heap checker failures go through the unhandled exception filter even if
1359 : // CrashForException is defined.
1360 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1361 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1362 :
1363 : int exit_code = RunOutOfProcessFunction(
1364 : L"crash_for_exception_harness.exe",
1365 E : testing::kAsanInvalidAccessWithCorruptAllocatedBlockHeader, true);
1366 E : EXPECT_EQ(EXIT_SUCCESS, exit_code);
1367 E : }
1368 :
1369 : TEST_F(InstrumentAppIntegrationTest,
1370 E : AsanHeapCheckerCallsReportCrashWithProtobuf) {
1371 : // Heap checker failures do get reported to ReportCrashWithProtobuf if it is
1372 : // defined.
1373 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1374 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1375 :
1376 : int exit_code = RunOutOfProcessFunction(
1377 : L"report_crash_with_protobuf_harness.exe",
1378 E : testing::kAsanInvalidAccessWithCorruptAllocatedBlockHeader, true);
1379 E : EXPECT_EQ(kExeReportCrashWithProtobufExitCode, exit_code);
1380 E : }
1381 :
1382 : TEST_F(InstrumentAppIntegrationTest,
1383 E : AsanOverflowCallsCrashForException) {
1384 : // Asan-detected violations go through CrashForException if it is available.
1385 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1386 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1387 : int exit_code =
1388 : RunOutOfProcessFunction(L"crash_for_exception_harness.exe",
1389 E : testing::kAsanRead8BufferOverflow, true);
1390 E : EXPECT_EQ(kExeCrashForExceptionExitCode, exit_code);
1391 E : }
1392 :
1393 : TEST_F(InstrumentAppIntegrationTest,
1394 E : AsanOverflowCallsReportCrashWithProtobuf) {
1395 : // Asan-detected violations go through ReportCrashWithProtobuf if it is
1396 : // available.
1397 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1398 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1399 : int exit_code =
1400 : RunOutOfProcessFunction(L"report_crash_with_protobuf_harness.exe",
1401 E : testing::kAsanRead8BufferOverflow, true);
1402 E : EXPECT_EQ(kExeReportCrashWithProtobufExitCode, exit_code);
1403 E : }
1404 :
1405 : TEST_F(InstrumentAppIntegrationTest,
1406 E : AsanInvalidAccessWithCorruptAllocatedBlockTrailer) {
1407 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1408 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1409 : OutOfProcessAsanErrorCheckAndValidateLog(
1410 : testing::kAsanInvalidAccessWithCorruptAllocatedBlockTrailer, true,
1411 E : kAsanCorruptHeap, NULL);
1412 E : }
1413 :
1414 E : TEST_F(InstrumentAppIntegrationTest, AsanInvalidAccessWithCorruptFreedBlock) {
1415 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1416 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1417 : OutOfProcessAsanErrorCheckAndValidateLog(
1418 : testing::kAsanInvalidAccessWithCorruptFreedBlock, true, kAsanCorruptHeap,
1419 E : NULL);
1420 E : }
1421 :
1422 E : TEST_F(InstrumentAppIntegrationTest, AsanCorruptBlockWithPageProtections) {
1423 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1424 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1425 : OutOfProcessAsanErrorCheckAndValidateLog(
1426 : testing::kAsanCorruptBlockWithPageProtections, true,
1427 E : kAsanHeapUseAfterFree, kAsanCorruptHeap);
1428 E : }
1429 :
1430 E : TEST_F(InstrumentAppIntegrationTest, SampledAllocationsAsanEndToEnd) {
1431 : cmd_line_.AppendSwitchASCII("asan-rtl-options",
1432 : "--allocation_guard_rate=0.5 "
1433 E : "--no_check_heap_on_failure");
1434 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1435 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1436 E : ASSERT_NO_FATAL_FAILURE(AsanErrorCheckSampledAllocations());
1437 E : }
1438 :
1439 E : TEST_F(InstrumentAppIntegrationTest, AsanLargeBlockHeapEnabledTest) {
1440 : cmd_line_.AppendSwitchASCII("asan-rtl-options",
1441 : "--no_check_heap_on_failure "
1442 : "--quarantine_size=4000000 "
1443 E : "--quarantine_block_size=2000000");
1444 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1445 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1446 E : ASSERT_NO_FATAL_FAILURE(AsanLargeBlockHeapTests(true));
1447 E : }
1448 :
1449 E : TEST_F(InstrumentAppIntegrationTest, AsanLargeBlockHeapDisabledTest) {
1450 : cmd_line_.AppendSwitchASCII("asan-rtl-options",
1451 : "--no_check_heap_on_failure "
1452 E : "--disable_large_block_heap");
1453 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1454 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1455 E : ASSERT_NO_FATAL_FAILURE(AsanLargeBlockHeapTests(false));
1456 E : }
1457 :
1458 E : TEST_F(InstrumentAppIntegrationTest, AsanLargeBlockHeapCtMallocDisabledTest) {
1459 : cmd_line_.AppendSwitchASCII("asan-rtl-options",
1460 : "--no_check_heap_on_failure "
1461 : "--disable_large_block_heap "
1462 E : "--disable_ctmalloc");
1463 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("asan"));
1464 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1465 E : ASSERT_NO_FATAL_FAILURE(AsanLargeBlockHeapTests(false));
1466 E : }
1467 :
1468 E : TEST_F(InstrumentAppIntegrationTest, AsanZebraHeapDisabledTest) {
1469 E : AsanZebraHeapTest(false);
1470 E : }
1471 :
1472 E : TEST_F(InstrumentAppIntegrationTest, AsanZebraHeapEnabledTest) {
1473 E : AsanZebraHeapTest(true);
1474 E : }
1475 :
1476 E : TEST_F(InstrumentAppIntegrationTest, AsanSymbolizerTestAsanBufferOverflow) {
1477 : AsanSymbolizerTest(testing::kAsanRead8BufferOverflow,
1478 : STRINGIFY(HEAP_BUFFER_OVERFLOW),
1479 : STRINGIFY(ASAN_READ_ACCESS),
1480 : 1,
1481 E : false);
1482 E : }
1483 :
1484 E : TEST_F(InstrumentAppIntegrationTest, AsanSymbolizerTestAsanBufferUnderflow) {
1485 : AsanSymbolizerTest(testing::kAsanWrite32BufferUnderflow,
1486 : STRINGIFY(HEAP_BUFFER_UNDERFLOW),
1487 : STRINGIFY(ASAN_WRITE_ACCESS),
1488 : 4,
1489 E : false);
1490 E : }
1491 :
1492 E : TEST_F(InstrumentAppIntegrationTest, AsanSymbolizerTestAsanUseAfterFree) {
1493 : AsanSymbolizerTest(testing::kAsanRead64UseAfterFree,
1494 : STRINGIFY(USE_AFTER_FREE),
1495 : STRINGIFY(ASAN_READ_ACCESS),
1496 : 8,
1497 E : false);
1498 E : }
1499 :
1500 E : TEST_F(InstrumentAppIntegrationTest, AsanSymbolizerTestAsanCorruptBlock) {
1501 : AsanSymbolizerTest(testing::kAsanCorruptBlock,
1502 : STRINGIFY(CORRUPT_BLOCK),
1503 : STRINGIFY(ASAN_UNKNOWN_ACCESS),
1504 : 0,
1505 E : false);
1506 E : }
1507 :
1508 : TEST_F(InstrumentAppIntegrationTest,
1509 E : AsanSymbolizerTestAsanCorruptBlockInQuarantine) {
1510 : AsanSymbolizerTest(testing::kAsanCorruptBlockInQuarantine,
1511 : STRINGIFY(CORRUPT_BLOCK),
1512 : STRINGIFY(ASAN_UNKNOWN_ACCESS),
1513 : 0,
1514 E : true);
1515 E : }
1516 :
1517 E : TEST_F(InstrumentAppIntegrationTest, BBEntryEndToEnd) {
1518 E : ASSERT_NO_FATAL_FAILURE(StartService());
1519 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("bbentry"));
1520 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1521 E : ASSERT_NO_FATAL_FAILURE(BBEntryInvokeTestDll());
1522 E : ASSERT_NO_FATAL_FAILURE(StopService());
1523 E : ASSERT_NO_FATAL_FAILURE(BBEntryCheckTestDll());
1524 E : }
1525 :
1526 E : TEST_F(InstrumentAppIntegrationTest, BranchEndToEnd) {
1527 E : ASSERT_NO_FATAL_FAILURE(StartService());
1528 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("branch"));
1529 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1530 E : ASSERT_NO_FATAL_FAILURE(BBEntryInvokeTestDll());
1531 E : ASSERT_NO_FATAL_FAILURE(UnloadDll());
1532 E : ASSERT_NO_FATAL_FAILURE(StopService());
1533 E : ASSERT_NO_FATAL_FAILURE(BranchCheckTestDll());
1534 E : }
1535 :
1536 E : TEST_F(InstrumentAppIntegrationTest, BranchWithBufferingEndToEnd) {
1537 E : cmd_line_.AppendSwitch("buffering");
1538 E : ASSERT_NO_FATAL_FAILURE(StartService());
1539 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("branch"));
1540 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1541 E : ASSERT_NO_FATAL_FAILURE(BBEntryInvokeTestDll());
1542 E : ASSERT_NO_FATAL_FAILURE(UnloadDll());
1543 E : ASSERT_NO_FATAL_FAILURE(StopService());
1544 E : ASSERT_NO_FATAL_FAILURE(BranchCheckTestDll());
1545 E : }
1546 :
1547 E : TEST_F(InstrumentAppIntegrationTest, BranchWithSlotEndToEnd) {
1548 E : cmd_line_.AppendSwitchASCII("fs-slot", "1");
1549 E : ASSERT_NO_FATAL_FAILURE(StartService());
1550 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("branch"));
1551 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1552 E : ASSERT_NO_FATAL_FAILURE(BBEntryInvokeTestDll());
1553 E : ASSERT_NO_FATAL_FAILURE(UnloadDll());
1554 E : ASSERT_NO_FATAL_FAILURE(StopService());
1555 E : ASSERT_NO_FATAL_FAILURE(BranchCheckTestDll());
1556 E : }
1557 :
1558 E : TEST_F(InstrumentAppIntegrationTest, BranchWithSlotAndBufferingEndToEnd) {
1559 E : cmd_line_.AppendSwitch("buffering");
1560 E : cmd_line_.AppendSwitchASCII("fs-slot", "1");
1561 E : ASSERT_NO_FATAL_FAILURE(StartService());
1562 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("branch"));
1563 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1564 E : ASSERT_NO_FATAL_FAILURE(BBEntryInvokeTestDll());
1565 E : ASSERT_NO_FATAL_FAILURE(UnloadDll());
1566 E : ASSERT_NO_FATAL_FAILURE(StopService());
1567 E : ASSERT_NO_FATAL_FAILURE(BranchCheckTestDll());
1568 E : }
1569 :
1570 E : TEST_F(InstrumentAppIntegrationTest, CallTraceEndToEnd) {
1571 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("calltrace"));
1572 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1573 E : }
1574 :
1575 E : TEST_F(InstrumentAppIntegrationTest, CoverageEndToEnd) {
1576 E : base::win::ScopedCOMInitializer scoped_com_initializer;
1577 E : ASSERT_NO_FATAL_FAILURE(StartService());
1578 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("coverage"));
1579 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1580 E : ASSERT_NO_FATAL_FAILURE(CoverageInvokeTestDll());
1581 E : ASSERT_NO_FATAL_FAILURE(StopService());
1582 E : ASSERT_NO_FATAL_FAILURE(CoverageCheckTestDll());
1583 E : }
1584 :
1585 E : TEST_F(InstrumentAppIntegrationTest, BBEntryCoverageEndToEnd) {
1586 : // Coverage grinder must be able to process traces produced by bbentry
1587 : // instrumentation.
1588 E : base::win::ScopedCOMInitializer scoped_com_initializer;
1589 E : ASSERT_NO_FATAL_FAILURE(StartService());
1590 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("bbentry"));
1591 E : ASSERT_NO_FATAL_FAILURE(EndToEndCheckTestDll());
1592 E : ASSERT_NO_FATAL_FAILURE(CoverageInvokeTestDll());
1593 E : ASSERT_NO_FATAL_FAILURE(StopService());
1594 E : ASSERT_NO_FATAL_FAILURE(CoverageCheckTestDll());
1595 E : }
1596 :
1597 E : TEST_F(InstrumentAppIntegrationTest, ProfileEndToEnd) {
1598 E : ASSERT_NO_FATAL_FAILURE(StartService());
1599 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("profile"));
1600 E : ASSERT_NO_FATAL_FAILURE(ProfileInvokeTestDll());
1601 E : ASSERT_NO_FATAL_FAILURE(UnloadDll());
1602 E : ASSERT_NO_FATAL_FAILURE(StopService());
1603 E : ASSERT_NO_FATAL_FAILURE(ProfileCheckTestDll(false));
1604 E : }
1605 :
1606 E : TEST_F(InstrumentAppIntegrationTest, ProfileWithImportsEndToEnd) {
1607 E : cmd_line_.AppendSwitch("instrument-imports");
1608 E : ASSERT_NO_FATAL_FAILURE(StartService());
1609 E : ASSERT_NO_FATAL_FAILURE(EndToEndTest("profile"));
1610 E : ASSERT_NO_FATAL_FAILURE(ProfileInvokeTestDll());
1611 E : ASSERT_NO_FATAL_FAILURE(UnloadDll());
1612 E : ASSERT_NO_FATAL_FAILURE(StopService());
1613 E : ASSERT_NO_FATAL_FAILURE(ProfileCheckTestDll(true));
1614 E : }
1615 :
1616 : } // namespace integration_tests
|