Index: sandbox/win/src/address_sanitizer_test.cc |
diff --git a/sandbox/win/src/address_sanitizer_test.cc b/sandbox/win/src/address_sanitizer_test.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..db7339c2e1ae38af4bd47791cbf9b6447a275d27 |
--- /dev/null |
+++ b/sandbox/win/src/address_sanitizer_test.cc |
@@ -0,0 +1,107 @@ |
+// Copyright 2015 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <stdio.h> |
+ |
+#include "base/environment.h" |
+#include "base/files/file_path.h" |
+#include "base/files/file_util.h" |
+#include "base/files/scoped_temp_dir.h" |
+#include "base/path_service.h" |
+#include "base/win/scoped_handle.h" |
+#include "base/win/windows_version.h" |
+#include "sandbox/win/tests/common/controller.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace sandbox { |
+ |
+class AddressSanitizerTests : public ::testing::Test { |
+ public: |
+ void SetUp() { |
+ env_.reset(base::Environment::Create()); |
+ had_asan_options_ = env_->GetVar("ASAN_OPTIONS", &old_asan_options_); |
+ } |
+ |
+ void TearDown() { |
+ if (had_asan_options_) |
+ ASSERT_TRUE(env_->SetVar("ASAN_OPTIONS", old_asan_options_)); |
+ else |
+ env_->UnSetVar("ASAN_OPTIONS"); |
+ } |
+ |
+ protected: |
+ scoped_ptr<base::Environment> env_; |
+ bool had_asan_options_; |
+ std::string old_asan_options_; |
+}; |
+ |
+SBOX_TESTS_COMMAND int AddressSanitizerTests_Report(int argc, wchar_t** argv) { |
+ // AddressSanitizer should detect an out of bounds write (heap buffer |
+ // overflow) in this code. |
+ volatile int idx = 42; |
+ int *blah = new int[42]; |
+ blah[idx] = 42; |
+ delete [] blah; |
+ return SBOX_TEST_FAILED; |
+} |
+ |
+TEST_F(AddressSanitizerTests, TestAddressSanitizer) { |
+ // This test is only supposed to work when using AddressSanitizer. |
+ // However, ASan/Win is not on the CQ yet, so compiler breakages may get into |
+ // the code unnoticed. To avoid that, we compile this test in all Windows |
+ // builds, but only run the AddressSanitizer-specific part of the test when |
+ // compiled with AddressSanitizer. |
+#if defined(ADDRESS_SANITIZER) |
+ bool asan_build = true; |
+#else |
+ bool asan_build = false; |
+#endif |
+ base::ScopedTempDir temp_directory; |
+ base::FilePath temp_file_name; |
+ ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); |
+ ASSERT_TRUE(CreateTemporaryFileInDir(temp_directory.path(), &temp_file_name)); |
+ |
+ SECURITY_ATTRIBUTES attrs = {}; |
+ attrs.nLength = sizeof(attrs); |
+ attrs.bInheritHandle = TRUE; |
+ base::win::ScopedHandle tmp_handle( |
+ CreateFile(temp_file_name.value().c_str(), GENERIC_WRITE, |
+ FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, |
+ &attrs, OPEN_EXISTING, 0, NULL)); |
+ EXPECT_TRUE(tmp_handle.IsValid()); |
+ |
+ TestRunner runner; |
+ ASSERT_EQ(SBOX_ALL_OK, runner.GetPolicy()->SetStderrHandle(tmp_handle.Get())); |
+ |
+ base::FilePath exe; |
+ ASSERT_TRUE(PathService::Get(base::FILE_EXE, &exe)); |
+ base::FilePath pdb_path = exe.DirName().Append(L"*.pdb"); |
+ ASSERT_TRUE(runner.AddFsRule(sandbox::TargetPolicy::FILES_ALLOW_READONLY, |
+ pdb_path.value().c_str())); |
+ |
+ env_->SetVar("ASAN_OPTIONS", "exitcode=123"); |
+ if (asan_build) { |
+ int result = runner.RunTest(L"AddressSanitizerTests_Report"); |
+ EXPECT_EQ(123, result); |
+ |
+ std::string data; |
+ ASSERT_TRUE(base::ReadFileToString(base::FilePath(temp_file_name), &data)); |
+ // Redirection uses a feature that was added in Windows Vista. |
+ if (base::win::GetVersion() >= base::win::VERSION_VISTA) { |
+ ASSERT_TRUE( |
+ strstr(data.c_str(), "ERROR: AddressSanitizer: heap-buffer-overflow")) |
+ << "There doesn't seem to be an ASan report:\n" << data; |
+ ASSERT_TRUE(strstr(data.c_str(), "AddressSanitizerTests_Report")) |
+ << "The ASan report doesn't appear to be symbolized:\n" << data; |
+ ASSERT_TRUE(strstr(data.c_str(), strrchr(__FILE__, '\\'))) |
Nico
2015/02/09 15:17:17
This test isn't passing on the bots:
http://build.
|
+ << "The stack trace doesn't have a correct filename:\n" << data; |
+ } else { |
+ LOG(WARNING) << "Pre-Vista versions are not supported."; |
+ } |
+ } else { |
+ LOG(WARNING) << "Not an AddressSanitizer build, skipping the run."; |
+ } |
+} |
+ |
+} |