OLD | NEW |
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/metrics/persistent_memory_allocator.h" | 5 #include "base/metrics/persistent_memory_allocator.h" |
6 | 6 |
7 #include <assert.h> | 7 #include <assert.h> |
8 #include <algorithm> | 8 #include <algorithm> |
9 | 9 |
10 #include "base/files/memory_mapped_file.h" | 10 #include "base/files/memory_mapped_file.h" |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 | 156 |
157 // These atomics operate inter-process and so must be lock-free. The local | 157 // These atomics operate inter-process and so must be lock-free. The local |
158 // casts are to make sure it can be evaluated at compile time to a constant. | 158 // casts are to make sure it can be evaluated at compile time to a constant. |
159 CHECK(((SharedMetadata*)0)->freeptr.is_lock_free()); | 159 CHECK(((SharedMetadata*)0)->freeptr.is_lock_free()); |
160 CHECK(((SharedMetadata*)0)->flags.is_lock_free()); | 160 CHECK(((SharedMetadata*)0)->flags.is_lock_free()); |
161 CHECK(((BlockHeader*)0)->next.is_lock_free()); | 161 CHECK(((BlockHeader*)0)->next.is_lock_free()); |
162 CHECK(corrupt_.is_lock_free()); | 162 CHECK(corrupt_.is_lock_free()); |
163 | 163 |
164 if (shared_meta()->cookie != kGlobalCookie) { | 164 if (shared_meta()->cookie != kGlobalCookie) { |
165 if (readonly) { | 165 if (readonly) { |
166 NOTREACHED(); | |
167 SetCorrupt(); | 166 SetCorrupt(); |
168 return; | 167 return; |
169 } | 168 } |
170 | 169 |
171 // This block is only executed when a completely new memory segment is | 170 // This block is only executed when a completely new memory segment is |
172 // being initialized. It's unshared and single-threaded... | 171 // being initialized. It's unshared and single-threaded... |
173 volatile BlockHeader* const first_block = | 172 volatile BlockHeader* const first_block = |
174 reinterpret_cast<volatile BlockHeader*>(mem_base_ + | 173 reinterpret_cast<volatile BlockHeader*>(mem_base_ + |
175 sizeof(SharedMetadata)); | 174 sizeof(SharedMetadata)); |
176 if (shared_meta()->cookie != 0 || | 175 if (shared_meta()->cookie != 0 || |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 | 207 |
209 // Allocate space for the name so other processes can learn it. | 208 // Allocate space for the name so other processes can learn it. |
210 if (!name.empty()) { | 209 if (!name.empty()) { |
211 const size_t name_length = name.length() + 1; | 210 const size_t name_length = name.length() + 1; |
212 shared_meta()->name = Allocate(name_length, 0); | 211 shared_meta()->name = Allocate(name_length, 0); |
213 char* name_cstr = GetAsObject<char>(shared_meta()->name, 0); | 212 char* name_cstr = GetAsObject<char>(shared_meta()->name, 0); |
214 if (name_cstr) | 213 if (name_cstr) |
215 strcpy(name_cstr, name.c_str()); | 214 strcpy(name_cstr, name.c_str()); |
216 } | 215 } |
217 } else { | 216 } else { |
218 if (readonly) { | 217 if (!readonly) { |
219 // For read-only access, validate reasonable ctor parameters. | |
220 DCHECK_GE(mem_size_, shared_meta()->freeptr.load()); | |
221 } else { | |
222 // The allocator is attaching to a previously initialized segment of | 218 // The allocator is attaching to a previously initialized segment of |
223 // memory. Make sure the embedded data matches what has been passed. | 219 // memory. Make sure the embedded data matches what has been passed. |
224 if (shared_meta()->size != mem_size_ || | 220 if (shared_meta()->size != mem_size_ || |
225 shared_meta()->page_size != mem_page_) { | 221 shared_meta()->page_size != mem_page_) { |
226 NOTREACHED(); | 222 NOTREACHED(); |
227 SetCorrupt(); | 223 SetCorrupt(); |
228 } | 224 } |
229 } | 225 } |
230 } | 226 } |
231 } | 227 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 return std::min(shared_meta()->freeptr.load(), mem_size_); | 271 return std::min(shared_meta()->freeptr.load(), mem_size_); |
276 } | 272 } |
277 | 273 |
278 size_t PersistentMemoryAllocator::GetAllocSize(Reference ref) const { | 274 size_t PersistentMemoryAllocator::GetAllocSize(Reference ref) const { |
279 const volatile BlockHeader* const block = GetBlock(ref, 0, 0, false, false); | 275 const volatile BlockHeader* const block = GetBlock(ref, 0, 0, false, false); |
280 if (!block) | 276 if (!block) |
281 return 0; | 277 return 0; |
282 uint32_t size = block->size; | 278 uint32_t size = block->size; |
283 // Header was verified by GetBlock() but a malicious actor could change | 279 // Header was verified by GetBlock() but a malicious actor could change |
284 // the value between there and here. Check it again. | 280 // the value between there and here. Check it again. |
285 if (size <= sizeof(BlockHeader) || ref + size >= mem_size_) { | 281 if (size <= sizeof(BlockHeader) || ref + size > mem_size_) { |
286 SetCorrupt(); | 282 SetCorrupt(); |
287 return 0; | 283 return 0; |
288 } | 284 } |
289 return size - sizeof(BlockHeader); | 285 return size - sizeof(BlockHeader); |
290 } | 286 } |
291 | 287 |
292 uint32_t PersistentMemoryAllocator::GetType(Reference ref) const { | 288 uint32_t PersistentMemoryAllocator::GetType(Reference ref) const { |
293 const volatile BlockHeader* const block = GetBlock(ref, 0, 0, false, false); | 289 const volatile BlockHeader* const block = GetBlock(ref, 0, 0, false, false); |
294 if (!block) | 290 if (!block) |
295 return 0; | 291 return 0; |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 FilePersistentMemoryAllocator::~FilePersistentMemoryAllocator() { | 665 FilePersistentMemoryAllocator::~FilePersistentMemoryAllocator() { |
670 } | 666 } |
671 | 667 |
672 // static | 668 // static |
673 bool FilePersistentMemoryAllocator::IsFileAcceptable( | 669 bool FilePersistentMemoryAllocator::IsFileAcceptable( |
674 const MemoryMappedFile& file) { | 670 const MemoryMappedFile& file) { |
675 return IsMemoryAcceptable(file.data(), file.length(), 0, true); | 671 return IsMemoryAcceptable(file.data(), file.length(), 0, true); |
676 } | 672 } |
677 | 673 |
678 } // namespace base | 674 } // namespace base |
OLD | NEW |