1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/memory/shared_memory_mapping.h"
6
7 #include <cstdint>
8 #include <utility>
9
10 #include "base/bits.h"
11 #include "base/logging.h"
12 #include "base/memory/shared_memory_security_policy.h"
13 #include "base/memory/shared_memory_tracker.h"
14 #include "base/system/sys_info.h"
15 #include "base/unguessable_token.h"
16 #include "build/build_config.h"
17
18 namespace base {
19
20 SharedMemoryMapping::SharedMemoryMapping() = default;
21
SharedMemoryMapping(SharedMemoryMapping && mapping)22 SharedMemoryMapping::SharedMemoryMapping(SharedMemoryMapping&& mapping) noexcept
23 : mapped_span_(std::exchange(mapping.mapped_span_, span<uint8_t>())),
24 size_(mapping.size_),
25 guid_(mapping.guid_),
26 mapper_(mapping.mapper_) {}
27
operator =(SharedMemoryMapping && mapping)28 SharedMemoryMapping& SharedMemoryMapping::operator=(
29 SharedMemoryMapping&& mapping) noexcept {
30 Unmap();
31 mapped_span_ = std::exchange(mapping.mapped_span_, span<uint8_t>());
32 size_ = mapping.size_;
33 guid_ = mapping.guid_;
34 mapper_ = mapping.mapper_;
35 return *this;
36 }
37
~SharedMemoryMapping()38 SharedMemoryMapping::~SharedMemoryMapping() {
39 Unmap();
40 }
41
SharedMemoryMapping(span<uint8_t> mapped_span,size_t size,const UnguessableToken & guid,SharedMemoryMapper * mapper)42 SharedMemoryMapping::SharedMemoryMapping(span<uint8_t> mapped_span,
43 size_t size,
44 const UnguessableToken& guid,
45 SharedMemoryMapper* mapper)
46 : mapped_span_(mapped_span), size_(size), guid_(guid), mapper_(mapper) {
47 // Note: except on Windows, `mapped_span_.size() == size_`.
48 SharedMemoryTracker::GetInstance()->IncrementMemoryUsage(*this);
49 }
50
Unmap()51 void SharedMemoryMapping::Unmap() {
52 if (!IsValid())
53 return;
54
55 SharedMemorySecurityPolicy::ReleaseReservationForMapping(size_);
56 SharedMemoryTracker::GetInstance()->DecrementMemoryUsage(*this);
57
58 SharedMemoryMapper* mapper = mapper_;
59 if (!mapper)
60 mapper = SharedMemoryMapper::GetDefaultInstance();
61
62 // The backing mapper expects offset to be aligned to
63 // `SysInfo::VMAllocationGranularity()`, so replicate the alignment that was
64 // done when originally mapping in the region.
65 uint8_t* aligned_data =
66 bits::AlignDown(mapped_span_.data(), SysInfo::VMAllocationGranularity());
67 size_t adjusted_size =
68 mapped_span_.size() +
69 static_cast<size_t>(mapped_span_.data() - aligned_data);
70 span<uint8_t> span_to_unmap = make_span(aligned_data, adjusted_size);
71 mapper->Unmap(span_to_unmap);
72 }
73
74 ReadOnlySharedMemoryMapping::ReadOnlySharedMemoryMapping() = default;
75 ReadOnlySharedMemoryMapping::ReadOnlySharedMemoryMapping(
76 ReadOnlySharedMemoryMapping&&) noexcept = default;
77 ReadOnlySharedMemoryMapping& ReadOnlySharedMemoryMapping::operator=(
78 ReadOnlySharedMemoryMapping&&) noexcept = default;
ReadOnlySharedMemoryMapping(span<uint8_t> mapped_span,size_t size,const UnguessableToken & guid,SharedMemoryMapper * mapper)79 ReadOnlySharedMemoryMapping::ReadOnlySharedMemoryMapping(
80 span<uint8_t> mapped_span,
81 size_t size,
82 const UnguessableToken& guid,
83 SharedMemoryMapper* mapper)
84 : SharedMemoryMapping(mapped_span, size, guid, mapper) {}
85
86 WritableSharedMemoryMapping::WritableSharedMemoryMapping() = default;
87 WritableSharedMemoryMapping::WritableSharedMemoryMapping(
88 WritableSharedMemoryMapping&&) noexcept = default;
89 WritableSharedMemoryMapping& WritableSharedMemoryMapping::operator=(
90 WritableSharedMemoryMapping&&) noexcept = default;
WritableSharedMemoryMapping(span<uint8_t> mapped_span,size_t size,const UnguessableToken & guid,SharedMemoryMapper * mapper)91 WritableSharedMemoryMapping::WritableSharedMemoryMapping(
92 span<uint8_t> mapped_span,
93 size_t size,
94 const UnguessableToken& guid,
95 SharedMemoryMapper* mapper)
96 : SharedMemoryMapping(mapped_span, size, guid, mapper) {}
97
98 } // namespace base
99