scoped_handle_verifier.cc 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. // Copyright 2018 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.
  4. #include "base/win/scoped_handle_verifier.h"
  5. #include <windows.h>
  6. #include <stddef.h>
  7. #include <unordered_map>
  8. #include <utility>
  9. #include "base/compiler_specific.h"
  10. #include "base/debug/alias.h"
  11. #include "base/debug/stack_trace.h"
  12. #include "base/synchronization/lock_impl.h"
  13. #include "base/trace_event/base_tracing.h"
  14. #include "base/win/base_win_buildflags.h"
  15. #include "base/win/current_module.h"
  16. #include "base/win/scoped_handle.h"
  17. extern "C" {
  18. __declspec(dllexport) void* GetHandleVerifier();
  19. void* GetHandleVerifier() {
  20. return base::win::internal::ScopedHandleVerifier::Get();
  21. }
  22. } // extern C
  23. namespace base {
  24. namespace win {
  25. namespace internal {
  26. namespace {
  27. ScopedHandleVerifier* g_active_verifier = nullptr;
  28. using GetHandleVerifierFn = void* (*)();
  29. using HandleMap =
  30. std::unordered_map<HANDLE, ScopedHandleVerifierInfo, HandleHash>;
  31. using NativeLock = base::internal::LockImpl;
  32. NOINLINE void ReportErrorOnScopedHandleOperation(
  33. const base::debug::StackTrace& creation_stack,
  34. HandleOperation operation) {
  35. auto creation_stack_copy = creation_stack;
  36. base::debug::Alias(&creation_stack_copy);
  37. base::debug::Alias(&operation);
  38. CHECK(false) << operation;
  39. __builtin_unreachable();
  40. }
  41. NOINLINE void ReportErrorOnScopedHandleOperation(
  42. const base::debug::StackTrace& creation_stack,
  43. const ScopedHandleVerifierInfo& other,
  44. HandleOperation operation) {
  45. auto other_stack_copy = *other.stack;
  46. base::debug::Alias(&other_stack_copy);
  47. auto creation_stack_copy = creation_stack;
  48. base::debug::Alias(&creation_stack_copy);
  49. base::debug::Alias(&operation);
  50. CHECK(false) << operation;
  51. __builtin_unreachable();
  52. }
  53. } // namespace
  54. // Simple automatic locking using a native critical section so it supports
  55. // recursive locking.
  56. class AutoNativeLock {
  57. public:
  58. explicit AutoNativeLock(NativeLock& lock) : lock_(lock) { lock_.Lock(); }
  59. AutoNativeLock(const AutoNativeLock&) = delete;
  60. AutoNativeLock& operator=(const AutoNativeLock&) = delete;
  61. ~AutoNativeLock() { lock_.Unlock(); }
  62. private:
  63. NativeLock& lock_;
  64. };
  65. ScopedHandleVerifierInfo::ScopedHandleVerifierInfo(
  66. const void* owner,
  67. const void* pc1,
  68. const void* pc2,
  69. std::unique_ptr<debug::StackTrace> stack,
  70. DWORD thread_id)
  71. : owner(owner),
  72. pc1(pc1),
  73. pc2(pc2),
  74. stack(std::move(stack)),
  75. thread_id(thread_id) {}
  76. ScopedHandleVerifierInfo::~ScopedHandleVerifierInfo() = default;
  77. ScopedHandleVerifierInfo::ScopedHandleVerifierInfo(
  78. ScopedHandleVerifierInfo&&) noexcept = default;
  79. ScopedHandleVerifierInfo& ScopedHandleVerifierInfo::operator=(
  80. ScopedHandleVerifierInfo&&) noexcept = default;
  81. ScopedHandleVerifier::ScopedHandleVerifier(bool enabled)
  82. : enabled_(enabled), lock_(GetLock()) {}
  83. // static
  84. ScopedHandleVerifier* ScopedHandleVerifier::Get() {
  85. if (!g_active_verifier)
  86. ScopedHandleVerifier::InstallVerifier();
  87. return g_active_verifier;
  88. }
  89. bool CloseHandleWrapper(HANDLE handle) {
  90. if (!::CloseHandle(handle))
  91. CHECK(false) << "CloseHandle failed";
  92. return true;
  93. }
  94. // Assigns the g_active_verifier global within the ScopedHandleVerifier lock.
  95. // If |existing_verifier| is non-null then |enabled| is ignored.
  96. // static
  97. void ScopedHandleVerifier::ThreadSafeAssignOrCreateScopedHandleVerifier(
  98. ScopedHandleVerifier* existing_verifier,
  99. bool enabled) {
  100. AutoNativeLock lock(*GetLock());
  101. // Another thread in this module might be trying to assign the global
  102. // verifier, so check that within the lock here.
  103. if (g_active_verifier)
  104. return;
  105. g_active_verifier =
  106. existing_verifier ? existing_verifier : new ScopedHandleVerifier(enabled);
  107. }
  108. // static
  109. void ScopedHandleVerifier::InstallVerifier() {
  110. #if BUILDFLAG(SINGLE_MODULE_MODE_HANDLE_VERIFIER)
  111. // Component build has one Active Verifier per module.
  112. ThreadSafeAssignOrCreateScopedHandleVerifier(nullptr, true);
  113. #else
  114. // If you are reading this, wondering why your process seems deadlocked, take
  115. // a look at your DllMain code and remove things that should not be done
  116. // there, like doing whatever gave you that nice windows handle you are trying
  117. // to store in a ScopedHandle.
  118. HMODULE main_module = ::GetModuleHandle(NULL);
  119. GetHandleVerifierFn get_handle_verifier =
  120. reinterpret_cast<GetHandleVerifierFn>(
  121. ::GetProcAddress(main_module, "GetHandleVerifier"));
  122. // This should only happen if running in a DLL is linked with base but the
  123. // hosting EXE is not. In this case, create a ScopedHandleVerifier for the
  124. // current module but leave it disabled.
  125. if (!get_handle_verifier) {
  126. ThreadSafeAssignOrCreateScopedHandleVerifier(nullptr, false);
  127. return;
  128. }
  129. // Check if in the main module.
  130. if (get_handle_verifier == GetHandleVerifier) {
  131. ThreadSafeAssignOrCreateScopedHandleVerifier(nullptr, true);
  132. return;
  133. }
  134. ScopedHandleVerifier* main_module_verifier =
  135. reinterpret_cast<ScopedHandleVerifier*>(get_handle_verifier());
  136. // Main module should always on-demand create a verifier.
  137. DCHECK(main_module_verifier);
  138. ThreadSafeAssignOrCreateScopedHandleVerifier(main_module_verifier, false);
  139. #endif
  140. }
  141. bool ScopedHandleVerifier::CloseHandle(HANDLE handle) {
  142. if (!enabled_)
  143. return CloseHandleWrapper(handle);
  144. closing_.Set(true);
  145. CloseHandleWrapper(handle);
  146. closing_.Set(false);
  147. return true;
  148. }
  149. // static
  150. NativeLock* ScopedHandleVerifier::GetLock() {
  151. static auto* native_lock = new NativeLock();
  152. return native_lock;
  153. }
  154. void ScopedHandleVerifier::StartTracking(HANDLE handle,
  155. const void* owner,
  156. const void* pc1,
  157. const void* pc2) {
  158. if (enabled_)
  159. StartTrackingImpl(handle, owner, pc1, pc2);
  160. }
  161. void ScopedHandleVerifier::StopTracking(HANDLE handle,
  162. const void* owner,
  163. const void* pc1,
  164. const void* pc2) {
  165. if (enabled_)
  166. StopTrackingImpl(handle, owner, pc1, pc2);
  167. }
  168. void ScopedHandleVerifier::Disable() {
  169. enabled_ = false;
  170. }
  171. void ScopedHandleVerifier::OnHandleBeingClosed(HANDLE handle,
  172. HandleOperation operation) {
  173. if (enabled_)
  174. OnHandleBeingClosedImpl(handle, operation);
  175. }
  176. HMODULE ScopedHandleVerifier::GetModule() const {
  177. return CURRENT_MODULE();
  178. }
  179. NOINLINE void ScopedHandleVerifier::StartTrackingImpl(HANDLE handle,
  180. const void* owner,
  181. const void* pc1,
  182. const void* pc2) {
  183. // Grab the thread id before the lock.
  184. DWORD thread_id = GetCurrentThreadId();
  185. // Grab the thread stacktrace before the lock.
  186. auto stacktrace = std::make_unique<debug::StackTrace>();
  187. AutoNativeLock lock(*lock_);
  188. std::pair<HandleMap::iterator, bool> result = map_.emplace(
  189. handle, ScopedHandleVerifierInfo{owner, pc1, pc2, std::move(stacktrace),
  190. thread_id});
  191. if (!result.second) {
  192. // Attempt to start tracking already tracked handle.
  193. ReportErrorOnScopedHandleOperation(creation_stack_, result.first->second,
  194. HandleOperation::kHandleAlreadyTracked);
  195. }
  196. }
  197. NOINLINE void ScopedHandleVerifier::StopTrackingImpl(HANDLE handle,
  198. const void* owner,
  199. const void* pc1,
  200. const void* pc2) {
  201. AutoNativeLock lock(*lock_);
  202. HandleMap::iterator i = map_.find(handle);
  203. if (i == map_.end()) {
  204. // Attempting to close an untracked handle.
  205. ReportErrorOnScopedHandleOperation(creation_stack_,
  206. HandleOperation::kCloseHandleNotTracked);
  207. }
  208. if (i->second.owner != owner) {
  209. // Attempting to close a handle not owned by opener.
  210. ReportErrorOnScopedHandleOperation(creation_stack_, i->second,
  211. HandleOperation::kCloseHandleNotOwner);
  212. }
  213. map_.erase(i);
  214. }
  215. NOINLINE void ScopedHandleVerifier::OnHandleBeingClosedImpl(
  216. HANDLE handle,
  217. HandleOperation operation) {
  218. if (closing_.Get())
  219. return;
  220. AutoNativeLock lock(*lock_);
  221. HandleMap::iterator i = map_.find(handle);
  222. if (i != map_.end()) {
  223. // CloseHandle called on tracked handle.
  224. ReportErrorOnScopedHandleOperation(creation_stack_, i->second, operation);
  225. }
  226. }
  227. HMODULE GetHandleVerifierModuleForTesting() {
  228. return g_active_verifier->GetModule();
  229. }
  230. } // namespace internal
  231. } // namespace win
  232. } // namespace base