OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/memory/shared_memory.h" | 5 #include "base/memory/shared_memory.h" |
6 | 6 |
7 #include <aclapi.h> | 7 #include <aclapi.h> |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.h" |
13 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 16 #include "base/unguessable_token.h" |
16 | 17 |
17 namespace { | 18 namespace { |
18 | 19 |
19 // Errors that can occur during Shared Memory construction. | 20 // Errors that can occur during Shared Memory construction. |
20 // These match tools/metrics/histograms/histograms.xml. | 21 // These match tools/metrics/histograms/histograms.xml. |
21 // This enum is append-only. | 22 // This enum is append-only. |
22 enum CreateError { | 23 enum CreateError { |
23 SUCCESS = 0, | 24 SUCCESS = 0, |
24 SIZE_ZERO = 1, | 25 SIZE_ZERO = 1, |
25 SIZE_TOO_LARGE = 2, | 26 SIZE_TOO_LARGE = 2, |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 | 234 |
234 // Windows ignores DACLs on certain unnamed objects (like shared sections). | 235 // Windows ignores DACLs on certain unnamed objects (like shared sections). |
235 // So, we generate a random name when we need to enforce read-only. | 236 // So, we generate a random name when we need to enforce read-only. |
236 uint64_t rand_values[4]; | 237 uint64_t rand_values[4]; |
237 RandBytes(&rand_values, sizeof(rand_values)); | 238 RandBytes(&rand_values, sizeof(rand_values)); |
238 name_ = StringPrintf(L"CrSharedMem_%016llx%016llx%016llx%016llx", | 239 name_ = StringPrintf(L"CrSharedMem_%016llx%016llx%016llx%016llx", |
239 rand_values[0], rand_values[1], | 240 rand_values[0], rand_values[1], |
240 rand_values[2], rand_values[3]); | 241 rand_values[2], rand_values[3]); |
241 } | 242 } |
242 DCHECK(!name_.empty()); | 243 DCHECK(!name_.empty()); |
243 shm_ = SharedMemoryHandle(CreateFileMappingWithReducedPermissions( | 244 shm_ = SharedMemoryHandle( |
244 &sa, rounded_size, name_.c_str())); | 245 CreateFileMappingWithReducedPermissions(&sa, rounded_size, name_.c_str()), |
| 246 UnguessableToken::Create()); |
245 if (!shm_.IsValid()) { | 247 if (!shm_.IsValid()) { |
246 // The error is logged within CreateFileMappingWithReducedPermissions(). | 248 // The error is logged within CreateFileMappingWithReducedPermissions(). |
247 return false; | 249 return false; |
248 } | 250 } |
249 | 251 |
250 requested_size_ = options.size; | 252 requested_size_ = options.size; |
251 | 253 |
252 // Check if the shared memory pre-exists. | 254 // Check if the shared memory pre-exists. |
253 if (GetLastError() == ERROR_ALREADY_EXISTS) { | 255 if (GetLastError() == ERROR_ALREADY_EXISTS) { |
254 // If the file already existed, set requested_size_ to 0 to show that | 256 // If the file already existed, set requested_size_ to 0 to show that |
(...skipping 17 matching lines...) Expand all Loading... |
272 return true; | 274 return true; |
273 } | 275 } |
274 | 276 |
275 bool SharedMemory::Open(const std::string& name, bool read_only) { | 277 bool SharedMemory::Open(const std::string& name, bool read_only) { |
276 DCHECK(!shm_.IsValid()); | 278 DCHECK(!shm_.IsValid()); |
277 DWORD access = FILE_MAP_READ | SECTION_QUERY; | 279 DWORD access = FILE_MAP_READ | SECTION_QUERY; |
278 if (!read_only) | 280 if (!read_only) |
279 access |= FILE_MAP_WRITE; | 281 access |= FILE_MAP_WRITE; |
280 name_ = ASCIIToUTF16(name); | 282 name_ = ASCIIToUTF16(name); |
281 read_only_ = read_only; | 283 read_only_ = read_only; |
| 284 |
| 285 // This form of sharing shared memory is deprecated. https://crbug.com/345734. |
| 286 // However, we can't get rid of it without a significant refactor because its |
| 287 // used to communicate between two versions of the same service process, very |
| 288 // early in the life cycle. |
| 289 // Technically, we should also pass the GUID from the original shared memory |
| 290 // region. We don't do that - this means that we will overcount this memory, |
| 291 // which thankfully isn't relevant since Chrome only communicates with a |
| 292 // single version of the service process. |
282 shm_ = SharedMemoryHandle( | 293 shm_ = SharedMemoryHandle( |
283 OpenFileMapping(access, false, name_.empty() ? nullptr : name_.c_str())); | 294 OpenFileMapping(access, false, name_.empty() ? nullptr : name_.c_str()), |
| 295 UnguessableToken::Create()); |
284 if (!shm_.IsValid()) | 296 if (!shm_.IsValid()) |
285 return false; | 297 return false; |
286 // If a name specified assume it's an external section. | 298 // If a name specified assume it's an external section. |
287 if (!name_.empty()) | 299 if (!name_.empty()) |
288 external_section_ = true; | 300 external_section_ = true; |
289 // Note: size_ is not set in this case. | 301 // Note: size_ is not set in this case. |
290 return true; | 302 return true; |
291 } | 303 } |
292 | 304 |
293 bool SharedMemory::MapAt(off_t offset, size_t bytes) { | 305 bool SharedMemory::MapAt(off_t offset, size_t bytes) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 return true; | 337 return true; |
326 } | 338 } |
327 | 339 |
328 SharedMemoryHandle SharedMemory::GetReadOnlyHandle() { | 340 SharedMemoryHandle SharedMemory::GetReadOnlyHandle() { |
329 HANDLE result; | 341 HANDLE result; |
330 ProcessHandle process = GetCurrentProcess(); | 342 ProcessHandle process = GetCurrentProcess(); |
331 if (!::DuplicateHandle(process, shm_.GetHandle(), process, &result, | 343 if (!::DuplicateHandle(process, shm_.GetHandle(), process, &result, |
332 FILE_MAP_READ | SECTION_QUERY, FALSE, 0)) { | 344 FILE_MAP_READ | SECTION_QUERY, FALSE, 0)) { |
333 return SharedMemoryHandle(); | 345 return SharedMemoryHandle(); |
334 } | 346 } |
335 SharedMemoryHandle handle = SharedMemoryHandle(result); | 347 SharedMemoryHandle handle = SharedMemoryHandle(result, shm_.GetGUID()); |
336 handle.SetOwnershipPassesToIPC(true); | 348 handle.SetOwnershipPassesToIPC(true); |
337 return handle; | 349 return handle; |
338 } | 350 } |
339 | 351 |
340 void SharedMemory::Close() { | 352 void SharedMemory::Close() { |
341 if (shm_.IsValid()) { | 353 if (shm_.IsValid()) { |
342 shm_.Close(); | 354 shm_.Close(); |
343 shm_ = SharedMemoryHandle(); | 355 shm_ = SharedMemoryHandle(); |
344 } | 356 } |
345 } | 357 } |
346 | 358 |
347 SharedMemoryHandle SharedMemory::handle() const { | 359 SharedMemoryHandle SharedMemory::handle() const { |
348 return shm_; | 360 return shm_; |
349 } | 361 } |
350 | 362 |
351 SharedMemoryHandle SharedMemory::TakeHandle() { | 363 SharedMemoryHandle SharedMemory::TakeHandle() { |
352 SharedMemoryHandle handle(shm_); | 364 SharedMemoryHandle handle(shm_); |
353 handle.SetOwnershipPassesToIPC(true); | 365 handle.SetOwnershipPassesToIPC(true); |
354 shm_ = SharedMemoryHandle(); | 366 shm_ = SharedMemoryHandle(); |
355 memory_ = nullptr; | 367 memory_ = nullptr; |
356 mapped_size_ = 0; | 368 mapped_size_ = 0; |
357 return handle; | 369 return handle; |
358 } | 370 } |
359 | 371 |
360 } // namespace base | 372 } // namespace base |
OLD | NEW |