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