1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/win/scoped_handle.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <windows.h>
8*6777b538SAndroid Build Coastguard Worker
9*6777b538SAndroid Build Coastguard Worker #include <winternl.h>
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Worker #include <string>
12*6777b538SAndroid Build Coastguard Worker #include <utility>
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker #include "base/command_line.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/files/file_path.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/scoped_native_library.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/test/multiprocess_test.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/test/test_timeouts.h"
19*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
20*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
21*6777b538SAndroid Build Coastguard Worker #include "testing/multiprocess_func_list.h"
22*6777b538SAndroid Build Coastguard Worker
23*6777b538SAndroid Build Coastguard Worker namespace base {
24*6777b538SAndroid Build Coastguard Worker namespace win {
25*6777b538SAndroid Build Coastguard Worker
26*6777b538SAndroid Build Coastguard Worker namespace {
27*6777b538SAndroid Build Coastguard Worker
FailureMessage(const std::string & msg)28*6777b538SAndroid Build Coastguard Worker std::string FailureMessage(const std::string& msg) {
29*6777b538SAndroid Build Coastguard Worker #if defined(NDEBUG) && defined(OFFICIAL_BUILD)
30*6777b538SAndroid Build Coastguard Worker // Official release builds strip all fatal messages for saving binary size,
31*6777b538SAndroid Build Coastguard Worker // see base/check.h.
32*6777b538SAndroid Build Coastguard Worker return "";
33*6777b538SAndroid Build Coastguard Worker #else
34*6777b538SAndroid Build Coastguard Worker return msg;
35*6777b538SAndroid Build Coastguard Worker #endif // defined(NDEBUG) && defined(OFFICIAL_BUILD)
36*6777b538SAndroid Build Coastguard Worker }
37*6777b538SAndroid Build Coastguard Worker
38*6777b538SAndroid Build Coastguard Worker } // namespace
39*6777b538SAndroid Build Coastguard Worker
40*6777b538SAndroid Build Coastguard Worker namespace testing {
41*6777b538SAndroid Build Coastguard Worker extern "C" bool __declspec(dllexport) RunTest();
42*6777b538SAndroid Build Coastguard Worker } // namespace testing
43*6777b538SAndroid Build Coastguard Worker
44*6777b538SAndroid Build Coastguard Worker using ScopedHandleTest = ::testing::Test;
45*6777b538SAndroid Build Coastguard Worker using ScopedHandleDeathTest = ::testing::Test;
46*6777b538SAndroid Build Coastguard Worker
TEST_F(ScopedHandleTest,ScopedHandle)47*6777b538SAndroid Build Coastguard Worker TEST_F(ScopedHandleTest, ScopedHandle) {
48*6777b538SAndroid Build Coastguard Worker // Any illegal error code will do. We just need to test that it is preserved
49*6777b538SAndroid Build Coastguard Worker // by ScopedHandle to avoid https://crbug.com/528394.
50*6777b538SAndroid Build Coastguard Worker const DWORD magic_error = 0x12345678;
51*6777b538SAndroid Build Coastguard Worker
52*6777b538SAndroid Build Coastguard Worker HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
53*6777b538SAndroid Build Coastguard Worker // Call SetLastError after creating the handle.
54*6777b538SAndroid Build Coastguard Worker ::SetLastError(magic_error);
55*6777b538SAndroid Build Coastguard Worker base::win::ScopedHandle handle_holder(handle);
56*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(magic_error, ::GetLastError());
57*6777b538SAndroid Build Coastguard Worker
58*6777b538SAndroid Build Coastguard Worker // Create a new handle and then set LastError again.
59*6777b538SAndroid Build Coastguard Worker handle = ::CreateMutex(nullptr, false, nullptr);
60*6777b538SAndroid Build Coastguard Worker ::SetLastError(magic_error);
61*6777b538SAndroid Build Coastguard Worker handle_holder.Set(handle);
62*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(magic_error, ::GetLastError());
63*6777b538SAndroid Build Coastguard Worker
64*6777b538SAndroid Build Coastguard Worker // Create a new handle and then set LastError again.
65*6777b538SAndroid Build Coastguard Worker handle = ::CreateMutex(nullptr, false, nullptr);
66*6777b538SAndroid Build Coastguard Worker base::win::ScopedHandle handle_source(handle);
67*6777b538SAndroid Build Coastguard Worker ::SetLastError(magic_error);
68*6777b538SAndroid Build Coastguard Worker handle_holder = std::move(handle_source);
69*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(magic_error, ::GetLastError());
70*6777b538SAndroid Build Coastguard Worker }
71*6777b538SAndroid Build Coastguard Worker
TEST_F(ScopedHandleDeathTest,HandleVerifierTrackedHasBeenClosed)72*6777b538SAndroid Build Coastguard Worker TEST_F(ScopedHandleDeathTest, HandleVerifierTrackedHasBeenClosed) {
73*6777b538SAndroid Build Coastguard Worker HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
74*6777b538SAndroid Build Coastguard Worker ASSERT_NE(HANDLE(nullptr), handle);
75*6777b538SAndroid Build Coastguard Worker
76*6777b538SAndroid Build Coastguard Worker ASSERT_DEATH(
77*6777b538SAndroid Build Coastguard Worker {
78*6777b538SAndroid Build Coastguard Worker base::win::ScopedHandle handle_holder(handle);
79*6777b538SAndroid Build Coastguard Worker ::NtClose(handle);
80*6777b538SAndroid Build Coastguard Worker // Destructing a ScopedHandle with an illegally closed handle should
81*6777b538SAndroid Build Coastguard Worker // fail.
82*6777b538SAndroid Build Coastguard Worker },
83*6777b538SAndroid Build Coastguard Worker FailureMessage("CloseHandle failed"));
84*6777b538SAndroid Build Coastguard Worker }
85*6777b538SAndroid Build Coastguard Worker
TEST_F(ScopedHandleDeathTest,HandleVerifierCloseTrackedHandle)86*6777b538SAndroid Build Coastguard Worker TEST_F(ScopedHandleDeathTest, HandleVerifierCloseTrackedHandle) {
87*6777b538SAndroid Build Coastguard Worker ASSERT_DEATH(
88*6777b538SAndroid Build Coastguard Worker {
89*6777b538SAndroid Build Coastguard Worker HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
90*6777b538SAndroid Build Coastguard Worker ASSERT_NE(HANDLE(nullptr), handle);
91*6777b538SAndroid Build Coastguard Worker
92*6777b538SAndroid Build Coastguard Worker // Start tracking the handle so that closes outside of the checker are
93*6777b538SAndroid Build Coastguard Worker // caught.
94*6777b538SAndroid Build Coastguard Worker base::win::CheckedScopedHandle handle_holder(handle);
95*6777b538SAndroid Build Coastguard Worker
96*6777b538SAndroid Build Coastguard Worker // Closing a tracked handle using ::CloseHandle should crash due to hook
97*6777b538SAndroid Build Coastguard Worker // noticing the illegal close.
98*6777b538SAndroid Build Coastguard Worker ::CloseHandle(handle);
99*6777b538SAndroid Build Coastguard Worker },
100*6777b538SAndroid Build Coastguard Worker // This test must match the CloseHandleHook causing this failure, because
101*6777b538SAndroid Build Coastguard Worker // if the hook doesn't crash and instead the handle is double closed by
102*6777b538SAndroid Build Coastguard Worker // the `handle_holder` going out of scope, then there is still a crash,
103*6777b538SAndroid Build Coastguard Worker // but a different crash and one we are not explicitly testing here. This
104*6777b538SAndroid Build Coastguard Worker // other crash is tested in HandleVerifierTrackedHasBeenClosed above.
105*6777b538SAndroid Build Coastguard Worker FailureMessage("CloseHandleHook validation failure"));
106*6777b538SAndroid Build Coastguard Worker }
107*6777b538SAndroid Build Coastguard Worker
TEST_F(ScopedHandleDeathTest,HandleVerifierDoubleTracking)108*6777b538SAndroid Build Coastguard Worker TEST_F(ScopedHandleDeathTest, HandleVerifierDoubleTracking) {
109*6777b538SAndroid Build Coastguard Worker HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
110*6777b538SAndroid Build Coastguard Worker ASSERT_NE(HANDLE(nullptr), handle);
111*6777b538SAndroid Build Coastguard Worker
112*6777b538SAndroid Build Coastguard Worker base::win::CheckedScopedHandle handle_holder(handle);
113*6777b538SAndroid Build Coastguard Worker
114*6777b538SAndroid Build Coastguard Worker ASSERT_DEATH({ base::win::CheckedScopedHandle handle_holder2(handle); },
115*6777b538SAndroid Build Coastguard Worker FailureMessage("Handle Already Tracked"));
116*6777b538SAndroid Build Coastguard Worker }
117*6777b538SAndroid Build Coastguard Worker
TEST_F(ScopedHandleDeathTest,HandleVerifierWrongOwner)118*6777b538SAndroid Build Coastguard Worker TEST_F(ScopedHandleDeathTest, HandleVerifierWrongOwner) {
119*6777b538SAndroid Build Coastguard Worker HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
120*6777b538SAndroid Build Coastguard Worker ASSERT_NE(HANDLE(nullptr), handle);
121*6777b538SAndroid Build Coastguard Worker
122*6777b538SAndroid Build Coastguard Worker base::win::CheckedScopedHandle handle_holder(handle);
123*6777b538SAndroid Build Coastguard Worker ASSERT_DEATH(
124*6777b538SAndroid Build Coastguard Worker {
125*6777b538SAndroid Build Coastguard Worker base::win::CheckedScopedHandle handle_holder2;
126*6777b538SAndroid Build Coastguard Worker handle_holder2.handle_ = handle;
127*6777b538SAndroid Build Coastguard Worker },
128*6777b538SAndroid Build Coastguard Worker FailureMessage("Closing a handle owned by something else"));
129*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(handle_holder.is_valid());
130*6777b538SAndroid Build Coastguard Worker handle_holder.Close();
131*6777b538SAndroid Build Coastguard Worker }
132*6777b538SAndroid Build Coastguard Worker
TEST_F(ScopedHandleDeathTest,HandleVerifierUntrackedHandle)133*6777b538SAndroid Build Coastguard Worker TEST_F(ScopedHandleDeathTest, HandleVerifierUntrackedHandle) {
134*6777b538SAndroid Build Coastguard Worker HANDLE handle = ::CreateMutex(nullptr, false, nullptr);
135*6777b538SAndroid Build Coastguard Worker ASSERT_NE(HANDLE(nullptr), handle);
136*6777b538SAndroid Build Coastguard Worker
137*6777b538SAndroid Build Coastguard Worker ASSERT_DEATH(
138*6777b538SAndroid Build Coastguard Worker {
139*6777b538SAndroid Build Coastguard Worker base::win::CheckedScopedHandle handle_holder;
140*6777b538SAndroid Build Coastguard Worker handle_holder.handle_ = handle;
141*6777b538SAndroid Build Coastguard Worker },
142*6777b538SAndroid Build Coastguard Worker FailureMessage("Closing an untracked handle"));
143*6777b538SAndroid Build Coastguard Worker
144*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(::CloseHandle(handle));
145*6777b538SAndroid Build Coastguard Worker }
146*6777b538SAndroid Build Coastguard Worker
147*6777b538SAndroid Build Coastguard Worker // Under ASan, the multi-process test crashes during process shutdown for
148*6777b538SAndroid Build Coastguard Worker // unknown reasons. Disable it for now. http://crbug.com/685262
149*6777b538SAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER)
150*6777b538SAndroid Build Coastguard Worker #define MAYBE_MultiProcess DISABLED_MultiProcess
151*6777b538SAndroid Build Coastguard Worker #else
152*6777b538SAndroid Build Coastguard Worker #define MAYBE_MultiProcess MultiProcess
153*6777b538SAndroid Build Coastguard Worker #endif
154*6777b538SAndroid Build Coastguard Worker
TEST_F(ScopedHandleTest,MAYBE_MultiProcess)155*6777b538SAndroid Build Coastguard Worker TEST_F(ScopedHandleTest, MAYBE_MultiProcess) {
156*6777b538SAndroid Build Coastguard Worker CommandLine command_line(base::GetMultiProcessTestChildBaseCommandLine());
157*6777b538SAndroid Build Coastguard Worker
158*6777b538SAndroid Build Coastguard Worker base::Process test_child_process = base::SpawnMultiProcessTestChild(
159*6777b538SAndroid Build Coastguard Worker "HandleVerifierChildProcess", command_line, LaunchOptions());
160*6777b538SAndroid Build Coastguard Worker
161*6777b538SAndroid Build Coastguard Worker int rv = -1;
162*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(test_child_process.WaitForExitWithTimeout(
163*6777b538SAndroid Build Coastguard Worker TestTimeouts::action_timeout(), &rv));
164*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0, rv);
165*6777b538SAndroid Build Coastguard Worker }
166*6777b538SAndroid Build Coastguard Worker
MULTIPROCESS_TEST_MAIN(HandleVerifierChildProcess)167*6777b538SAndroid Build Coastguard Worker MULTIPROCESS_TEST_MAIN(HandleVerifierChildProcess) {
168*6777b538SAndroid Build Coastguard Worker ScopedNativeLibrary module(
169*6777b538SAndroid Build Coastguard Worker FilePath(FILE_PATH_LITERAL("scoped_handle_test_dll.dll")));
170*6777b538SAndroid Build Coastguard Worker
171*6777b538SAndroid Build Coastguard Worker if (!module.is_valid())
172*6777b538SAndroid Build Coastguard Worker return 1;
173*6777b538SAndroid Build Coastguard Worker auto run_test_function = reinterpret_cast<decltype(&testing::RunTest)>(
174*6777b538SAndroid Build Coastguard Worker module.GetFunctionPointer("RunTest"));
175*6777b538SAndroid Build Coastguard Worker if (!run_test_function)
176*6777b538SAndroid Build Coastguard Worker return 1;
177*6777b538SAndroid Build Coastguard Worker if (!run_test_function())
178*6777b538SAndroid Build Coastguard Worker return 1;
179*6777b538SAndroid Build Coastguard Worker
180*6777b538SAndroid Build Coastguard Worker return 0;
181*6777b538SAndroid Build Coastguard Worker }
182*6777b538SAndroid Build Coastguard Worker
183*6777b538SAndroid Build Coastguard Worker } // namespace win
184*6777b538SAndroid Build Coastguard Worker } // namespace base
185