• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
5 #ifndef BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_
6 #define BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_
7 
8 #include "base/gtest_prod_util.h"
9 #include "base/macros.h"
10 #include "base/memory/platform_shared_memory_region.h"
11 #include "base/memory/shared_memory_mapping.h"
12 
13 namespace base {
14 
15 // Scoped move-only handle to a region of platform shared memory. The instance
16 // owns the platform handle it wraps. Mappings created by this region are
17 // writable. These mappings remain valid even after the region handle is moved
18 // or destroyed.
19 //
20 // NOTE: UnsafeSharedMemoryRegion cannot be converted to a read-only region. Use
21 // with caution as the region will be writable to any process with a handle to
22 // the region.
23 //
24 // Use this if and only if the following is true:
25 // - You do not need to share the region as read-only, and,
26 // - You need to have several instances of the region simultaneously, possibly
27 //   in different processes, that can produce writable mappings.
28 
29 class BASE_EXPORT UnsafeSharedMemoryRegion {
30  public:
31   using MappingType = WritableSharedMemoryMapping;
32   // Creates a new UnsafeSharedMemoryRegion instance of a given size that can be
33   // used for mapping writable shared memory into the virtual address space.
34   static UnsafeSharedMemoryRegion Create(size_t size);
35 
36   // Returns an UnsafeSharedMemoryRegion built from a platform-specific handle
37   // that was taken from another UnsafeSharedMemoryRegion instance. Returns an
38   // invalid region iff the |handle| is invalid. CHECK-fails if the |handle|
39   // isn't unsafe.
40   // This should be used only by the code passing a handle across
41   // process boundaries.
42   static UnsafeSharedMemoryRegion Deserialize(
43       subtle::PlatformSharedMemoryRegion handle);
44 
45   // Extracts a platform handle from the region. Ownership is transferred to the
46   // returned region object.
47   // This should be used only for sending the handle from the current
48   // process to another.
49   static subtle::PlatformSharedMemoryRegion TakeHandleForSerialization(
50       UnsafeSharedMemoryRegion region);
51 
52   // Default constructor initializes an invalid instance.
53   UnsafeSharedMemoryRegion();
54 
55   // Move operations are allowed.
56   UnsafeSharedMemoryRegion(UnsafeSharedMemoryRegion&&);
57   UnsafeSharedMemoryRegion& operator=(UnsafeSharedMemoryRegion&&);
58 
59   // Destructor closes shared memory region if valid.
60   // All created mappings will remain valid.
61   ~UnsafeSharedMemoryRegion();
62 
63   // Duplicates the underlying platform handle and creates a new
64   // UnsafeSharedMemoryRegion instance that owns the newly created handle.
65   // Returns a valid UnsafeSharedMemoryRegion on success, invalid otherwise.
66   // The current region instance remains valid in any case.
67   UnsafeSharedMemoryRegion Duplicate() const;
68 
69   // Maps the shared memory region into the caller's address space with write
70   // access. The mapped address is guaranteed to have an alignment of
71   // at least |subtle::PlatformSharedMemoryRegion::kMapMinimumAlignment|.
72   // Returns a valid WritableSharedMemoryMapping instance on success, invalid
73   // otherwise.
74   WritableSharedMemoryMapping Map() const;
75 
76   // Same as above, but maps only |size| bytes of the shared memory region
77   // starting with the given |offset|. |offset| must be aligned to value of
78   // |SysInfo::VMAllocationGranularity()|. Returns an invalid mapping if
79   // requested bytes are out of the region limits.
80   WritableSharedMemoryMapping MapAt(off_t offset, size_t size) const;
81 
82   // Whether the underlying platform handle is valid.
83   bool IsValid() const;
84 
85   // Returns the maximum mapping size that can be created from this region.
GetSize()86   size_t GetSize() const {
87     DCHECK(IsValid());
88     return handle_.GetSize();
89   }
90 
91   // Returns 128-bit GUID of the region.
GetGUID()92   const UnguessableToken& GetGUID() const {
93     DCHECK(IsValid());
94     return handle_.GetGUID();
95   }
96 
97  private:
98   FRIEND_TEST_ALL_PREFIXES(DiscardableSharedMemoryTest,
99                            LockShouldFailIfPlatformLockPagesFails);
100   friend class DiscardableSharedMemory;
101 
102   explicit UnsafeSharedMemoryRegion(subtle::PlatformSharedMemoryRegion handle);
103 
104   // Returns a platform shared memory handle. |this| remains the owner of the
105   // handle.
GetPlatformHandle()106   subtle::PlatformSharedMemoryRegion::PlatformHandle GetPlatformHandle() const {
107     DCHECK(IsValid());
108     return handle_.GetPlatformHandle();
109   }
110 
111   subtle::PlatformSharedMemoryRegion handle_;
112 
113   DISALLOW_COPY_AND_ASSIGN(UnsafeSharedMemoryRegion);
114 };
115 
116 }  // namespace base
117 
118 #endif  // BASE_MEMORY_UNSAFE_SHARED_MEMORY_REGION_H_
119