Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / sandbox / win / src / address_sanitizer_test.cc
blobb88aa81cd43cb12347929962564317c37228a9b5
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <stdio.h>
7 #include "base/environment.h"
8 #include "base/files/file_path.h"
9 #include "base/files/file_util.h"
10 #include "base/files/scoped_temp_dir.h"
11 #include "base/path_service.h"
12 #include "base/win/scoped_handle.h"
13 #include "base/win/windows_version.h"
14 #include "sandbox/win/tests/common/controller.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 namespace sandbox {
19 class AddressSanitizerTests : public ::testing::Test {
20 public:
21 void SetUp() override {
22 env_.reset(base::Environment::Create());
23 had_asan_options_ = env_->GetVar("ASAN_OPTIONS", &old_asan_options_);
26 void TearDown() override {
27 if (had_asan_options_)
28 ASSERT_TRUE(env_->SetVar("ASAN_OPTIONS", old_asan_options_));
29 else
30 env_->UnSetVar("ASAN_OPTIONS");
33 protected:
34 scoped_ptr<base::Environment> env_;
35 bool had_asan_options_;
36 std::string old_asan_options_;
39 SBOX_TESTS_COMMAND int AddressSanitizerTests_Report(int argc, wchar_t** argv) {
40 // AddressSanitizer should detect an out of bounds write (heap buffer
41 // overflow) in this code.
42 volatile int idx = 42;
43 int *blah = new int[42];
44 blah[idx] = 42;
45 delete [] blah;
46 return SBOX_TEST_FAILED;
49 TEST_F(AddressSanitizerTests, TestAddressSanitizer) {
50 // This test is only supposed to work when using AddressSanitizer.
51 // However, ASan/Win is not on the CQ yet, so compiler breakages may get into
52 // the code unnoticed. To avoid that, we compile this test in all Windows
53 // builds, but only run the AddressSanitizer-specific part of the test when
54 // compiled with AddressSanitizer.
55 #if defined(ADDRESS_SANITIZER)
56 bool asan_build = true;
57 #else
58 bool asan_build = false;
59 #endif
60 base::ScopedTempDir temp_directory;
61 base::FilePath temp_file_name;
62 ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
63 ASSERT_TRUE(CreateTemporaryFileInDir(temp_directory.path(), &temp_file_name));
65 SECURITY_ATTRIBUTES attrs = {};
66 attrs.nLength = sizeof(attrs);
67 attrs.bInheritHandle = TRUE;
68 base::win::ScopedHandle tmp_handle(
69 CreateFile(temp_file_name.value().c_str(), GENERIC_WRITE,
70 FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
71 &attrs, OPEN_EXISTING, 0, NULL));
72 EXPECT_TRUE(tmp_handle.IsValid());
74 TestRunner runner;
75 ASSERT_EQ(SBOX_ALL_OK, runner.GetPolicy()->SetStderrHandle(tmp_handle.Get()));
77 base::FilePath exe;
78 ASSERT_TRUE(PathService::Get(base::FILE_EXE, &exe));
79 base::FilePath pdb_path = exe.DirName().Append(L"*.pdb");
80 ASSERT_TRUE(runner.AddFsRule(sandbox::TargetPolicy::FILES_ALLOW_READONLY,
81 pdb_path.value().c_str()));
83 env_->SetVar("ASAN_OPTIONS", "exitcode=123");
84 if (asan_build) {
85 int result = runner.RunTest(L"AddressSanitizerTests_Report");
86 EXPECT_EQ(123, result);
88 std::string data;
89 ASSERT_TRUE(base::ReadFileToString(base::FilePath(temp_file_name), &data));
90 // Redirection uses a feature that was added in Windows Vista.
91 if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
92 ASSERT_TRUE(
93 strstr(data.c_str(), "ERROR: AddressSanitizer: heap-buffer-overflow"))
94 << "There doesn't seem to be an ASan report:\n" << data;
95 ASSERT_TRUE(strstr(data.c_str(), "AddressSanitizerTests_Report"))
96 << "The ASan report doesn't appear to be symbolized:\n" << data;
97 ASSERT_TRUE(strstr(data.c_str(), strrchr(__FILE__, '\\')))
98 << "The stack trace doesn't have a correct filename:\n" << data;
99 } else {
100 LOG(WARNING) << "Pre-Vista versions are not supported.";
102 } else {
103 LOG(WARNING) << "Not an AddressSanitizer build, skipping the run.";