xref: /aosp_15_r20/external/cronet/base/win/scoped_handle_verifier.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2018 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 #ifndef BASE_WIN_SCOPED_HANDLE_VERIFIER_H_
6*6777b538SAndroid Build Coastguard Worker #define BASE_WIN_SCOPED_HANDLE_VERIFIER_H_
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include <memory>
9*6777b538SAndroid Build Coastguard Worker #include <unordered_map>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "base/base_export.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/debug/stack_trace.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/hash/hash.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/lock_impl.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/win/windows_types.h"
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker namespace base {
19*6777b538SAndroid Build Coastguard Worker namespace win {
20*6777b538SAndroid Build Coastguard Worker enum class HandleOperation;
21*6777b538SAndroid Build Coastguard Worker namespace internal {
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker struct HandleHash {
operatorHandleHash24*6777b538SAndroid Build Coastguard Worker   size_t operator()(const HANDLE& handle) const {
25*6777b538SAndroid Build Coastguard Worker     return base::FastHash(as_bytes(make_span(&handle, 1u)));
26*6777b538SAndroid Build Coastguard Worker   }
27*6777b538SAndroid Build Coastguard Worker };
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker struct ScopedHandleVerifierInfo {
30*6777b538SAndroid Build Coastguard Worker   ScopedHandleVerifierInfo(const void* owner,
31*6777b538SAndroid Build Coastguard Worker                            const void* pc1,
32*6777b538SAndroid Build Coastguard Worker                            const void* pc2,
33*6777b538SAndroid Build Coastguard Worker                            std::unique_ptr<debug::StackTrace> stack,
34*6777b538SAndroid Build Coastguard Worker                            DWORD thread_id);
35*6777b538SAndroid Build Coastguard Worker   ~ScopedHandleVerifierInfo();
36*6777b538SAndroid Build Coastguard Worker 
37*6777b538SAndroid Build Coastguard Worker   ScopedHandleVerifierInfo(const ScopedHandleVerifierInfo&) = delete;
38*6777b538SAndroid Build Coastguard Worker   ScopedHandleVerifierInfo& operator=(const ScopedHandleVerifierInfo&) = delete;
39*6777b538SAndroid Build Coastguard Worker   ScopedHandleVerifierInfo(ScopedHandleVerifierInfo&&) noexcept;
40*6777b538SAndroid Build Coastguard Worker   ScopedHandleVerifierInfo& operator=(ScopedHandleVerifierInfo&&) noexcept;
41*6777b538SAndroid Build Coastguard Worker 
42*6777b538SAndroid Build Coastguard Worker   raw_ptr<const void> owner;
43*6777b538SAndroid Build Coastguard Worker   raw_ptr<const void> pc1;
44*6777b538SAndroid Build Coastguard Worker   raw_ptr<const void> pc2;
45*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<debug::StackTrace> stack;
46*6777b538SAndroid Build Coastguard Worker   DWORD thread_id;
47*6777b538SAndroid Build Coastguard Worker };
48*6777b538SAndroid Build Coastguard Worker 
49*6777b538SAndroid Build Coastguard Worker // Implements the actual object that is verifying handles for this process.
50*6777b538SAndroid Build Coastguard Worker // The active instance is shared across the module boundary but there is no
51*6777b538SAndroid Build Coastguard Worker // way to delete this object from the wrong side of it (or any side, actually).
52*6777b538SAndroid Build Coastguard Worker // We need [[clang::lto_visibility_public]] because instances of this class are
53*6777b538SAndroid Build Coastguard Worker // passed across module boundaries. This means different modules must have
54*6777b538SAndroid Build Coastguard Worker // compatible definitions of the class even when whole program optimization is
55*6777b538SAndroid Build Coastguard Worker // enabled - which is what this attribute accomplishes. The pragma stops MSVC
56*6777b538SAndroid Build Coastguard Worker // from emitting an unrecognized attribute warning.
57*6777b538SAndroid Build Coastguard Worker #pragma warning(push)
58*6777b538SAndroid Build Coastguard Worker #pragma warning(disable : 5030)
59*6777b538SAndroid Build Coastguard Worker class [[clang::lto_visibility_public, nodiscard]] ScopedHandleVerifier {
60*6777b538SAndroid Build Coastguard Worker #pragma warning(pop)
61*6777b538SAndroid Build Coastguard Worker  public:
62*6777b538SAndroid Build Coastguard Worker   ScopedHandleVerifier(const ScopedHandleVerifier&) = delete;
63*6777b538SAndroid Build Coastguard Worker   ScopedHandleVerifier& operator=(const ScopedHandleVerifier&) = delete;
64*6777b538SAndroid Build Coastguard Worker 
65*6777b538SAndroid Build Coastguard Worker   // Retrieves the current verifier.
66*6777b538SAndroid Build Coastguard Worker   static ScopedHandleVerifier* Get();
67*6777b538SAndroid Build Coastguard Worker 
68*6777b538SAndroid Build Coastguard Worker   // The methods required by HandleTraits. They are virtual because we need to
69*6777b538SAndroid Build Coastguard Worker   // forward the call execution to another module, instead of letting the
70*6777b538SAndroid Build Coastguard Worker   // compiler call the version that is linked in the current module.
71*6777b538SAndroid Build Coastguard Worker   virtual bool CloseHandle(HANDLE handle);
72*6777b538SAndroid Build Coastguard Worker   virtual void StartTracking(HANDLE handle, const void* owner, const void* pc1,
73*6777b538SAndroid Build Coastguard Worker                              const void* pc2);
74*6777b538SAndroid Build Coastguard Worker   virtual void StopTracking(HANDLE handle, const void* owner, const void* pc1,
75*6777b538SAndroid Build Coastguard Worker                             const void* pc2);
76*6777b538SAndroid Build Coastguard Worker   virtual void Disable();
77*6777b538SAndroid Build Coastguard Worker   virtual void OnHandleBeingClosed(HANDLE handle, HandleOperation operation);
78*6777b538SAndroid Build Coastguard Worker   virtual HMODULE GetModule() const;
79*6777b538SAndroid Build Coastguard Worker 
80*6777b538SAndroid Build Coastguard Worker  private:
81*6777b538SAndroid Build Coastguard Worker   explicit ScopedHandleVerifier(bool enabled);
82*6777b538SAndroid Build Coastguard Worker   ~ScopedHandleVerifier();  // Not implemented.
83*6777b538SAndroid Build Coastguard Worker 
84*6777b538SAndroid Build Coastguard Worker   void StartTrackingImpl(HANDLE handle, const void* owner, const void* pc1,
85*6777b538SAndroid Build Coastguard Worker                          const void* pc2);
86*6777b538SAndroid Build Coastguard Worker   void StopTrackingImpl(HANDLE handle, const void* owner, const void* pc1,
87*6777b538SAndroid Build Coastguard Worker                         const void* pc2);
88*6777b538SAndroid Build Coastguard Worker   void OnHandleBeingClosedImpl(HANDLE handle, HandleOperation operation);
89*6777b538SAndroid Build Coastguard Worker 
90*6777b538SAndroid Build Coastguard Worker   static base::internal::LockImpl* GetLock();
91*6777b538SAndroid Build Coastguard Worker   static void InstallVerifier();
92*6777b538SAndroid Build Coastguard Worker   static void ThreadSafeAssignOrCreateScopedHandleVerifier(
93*6777b538SAndroid Build Coastguard Worker       ScopedHandleVerifier * existing_verifier, bool enabled);
94*6777b538SAndroid Build Coastguard Worker 
95*6777b538SAndroid Build Coastguard Worker   base::debug::StackTrace creation_stack_;
96*6777b538SAndroid Build Coastguard Worker   bool enabled_;
97*6777b538SAndroid Build Coastguard Worker   raw_ptr<base::internal::LockImpl> lock_;
98*6777b538SAndroid Build Coastguard Worker   std::unordered_map<HANDLE, ScopedHandleVerifierInfo, HandleHash> map_;
99*6777b538SAndroid Build Coastguard Worker };
100*6777b538SAndroid Build Coastguard Worker 
101*6777b538SAndroid Build Coastguard Worker // This testing function returns the module that the HandleVerifier concrete
102*6777b538SAndroid Build Coastguard Worker // implementation was instantiated in.
103*6777b538SAndroid Build Coastguard Worker BASE_EXPORT HMODULE GetHandleVerifierModuleForTesting();
104*6777b538SAndroid Build Coastguard Worker 
105*6777b538SAndroid Build Coastguard Worker }  // namespace internal
106*6777b538SAndroid Build Coastguard Worker }  // namespace win
107*6777b538SAndroid Build Coastguard Worker }  // namespace base
108*6777b538SAndroid Build Coastguard Worker 
109*6777b538SAndroid Build Coastguard Worker #endif  // BASE_WIN_SCOPED_HANDLE_VERIFIER_H_
110