Bug 1839315: part 4) Link from `SheetLoadData::mWasAlternate` to spec. r=emilio DONTBUILD
[gecko.git] / ipc / chromium / src / base / shared_memory.h
blob773557733496edacb00f5f5b345d4205b3d0c733
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style license that can be
5 // found in the LICENSE file.
7 #ifndef BASE_SHARED_MEMORY_H_
8 #define BASE_SHARED_MEMORY_H_
10 #if defined(XP_UNIX)
11 # include <sys/types.h>
12 # include <semaphore.h>
13 #endif
14 #include <string>
16 #include "base/basictypes.h"
17 #include "base/process.h"
18 #include "mozilla/Attributes.h"
19 #include "mozilla/UniquePtrExtensions.h"
21 namespace base {
23 // SharedMemoryHandle is a platform specific type which represents
24 // the underlying OS handle to a shared memory segment.
25 typedef mozilla::UniqueFileHandle SharedMemoryHandle;
27 // Platform abstraction for shared memory. Provides a C++ wrapper
28 // around the OS primitive for a memory mapped file.
29 class SharedMemory {
30 public:
31 // Create a new SharedMemory object.
32 SharedMemory() = default;
34 // Create a new SharedMemory object from an existing, open
35 // shared memory file.
36 SharedMemory(SharedMemoryHandle init_handle, bool read_only)
37 : SharedMemory() {
38 SetHandle(std::move(init_handle), read_only);
41 // Move constructor; transfers ownership.
42 SharedMemory(SharedMemory&& other) = default;
44 // Destructor. Will close any open files.
45 ~SharedMemory();
47 // Initialize a new SharedMemory object from an existing, open
48 // shared memory file.
49 bool SetHandle(SharedMemoryHandle handle, bool read_only);
51 // Return true iff the given handle is valid (i.e. not the distingished
52 // invalid value; NULL for a HANDLE and -1 for a file descriptor)
53 static bool IsHandleValid(const SharedMemoryHandle& handle);
55 // IsHandleValid applied to this object's handle.
56 bool IsValid() const { return static_cast<bool>(mapped_file_); }
58 // Return invalid handle (see comment above for exact definition).
59 static SharedMemoryHandle NULLHandle();
61 // Creates a shared memory segment.
62 // Returns true on success, false on failure.
63 bool Create(size_t size) { return CreateInternal(size, false); }
65 // Creates a shared memory segment that supports the Freeze()
66 // method; see below. (Warning: creating freezeable shared memory
67 // within a sandboxed process isn't possible on some platforms.)
68 // Returns true on success, false on failure.
69 bool CreateFreezeable(size_t size) { return CreateInternal(size, true); }
71 // Maps the shared memory into the caller's address space.
72 // Returns true on success, false otherwise. The memory address
73 // is accessed via the memory() accessor.
75 // If the specified fixed address is not null, it is the address that the
76 // shared memory must be mapped at. Returns false if the shared memory
77 // could not be mapped at that address.
78 bool Map(size_t bytes, void* fixed_address = nullptr);
80 // Unmaps the shared memory from the caller's address space.
81 void Unmap() { memory_ = nullptr; }
83 // Get the size of the opened shared memory backing file.
84 // Note: This size is only available to the creator of the
85 // shared memory, and not to those that opened shared memory
86 // created externally.
87 // Returns 0 if not opened or unknown.
88 size_t max_size() const { return max_size_; }
90 // Gets a pointer to the opened memory space if it has been
91 // Mapped via Map(). Returns NULL if it is not mapped.
92 void* memory() const { return memory_.get(); }
94 // Extracts the underlying file handle, returning a RAII type.
95 // If `unmap_view` is true, this unmaps the memory as a side-effect (and
96 // cleans up any OS-specific resources).
97 mozilla::UniqueFileHandle TakeHandle(bool unmap_view = true) {
98 mozilla::UniqueFileHandle handle = std::move(mapped_file_);
99 Close(unmap_view);
100 return handle;
103 // Creates a copy of the underlying file handle, returning a RAII type.
104 // This operation may fail, in which case the returned file handle will be
105 // invalid.
106 mozilla::UniqueFileHandle CloneHandle();
108 // Make the shared memory object read-only, such that it cannot be
109 // written even if it's sent to an untrusted process. If it was
110 // mapped in this process, it will be unmapped. The object must
111 // have been created with CreateFreezeable(), and must not have
112 // already been shared to another process.
114 // (See bug 1479960 comment #0 for OS-specific implementation
115 // details.)
116 [[nodiscard]] bool Freeze() {
117 Unmap();
118 return ReadOnlyCopy(this);
121 // Similar to Freeze(), but assigns the read-only capability to
122 // another SharedMemory object and leaves this object's mapping in
123 // place and writeable. This can be used to broadcast data to
124 // several untrusted readers without copying.
126 // The other constraints of Freeze() still apply: this object closes
127 // its handle (as if by `Close(false)`), it cannot have been
128 // previously shared, and the read-only handle cannot be used to
129 // write the memory even by a malicious process.
131 // (The out parameter can currently be the same as `this` if and
132 // only if the memory was unmapped, but this is an implementation
133 // detail and shouldn't be relied on; for that use case Freeze()
134 // should be used instead.)
135 [[nodiscard]] bool ReadOnlyCopy(SharedMemory* ro_out);
137 // Closes the open shared memory segment.
138 // It is safe to call Close repeatedly.
139 void Close(bool unmap_view = true);
141 // Returns a page-aligned address at which the given number of bytes could
142 // probably be mapped. Returns NULL on error or if there is insufficient
143 // contiguous address space to map the required number of pages.
145 // Note that there is no guarantee that the given address space will actually
146 // be free by the time this function returns, since another thread might map
147 // something there in the meantime.
148 static void* FindFreeAddressSpace(size_t size);
150 #ifdef XP_UNIX
151 // If named POSIX shm is being used, append the prefix (including
152 // the leading '/') that would be used by a process with the given
153 // pid to the given string and return true. If not, return false.
154 // (This is public so that the Linux sandboxing code can use it.)
155 static bool AppendPosixShmPrefix(std::string* str, pid_t pid);
156 // Similar, but simply returns whether POSIX shm is in use.
157 static bool UsingPosixShm();
158 #endif
160 private:
161 bool CreateInternal(size_t size, bool freezeable);
163 // Unmapping shared memory requires the mapped size on Unix but not
164 // Windows; this encapsulates that difference.
165 struct MappingDeleter {
166 #ifdef XP_UNIX
167 // A default-constructed deleter must be used only with nullptr
168 // (to allow default-constructing UniqueMapping). A deleter with
169 // a size must be used at most once.
170 size_t mapped_size_ = 0;
171 explicit MappingDeleter(size_t size) : mapped_size_(size) {}
172 #endif
173 MappingDeleter() = default;
174 void operator()(void* ptr);
176 using UniqueMapping = mozilla::UniquePtr<void, MappingDeleter>;
178 UniqueMapping memory_;
179 size_t max_size_ = 0;
180 mozilla::UniqueFileHandle mapped_file_;
181 #if defined(XP_WIN)
182 // If true indicates this came from an external source so needs extra checks
183 // before being mapped.
184 bool external_section_ = false;
185 #elif !defined(ANDROID)
186 mozilla::UniqueFileHandle frozen_file_;
187 bool is_memfd_ = false;
188 #endif
189 bool read_only_ = false;
190 bool freezeable_ = false;
192 DISALLOW_EVIL_CONSTRUCTORS(SharedMemory);
195 } // namespace base
197 #endif // BASE_SHARED_MEMORY_H_