security/sandbox/chromium/base/win/scoped_handle.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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 #ifndef BASE_WIN_SCOPED_HANDLE_H_
     6 #define BASE_WIN_SCOPED_HANDLE_H_
     8 #include <windows.h>
    10 #include "base/base_export.h"
    11 #include "base/basictypes.h"
    12 #include "base/location.h"
    13 #include "base/logging.h"
    14 #include "base/move.h"
    16 namespace base {
    17 namespace win {
    19 // TODO(rvargas): remove this with the rest of the verifier.
    20 #if defined(COMPILER_MSVC)
    21 // MSDN says to #include <intrin.h>, but that breaks the VS2005 build.
    22 extern "C" {
    23   void* _ReturnAddress();
    24 }
    25 #define BASE_WIN_GET_CALLER _ReturnAddress()
    26 #elif defined(COMPILER_GCC)
    27 #define BASE_WIN_GET_CALLER __builtin_extract_return_addr(\\
    28     __builtin_return_address(0))
    29 #endif
    31 // Generic wrapper for raw handles that takes care of closing handles
    32 // automatically. The class interface follows the style of
    33 // the ScopedStdioHandle class with a few additions:
    34 //   - IsValid() method can tolerate multiple invalid handle values such as NULL
    35 //     and INVALID_HANDLE_VALUE (-1) for Win32 handles.
    36 //   - Receive() method allows to receive a handle value from a function that
    37 //     takes a raw handle pointer only.
    38 template <class Traits, class Verifier>
    39 class GenericScopedHandle {
    40   MOVE_ONLY_TYPE_FOR_CPP_03(GenericScopedHandle, RValue)
    42  public:
    43   typedef typename Traits::Handle Handle;
    45   // Helper object to contain the effect of Receive() to the function that needs
    46   // a pointer, and allow proper tracking of the handle.
    47   class Receiver {
    48    public:
    49     explicit Receiver(GenericScopedHandle* owner)
    50         : handle_(Traits::NullHandle()),
    51           owner_(owner) {}
    52     ~Receiver() { owner_->Set(handle_); }
    54     operator Handle*() { return &handle_; }
    56    private:
    57     Handle handle_;
    58     GenericScopedHandle* owner_;
    59   };
    61   GenericScopedHandle() : handle_(Traits::NullHandle()) {}
    63   explicit GenericScopedHandle(Handle handle) : handle_(Traits::NullHandle()) {
    64     Set(handle);
    65   }
    67   // Move constructor for C++03 move emulation of this type.
    68   GenericScopedHandle(RValue other) : handle_(Traits::NullHandle()) {
    69     Set(other.object->Take());
    70   }
    72   ~GenericScopedHandle() {
    73     Close();
    74   }
    76   bool IsValid() const {
    77     return Traits::IsHandleValid(handle_);
    78   }
    80   // Move operator= for C++03 move emulation of this type.
    81   GenericScopedHandle& operator=(RValue other) {
    82     if (this != other.object) {
    83       Set(other.object->Take());
    84     }
    85     return *this;
    86   }
    88   void Set(Handle handle) {
    89     if (handle_ != handle) {
    90       Close();
    92       if (Traits::IsHandleValid(handle)) {
    93         handle_ = handle;
    94         Verifier::StartTracking(handle, this, BASE_WIN_GET_CALLER,
    95                                 tracked_objects::GetProgramCounter());
    96       }
    97     }
    98   }
   100   Handle Get() const {
   101     return handle_;
   102   }
   104   operator Handle() const {
   105     return handle_;
   106   }
   108   // This method is intended to be used with functions that require a pointer to
   109   // a destination handle, like so:
   110   //    void CreateRequiredHandle(Handle* out_handle);
   111   //    ScopedHandle a;
   112   //    CreateRequiredHandle(a.Receive());
   113   Receiver Receive() {
   114     DCHECK(!Traits::IsHandleValid(handle_)) << "Handle must be NULL";
   115     return Receiver(this);
   116   }
   118   // Transfers ownership away from this object.
   119   Handle Take() {
   120     Handle temp = handle_;
   121     handle_ = Traits::NullHandle();
   122     if (Traits::IsHandleValid(temp)) {
   123       Verifier::StopTracking(temp, this, BASE_WIN_GET_CALLER,
   124                              tracked_objects::GetProgramCounter());
   125     }
   126     return temp;
   127   }
   129   // Explicitly closes the owned handle.
   130   void Close() {
   131     if (Traits::IsHandleValid(handle_)) {
   132       Verifier::StopTracking(handle_, this, BASE_WIN_GET_CALLER,
   133                              tracked_objects::GetProgramCounter());
   135       if (!Traits::CloseHandle(handle_))
   136         CHECK(false);
   138       handle_ = Traits::NullHandle();
   139     }
   140   }
   142  private:
   143   Handle handle_;
   144 };
   146 #undef BASE_WIN_GET_CALLER
   148 // The traits class for Win32 handles that can be closed via CloseHandle() API.
   149 class HandleTraits {
   150  public:
   151   typedef HANDLE Handle;
   153   // Closes the handle.
   154   static bool CloseHandle(HANDLE handle) {
   155     return ::CloseHandle(handle) != FALSE;
   156   }
   158   // Returns true if the handle value is valid.
   159   static bool IsHandleValid(HANDLE handle) {
   160     return handle != NULL && handle != INVALID_HANDLE_VALUE;
   161   }
   163   // Returns NULL handle value.
   164   static HANDLE NullHandle() {
   165     return NULL;
   166   }
   168  private:
   169   DISALLOW_IMPLICIT_CONSTRUCTORS(HandleTraits);
   170 };
   172 // Do-nothing verifier.
   173 class DummyVerifierTraits {
   174  public:
   175   typedef HANDLE Handle;
   177   static void StartTracking(HANDLE handle, const void* owner,
   178                             const void* pc1, const void* pc2) {}
   179   static void StopTracking(HANDLE handle, const void* owner,
   180                            const void* pc1, const void* pc2) {}
   182  private:
   183   DISALLOW_IMPLICIT_CONSTRUCTORS(DummyVerifierTraits);
   184 };
   186 // Performs actual run-time tracking.
   187 class BASE_EXPORT VerifierTraits {
   188  public:
   189   typedef HANDLE Handle;
   191   static void StartTracking(HANDLE handle, const void* owner,
   192                             const void* pc1, const void* pc2);
   193   static void StopTracking(HANDLE handle, const void* owner,
   194                            const void* pc1, const void* pc2);
   196  private:
   197   DISALLOW_IMPLICIT_CONSTRUCTORS(VerifierTraits);
   198 };
   200 typedef GenericScopedHandle<HandleTraits, VerifierTraits> ScopedHandle;
   202 }  // namespace win
   203 }  // namespace base
   205 #endif  // BASE_SCOPED_HANDLE_WIN_H_

mercurial