tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

unsafe_shared_memory_region.h (5423B)


      1 // Copyright 2018 The Chromium Authors
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_
      6 #define BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_
      7 
      8 #include "base/base_export.h"
      9 #include "base/check.h"
     10 #include "base/memory/platform_shared_memory_region.h"
     11 #include "base/memory/shared_memory_mapping.h"
     12 
     13 #include <stdint.h>
     14 
     15 namespace base {
     16 
     17 // Scoped move-only handle to a region of platform shared memory. The instance
     18 // owns the platform handle it wraps. Mappings created by this region are
     19 // writable. These mappings remain valid even after the region handle is moved
     20 // or destroyed.
     21 //
     22 // NOTE: UnsafeSharedMemoryRegion cannot be converted to a read-only region. Use
     23 // with caution as the region will be writable to any process with a handle to
     24 // the region.
     25 //
     26 // Use this if and only if the following is true:
     27 // - You do not need to share the region as read-only, and,
     28 // - You need to have several instances of the region simultaneously, possibly
     29 //   in different processes, that can produce writable mappings.
     30 
     31 class BASE_EXPORT UnsafeSharedMemoryRegion {
     32 public:
     33  using MappingType = WritableSharedMemoryMapping;
     34  // Creates a new UnsafeSharedMemoryRegion instance of a given size that can be
     35  // used for mapping writable shared memory into the virtual address space.
     36  static UnsafeSharedMemoryRegion Create(size_t size);
     37  using CreateFunction = decltype(Create);
     38 
     39  // Returns an UnsafeSharedMemoryRegion built from a platform-specific handle
     40  // that was taken from another UnsafeSharedMemoryRegion instance. Returns an
     41  // invalid region iff the |handle| is invalid. CHECK-fails if the |handle|
     42  // isn't unsafe.
     43  // This should be used only by the code passing a handle across
     44  // process boundaries.
     45  static UnsafeSharedMemoryRegion Deserialize(
     46      subtle::PlatformSharedMemoryRegion handle);
     47 
     48  // Extracts a platform handle from the region. Ownership is transferred to the
     49  // returned region object.
     50  // This should be used only for sending the handle from the current
     51  // process to another.
     52  static subtle::PlatformSharedMemoryRegion TakeHandleForSerialization(
     53      UnsafeSharedMemoryRegion region);
     54 
     55  // Default constructor initializes an invalid instance.
     56  UnsafeSharedMemoryRegion();
     57 
     58  // Move operations are allowed.
     59  UnsafeSharedMemoryRegion(UnsafeSharedMemoryRegion&&);
     60  UnsafeSharedMemoryRegion& operator=(UnsafeSharedMemoryRegion&&);
     61 
     62  UnsafeSharedMemoryRegion(const UnsafeSharedMemoryRegion&) = delete;
     63  UnsafeSharedMemoryRegion& operator=(const UnsafeSharedMemoryRegion&) = delete;
     64 
     65  // Destructor closes shared memory region if valid.
     66  // All created mappings will remain valid.
     67  ~UnsafeSharedMemoryRegion();
     68 
     69  // Duplicates the underlying platform handle and creates a new
     70  // UnsafeSharedMemoryRegion instance that owns the newly created handle.
     71  // Returns a valid UnsafeSharedMemoryRegion on success, invalid otherwise.
     72  // The current region instance remains valid in any case.
     73  UnsafeSharedMemoryRegion Duplicate() const;
     74 
     75  // Maps the shared memory region into the caller's address space with write
     76  // access. The mapped address is guaranteed to have an alignment of
     77  // at least |subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment|.
     78  // Returns a valid WritableSharedMemoryMapping instance on success, invalid
     79  // otherwise. A custom |SharedMemoryMapper| for mapping (and later unmapping)
     80  // the region can be provided using the optional |mapper| parameter.
     81  WritableSharedMemoryMapping Map(SharedMemoryMapper* mapper = nullptr) const;
     82 
     83  // Similar to `Map()`, but maps only `size` bytes of the shared memory block
     84  // at byte `offset`. Returns an invalid mapping if requested bytes are out of
     85  // the region limits.
     86  //
     87  // `offset` does not need to be aligned; if `offset` is not a multiple of
     88  // `subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment`, then the
     89  // returned mapping will not respect alignment either. Internally, `offset`
     90  // and `size` are still first adjusted to respect alignment when mapping in
     91  // the shared memory region, but the returned mapping will be "unadjusted" to
     92  // match the exact `offset` and `size` requested.
     93  WritableSharedMemoryMapping MapAt(uint64_t offset,
     94                                    size_t size,
     95                                    SharedMemoryMapper* mapper = nullptr) const;
     96 
     97  // Whether the underlying platform handle is valid.
     98  bool IsValid() const;
     99 
    100  // Returns the maximum mapping size that can be created from this region.
    101  size_t GetSize() const {
    102    DCHECK(IsValid());
    103    return handle_.GetSize();
    104  }
    105 
    106  // Returns 128-bit GUID of the region.
    107  const UnguessableToken& GetGUID() const {
    108    DCHECK(IsValid());
    109    return handle_.GetGUID();
    110  }
    111 
    112  // Returns a platform shared memory handle. |this| remains the owner of the
    113  // handle.
    114  subtle::PlatformSharedMemoryHandle GetPlatformHandle() const {
    115    DCHECK(IsValid());
    116    return handle_.GetPlatformHandle();
    117  }
    118 
    119 private:
    120  friend class SharedMemoryHooks;
    121 
    122  explicit UnsafeSharedMemoryRegion(subtle::PlatformSharedMemoryRegion handle);
    123 
    124  static void set_create_hook(CreateFunction* hook) { create_hook_ = hook; }
    125 
    126  static CreateFunction* create_hook_;
    127 
    128  subtle::PlatformSharedMemoryRegion handle_;
    129 };
    130 
    131 }  // namespace base
    132 
    133 #endif  // BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_