Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(114)

Side by Side Diff: base/metrics/persistent_memory_allocator.cc

Issue 1654053002: New test and off-by-one fix for data persisted to disk. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: allow crash-test to run with dcheck enabled Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | base/metrics/persistent_memory_allocator_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « no previous file | base/metrics/persistent_memory_allocator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698