1 // Copyright (c) 2012 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 "base/win/scoped_handle.h"
7 #include <unordered_map>
9 #include "base/debug/alias.h"
10 #include "base/hash.h"
11 #include "base/lazy_instance.h"
12 #include "base/logging.h"
13 #include "base/synchronization/lock_impl.h"
16 __declspec(dllexport
) void* GetHandleVerifier();
17 typedef void* (*GetHandleVerifierFn
)();
23 size_t operator()(const HANDLE
& handle
) const {
24 char buffer
[sizeof(handle
)];
25 memcpy(buffer
, &handle
, sizeof(handle
));
26 return base::Hash(buffer
, sizeof(buffer
));
36 typedef std::unordered_map
<HANDLE
, Info
, HandleHash
> HandleMap
;
38 // g_lock protects the handle map and setting g_active_verifier.
39 typedef base::internal::LockImpl NativeLock
;
40 base::LazyInstance
<NativeLock
>::Leaky g_lock
= LAZY_INSTANCE_INITIALIZER
;
42 bool CloseHandleWrapper(HANDLE handle
) {
43 if (!::CloseHandle(handle
))
48 // Simple automatic locking using a native critical section so it supports
50 class AutoNativeLock
{
52 explicit AutoNativeLock(NativeLock
& lock
) : lock_(lock
) {
62 DISALLOW_COPY_AND_ASSIGN(AutoNativeLock
);
65 // Implements the actual object that is verifying handles for this process.
66 // The active instance is shared across the module boundary but there is no
67 // way to delete this object from the wrong side of it (or any side, actually).
68 class ActiveVerifier
{
70 explicit ActiveVerifier(bool enabled
)
71 : enabled_(enabled
), closing_(false), lock_(g_lock
.Pointer()) {
74 // Retrieves the current verifier.
75 static ActiveVerifier
* Get();
77 // The methods required by HandleTraits. They are virtual because we need to
78 // forward the call execution to another module, instead of letting the
79 // compiler call the version that is linked in the current module.
80 virtual bool CloseHandle(HANDLE handle
);
81 virtual void StartTracking(HANDLE handle
, const void* owner
,
82 const void* pc1
, const void* pc2
);
83 virtual void StopTracking(HANDLE handle
, const void* owner
,
84 const void* pc1
, const void* pc2
);
85 virtual void Disable();
86 virtual void OnHandleBeingClosed(HANDLE handle
);
89 ~ActiveVerifier(); // Not implemented.
91 static void InstallVerifier();
97 DISALLOW_COPY_AND_ASSIGN(ActiveVerifier
);
99 ActiveVerifier
* g_active_verifier
= NULL
;
102 ActiveVerifier
* ActiveVerifier::Get() {
103 if (!g_active_verifier
)
104 ActiveVerifier::InstallVerifier();
106 return g_active_verifier
;
110 void ActiveVerifier::InstallVerifier() {
111 #if defined(COMPONENT_BUILD)
112 AutoNativeLock
lock(g_lock
.Get());
113 g_active_verifier
= new ActiveVerifier(true);
115 // If you are reading this, wondering why your process seems deadlocked, take
116 // a look at your DllMain code and remove things that should not be done
117 // there, like doing whatever gave you that nice windows handle you are trying
118 // to store in a ScopedHandle.
119 HMODULE main_module
= ::GetModuleHandle(NULL
);
120 GetHandleVerifierFn get_handle_verifier
=
121 reinterpret_cast<GetHandleVerifierFn
>(::GetProcAddress(
122 main_module
, "GetHandleVerifier"));
124 if (!get_handle_verifier
) {
125 g_active_verifier
= new ActiveVerifier(false);
129 ActiveVerifier
* verifier
=
130 reinterpret_cast<ActiveVerifier
*>(get_handle_verifier());
132 // This lock only protects against races in this module, which is fine.
133 AutoNativeLock
lock(g_lock
.Get());
134 g_active_verifier
= verifier
? verifier
: new ActiveVerifier(true);
138 bool ActiveVerifier::CloseHandle(HANDLE handle
) {
140 return CloseHandleWrapper(handle
);
142 AutoNativeLock
lock(*lock_
);
144 CloseHandleWrapper(handle
);
150 void ActiveVerifier::StartTracking(HANDLE handle
, const void* owner
,
151 const void* pc1
, const void* pc2
) {
155 // Idea here is to make our handles non-closable until we close it ourselves.
156 // Handles provided could be totally fabricated especially through our
157 // unittest, we are ignoring that for now by not checking return value.
158 ::SetHandleInformation(handle
, HANDLE_FLAG_PROTECT_FROM_CLOSE
,
159 HANDLE_FLAG_PROTECT_FROM_CLOSE
);
161 // Grab the thread id before the lock.
162 DWORD thread_id
= GetCurrentThreadId();
164 AutoNativeLock
lock(*lock_
);
166 Info handle_info
= { owner
, pc1
, pc2
, thread_id
};
167 std::pair
<HANDLE
, Info
> item(handle
, handle_info
);
168 std::pair
<HandleMap::iterator
, bool> result
= map_
.insert(item
);
169 if (!result
.second
) {
170 Info other
= result
.first
->second
;
171 base::debug::Alias(&other
);
176 void ActiveVerifier::StopTracking(HANDLE handle
, const void* owner
,
177 const void* pc1
, const void* pc2
) {
181 // We expect handle to be protected till this point.
183 if (::GetHandleInformation(handle
, &flags
)) {
184 CHECK_NE(0U, (flags
& HANDLE_FLAG_PROTECT_FROM_CLOSE
));
186 // Unprotect handle so that it could be closed.
187 ::SetHandleInformation(handle
, HANDLE_FLAG_PROTECT_FROM_CLOSE
, 0);
190 AutoNativeLock
lock(*lock_
);
191 HandleMap::iterator i
= map_
.find(handle
);
195 Info other
= i
->second
;
196 if (other
.owner
!= owner
) {
197 base::debug::Alias(&other
);
204 void ActiveVerifier::Disable() {
208 void ActiveVerifier::OnHandleBeingClosed(HANDLE handle
) {
209 AutoNativeLock
lock(*lock_
);
213 HandleMap::iterator i
= map_
.find(handle
);
217 Info other
= i
->second
;
218 base::debug::Alias(&other
);
224 void* GetHandleVerifier() {
225 return g_active_verifier
;
232 bool HandleTraits::CloseHandle(HANDLE handle
) {
233 return ActiveVerifier::Get()->CloseHandle(handle
);
237 void VerifierTraits::StartTracking(HANDLE handle
, const void* owner
,
238 const void* pc1
, const void* pc2
) {
239 return ActiveVerifier::Get()->StartTracking(handle
, owner
, pc1
, pc2
);
243 void VerifierTraits::StopTracking(HANDLE handle
, const void* owner
,
244 const void* pc1
, const void* pc2
) {
245 return ActiveVerifier::Get()->StopTracking(handle
, owner
, pc1
, pc2
);
248 void DisableHandleVerifier() {
249 return ActiveVerifier::Get()->Disable();
252 void OnHandleBeingClosed(HANDLE handle
) {
253 return ActiveVerifier::Get()->OnHandleBeingClosed(handle
);