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

Side by Side Diff: base/memory/shared_memory_win.cc

Issue 1677163003: base: Create file mappings with reduced access control permissions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update comments, again. 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
OLDNEW
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
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 // The handle must have SECTION_QUERY access for this to succeed. 55 // The handle must have SECTION_QUERY access for this to succeed.
56 SECTION_BASIC_INFORMATION basic_information = {}; 56 SECTION_BASIC_INFORMATION basic_information = {};
57 ULONG status = 57 ULONG status =
58 nt_query_section_func(handle, SectionBasicInformation, &basic_information, 58 nt_query_section_func(handle, SectionBasicInformation, &basic_information,
59 sizeof(basic_information), nullptr); 59 sizeof(basic_information), nullptr);
60 if (status) 60 if (status)
61 return false; 61 return false;
62 return (basic_information.Attributes & SEC_IMAGE) != SEC_IMAGE; 62 return (basic_information.Attributes & SEC_IMAGE) != SEC_IMAGE;
63 } 63 }
64 64
65 // Returns a HANDLE on success and |nullptr| on failure.
66 // This function is similar to CreateFileMapping, but removes the permissions
67 // WRITE_DAC, WRITE_OWNER, READ_CONTROL, and DELETE.
68 //
69 // A newly created file mapping has two sets of permissions. It has access
70 // control permissions (WRITE_DAC, WRITE_OWNER, READ_CONTROL, and DELETE) and
71 // file permissions (FILE_MAP_READ, FILE_MAP_WRITE, etc.). ::DuplicateHandle()
72 // with the parameter DUPLICATE_SAME_ACCESS copies both sets of permissions.
73 //
74 // The Chrome sandbox prevents HANDLEs with the WRITE_DAC permission from being
75 // duplicated into unprivileged processes. But the only way to copy file
76 // permissions is with the parameter DUPLICATE_SAME_ACCESS. This means that
77 // there is no way for a privileged process to duplicate a file mapping into an
78 // unprivileged process while maintaining the previous file permissions.
79 //
80 // By removing all access control permissions of a file mapping immediately
81 // after creation, ::DuplicateHandle() effectively only copies the file
82 // permissions.
83 HANDLE CreateFileMappingWithReducedPermissions(SECURITY_ATTRIBUTES* sa,
84 size_t rounded_size,
85 LPCWSTR name) {
86 HANDLE h = CreateFileMapping(INVALID_HANDLE_VALUE, sa, PAGE_READWRITE, 0,
87 static_cast<DWORD>(rounded_size), name);
88 if (!h)
89 return nullptr;
90
91 HANDLE h2;
92 BOOL success = ::DuplicateHandle(
93 GetCurrentProcess(), h, GetCurrentProcess(), &h2,
94 FILE_MAP_READ | FILE_MAP_WRITE | SECTION_QUERY, FALSE, 0);
95 ::CloseHandle(h);
Mark Mentovai 2016/02/17 19:03:14 BOOL rv = ::CloseHandle(h); DCHECK(rv); ?
erikchen 2016/02/17 19:22:26 Done.
96 return success ? h2 : nullptr;
97 }
98
65 } // namespace. 99 } // namespace.
66 100
67 namespace base { 101 namespace base {
68 102
69 SharedMemoryCreateOptions::SharedMemoryCreateOptions() 103 SharedMemoryCreateOptions::SharedMemoryCreateOptions()
70 : name_deprecated(nullptr), 104 : name_deprecated(nullptr),
71 open_existing_deprecated(false), 105 open_existing_deprecated(false),
72 size(0), 106 size(0),
73 executable(false), 107 executable(false),
74 share_read_only(false) {} 108 share_read_only(false) {}
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 163
130 // static 164 // static
131 SharedMemoryHandle SharedMemory::DuplicateHandle( 165 SharedMemoryHandle SharedMemory::DuplicateHandle(
132 const SharedMemoryHandle& handle) { 166 const SharedMemoryHandle& handle) {
133 DCHECK(handle.BelongsToCurrentProcess()); 167 DCHECK(handle.BelongsToCurrentProcess());
134 HANDLE duped_handle; 168 HANDLE duped_handle;
135 ProcessHandle process = GetCurrentProcess(); 169 ProcessHandle process = GetCurrentProcess();
136 BOOL success = 170 BOOL success =
137 ::DuplicateHandle(process, handle.GetHandle(), process, &duped_handle, 0, 171 ::DuplicateHandle(process, handle.GetHandle(), process, &duped_handle, 0,
138 FALSE, DUPLICATE_SAME_ACCESS); 172 FALSE, DUPLICATE_SAME_ACCESS);
139 if (success) 173 if (success) {
140 return SharedMemoryHandle(duped_handle, GetCurrentProcId()); 174 base::SharedMemoryHandle handle(duped_handle, GetCurrentProcId());
175 handle.SetOwnershipPassesToIPC(true);
176 return handle;
177 }
141 return SharedMemoryHandle(); 178 return SharedMemoryHandle();
142 } 179 }
143 180
144 bool SharedMemory::CreateAndMapAnonymous(size_t size) { 181 bool SharedMemory::CreateAndMapAnonymous(size_t size) {
145 return CreateAnonymous(size) && Map(size); 182 return CreateAnonymous(size) && Map(size);
146 } 183 }
147 184
148 bool SharedMemory::Create(const SharedMemoryCreateOptions& options) { 185 bool SharedMemory::Create(const SharedMemoryCreateOptions& options) {
149 // TODO(bsy,sehr): crbug.com/210609 NaCl forces us to round up 64k here, 186 // TODO(bsy,sehr): crbug.com/210609 NaCl forces us to round up 64k here,
150 // wasting 32k per mapping on average. 187 // wasting 32k per mapping on average.
151 static const size_t kSectionMask = 65536 - 1; 188 static const size_t kSectionMask = 65536 - 1;
152 DCHECK(!options.executable); 189 DCHECK(!options.executable);
153 DCHECK(!mapped_file_); 190 DCHECK(!mapped_file_);
154 if (options.size == 0) 191 if (options.size == 0)
155 return false; 192 return false;
156 193
157 // Check maximum accounting for overflow. 194 // Check maximum accounting for overflow.
158 if (options.size > 195 if (options.size >
159 static_cast<size_t>(std::numeric_limits<int>::max()) - kSectionMask) 196 static_cast<size_t>(std::numeric_limits<int>::max()) - kSectionMask)
160 return false; 197 return false;
161 198
162 size_t rounded_size = (options.size + kSectionMask) & ~kSectionMask; 199 size_t rounded_size = (options.size + kSectionMask) & ~kSectionMask;
163 name_ = options.name_deprecated ? 200 name_ = options.name_deprecated ?
164 ASCIIToUTF16(*options.name_deprecated) : L""; 201 ASCIIToUTF16(*options.name_deprecated) : L"";
165 SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, FALSE }; 202 SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, FALSE };
166 SECURITY_DESCRIPTOR sd; 203 SECURITY_DESCRIPTOR sd;
167 ACL dacl; 204 ACL dacl;
168 205
169 if (options.share_read_only && name_.empty()) { 206 if (name_.empty()) {
penny 2016/02/17 00:32:24 So, we're no longer looking at whether |share_read
erikchen 2016/02/17 00:43:22 (1) is a correct assessment. I would prefer to rem
170 // Add an empty DACL to enforce anonymous read-only sections. 207 // Add an empty DACL to enforce anonymous read-only sections.
171 sa.lpSecurityDescriptor = &sd; 208 sa.lpSecurityDescriptor = &sd;
172 if (!InitializeAcl(&dacl, sizeof(dacl), ACL_REVISION)) 209 if (!InitializeAcl(&dacl, sizeof(dacl), ACL_REVISION))
173 return false; 210 return false;
174 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) 211 if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
175 return false; 212 return false;
176 if (!SetSecurityDescriptorDacl(&sd, TRUE, &dacl, FALSE)) 213 if (!SetSecurityDescriptorDacl(&sd, TRUE, &dacl, FALSE))
177 return false; 214 return false;
178 215
179 // Windows ignores DACLs on certain unnamed objects (like shared sections). 216 // Windows ignores DACLs on certain unnamed objects (like shared sections).
180 // So, we generate a random name when we need to enforce read-only. 217 // So, we generate a random name when we need to enforce read-only.
181 uint64_t rand_values[4]; 218 uint64_t rand_values[4];
182 RandBytes(&rand_values, sizeof(rand_values)); 219 RandBytes(&rand_values, sizeof(rand_values));
183 name_ = StringPrintf(L"CrSharedMem_%016llx%016llx%016llx%016llx", 220 name_ = StringPrintf(L"CrSharedMem_%016llx%016llx%016llx%016llx",
184 rand_values[0], rand_values[1], 221 rand_values[0], rand_values[1],
185 rand_values[2], rand_values[3]); 222 rand_values[2], rand_values[3]);
186 } 223 }
187 mapped_file_ = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, 224 mapped_file_ = CreateFileMappingWithReducedPermissions(
188 PAGE_READWRITE, 0, static_cast<DWORD>(rounded_size), 225 &sa, rounded_size, name_.empty() ? nullptr : name_.c_str());
189 name_.empty() ? nullptr : name_.c_str());
190 if (!mapped_file_) 226 if (!mapped_file_)
191 return false; 227 return false;
192 228
193 requested_size_ = options.size; 229 requested_size_ = options.size;
194 230
195 // Check if the shared memory pre-exists. 231 // Check if the shared memory pre-exists.
196 if (GetLastError() == ERROR_ALREADY_EXISTS) { 232 if (GetLastError() == ERROR_ALREADY_EXISTS) {
197 // If the file already existed, set requested_size_ to 0 to show that 233 // If the file already existed, set requested_size_ to 0 to show that
198 // we don't know the size. 234 // we don't know the size.
199 requested_size_ = 0; 235 requested_size_ = 0;
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 ::CloseHandle(mapped_file_); 338 ::CloseHandle(mapped_file_);
303 mapped_file_ = NULL; 339 mapped_file_ = NULL;
304 } 340 }
305 } 341 }
306 342
307 SharedMemoryHandle SharedMemory::handle() const { 343 SharedMemoryHandle SharedMemory::handle() const {
308 return SharedMemoryHandle(mapped_file_, base::GetCurrentProcId()); 344 return SharedMemoryHandle(mapped_file_, base::GetCurrentProcId());
309 } 345 }
310 346
311 } // namespace base 347 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698