OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 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 "ipc/attachment_broker_privileged_mac.h" | 5 #include "ipc/attachment_broker_privileged_mac.h" |
6 | 6 |
7 #include <mach/mach.h> | 7 #include <mach/mach.h> |
8 #include <mach/mach_vm.h> | 8 #include <mach/mach_vm.h> |
9 | 9 |
10 #include <map> | 10 #include <map> |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 cmd_line.GetSwitchValueASCII(g_service_switch_name); | 82 cmd_line.GetSwitchValueASCII(g_service_switch_name); |
83 base::mac::ScopedMachSendRight server_port( | 83 base::mac::ScopedMachSendRight server_port( |
84 LookupServer(service_name.c_str())); | 84 LookupServer(service_name.c_str())); |
85 base::mac::ScopedMachReceiveRight client_port(MakeReceivingPort()); | 85 base::mac::ScopedMachReceiveRight client_port(MakeReceivingPort()); |
86 | 86 |
87 // |server_port| is a newly allocated right which will be deallocated once | 87 // |server_port| is a newly allocated right which will be deallocated once |
88 // this method returns. | 88 // this method returns. |
89 *original_name_count = GetActiveNameCount() - 1; | 89 *original_name_count = GetActiveNameCount() - 1; |
90 | 90 |
91 // Send the port that this process is listening on to the server. | 91 // Send the port that this process is listening on to the server. |
92 SendMachPort(server_port, client_port, MACH_MSG_TYPE_MAKE_SEND); | 92 SendMachPort(server_port.get(), client_port.get(), MACH_MSG_TYPE_MAKE_SEND); |
93 | 93 |
94 // Send the task port for this process. | 94 // Send the task port for this process. |
95 SendMachPort(server_port, mach_task_self(), MACH_MSG_TYPE_COPY_SEND); | 95 SendMachPort(server_port.get(), mach_task_self(), MACH_MSG_TYPE_COPY_SEND); |
96 return client_port; | 96 return client_port; |
97 } | 97 } |
98 | 98 |
99 // Creates a new shared memory region populated with 'a'. | 99 // Creates a new shared memory region populated with 'a'. |
100 scoped_ptr<base::SharedMemory> CreateAndPopulateSharedMemoryHandle( | 100 scoped_ptr<base::SharedMemory> CreateAndPopulateSharedMemoryHandle( |
101 size_t size) { | 101 size_t size) { |
102 base::SharedMemoryHandle shm(size); | 102 base::SharedMemoryHandle shm(size); |
103 scoped_ptr<base::SharedMemory> shared_memory( | 103 scoped_ptr<base::SharedMemory> shared_memory( |
104 new base::SharedMemory(shm, false)); | 104 new base::SharedMemory(shm, false)); |
105 shared_memory->Map(size); | 105 shared_memory->Map(size); |
(...skipping 25 matching lines...) Expand all Loading... |
131 command_line.AppendSwitchASCII(g_service_switch_name, service_name_); | 131 command_line.AppendSwitchASCII(g_service_switch_name, service_name_); |
132 return command_line; | 132 return command_line; |
133 } | 133 } |
134 | 134 |
135 void SetUpChild(const std::string& name) { | 135 void SetUpChild(const std::string& name) { |
136 // Make a random service name so that this test doesn't conflict with other | 136 // Make a random service name so that this test doesn't conflict with other |
137 // similar tests. | 137 // similar tests. |
138 service_name_ = CreateRandomServiceName(); | 138 service_name_ = CreateRandomServiceName(); |
139 server_port_.reset(BecomeMachServer(service_name_.c_str()).release()); | 139 server_port_.reset(BecomeMachServer(service_name_.c_str()).release()); |
140 child_process_ = SpawnChild(name); | 140 child_process_ = SpawnChild(name); |
141 client_port_.reset(ReceiveMachPort(server_port_).release()); | 141 client_port_.reset(ReceiveMachPort(server_port_.get()).release()); |
142 client_task_port_.reset(ReceiveMachPort(server_port_).release()); | 142 client_task_port_.reset(ReceiveMachPort(server_port_.get()).release()); |
143 } | 143 } |
144 | 144 |
145 static const int s_memory_size = 99999; | 145 static const int s_memory_size = 99999; |
146 | 146 |
147 protected: | 147 protected: |
148 std::string service_name_; | 148 std::string service_name_; |
149 | 149 |
150 // A port on which the main process listens for mach messages from the child | 150 // A port on which the main process listens for mach messages from the child |
151 // process. | 151 // process. |
152 base::mac::ScopedMachReceiveRight server_port_; | 152 base::mac::ScopedMachReceiveRight server_port_; |
(...skipping 19 matching lines...) Expand all Loading... |
172 // Create some shared memory. | 172 // Create some shared memory. |
173 scoped_ptr<base::SharedMemory> shared_memory = | 173 scoped_ptr<base::SharedMemory> shared_memory = |
174 CreateAndPopulateSharedMemoryHandle(s_memory_size); | 174 CreateAndPopulateSharedMemoryHandle(s_memory_size); |
175 ASSERT_TRUE(shared_memory->handle().IsValid()); | 175 ASSERT_TRUE(shared_memory->handle().IsValid()); |
176 | 176 |
177 // Insert the memory object into the destination task, via an intermediate | 177 // Insert the memory object into the destination task, via an intermediate |
178 // port. | 178 // port. |
179 IncrementMachRefCount(shared_memory->handle().GetMemoryObject(), | 179 IncrementMachRefCount(shared_memory->handle().GetMemoryObject(), |
180 MACH_PORT_RIGHT_SEND); | 180 MACH_PORT_RIGHT_SEND); |
181 mach_port_name_t inserted_memory_object = broker.CreateIntermediateMachPort( | 181 mach_port_name_t inserted_memory_object = broker.CreateIntermediateMachPort( |
182 client_task_port_, base::mac::ScopedMachSendRight( | 182 client_task_port_.get(), base::mac::ScopedMachSendRight( |
183 shared_memory->handle().GetMemoryObject())); | 183 shared_memory->handle().GetMemoryObject())); |
184 EXPECT_NE(inserted_memory_object, | 184 EXPECT_NE(inserted_memory_object, |
185 static_cast<mach_port_name_t>(MACH_PORT_NULL)); | 185 static_cast<mach_port_name_t>(MACH_PORT_NULL)); |
186 SendUInt32(client_port_, inserted_memory_object); | 186 SendUInt32(client_port_.get(), inserted_memory_object); |
187 | 187 |
188 // Check that no names have been leaked. | 188 // Check that no names have been leaked. |
189 shared_memory.reset(); | 189 shared_memory.reset(); |
190 EXPECT_EQ(original_name_count, GetActiveNameCount()); | 190 EXPECT_EQ(original_name_count, GetActiveNameCount()); |
191 | 191 |
192 int rv = -1; | 192 int rv = -1; |
193 ASSERT_TRUE(child_process_.WaitForExitWithTimeout( | 193 ASSERT_TRUE(child_process_.WaitForExitWithTimeout( |
194 TestTimeouts::action_timeout(), &rv)); | 194 TestTimeouts::action_timeout(), &rv)); |
195 EXPECT_EQ(0, rv); | 195 EXPECT_EQ(0, rv); |
196 } | 196 } |
197 | 197 |
198 MULTIPROCESS_TEST_MAIN(InsertRightClient) { | 198 MULTIPROCESS_TEST_MAIN(InsertRightClient) { |
199 mach_msg_type_number_t original_name_count = 0; | 199 mach_msg_type_number_t original_name_count = 0; |
200 base::mac::ScopedMachReceiveRight client_port( | 200 base::mac::ScopedMachReceiveRight client_port( |
201 CommonChildProcessSetUp(&original_name_count).release()); | 201 CommonChildProcessSetUp(&original_name_count).release()); |
202 base::mac::ScopedMachReceiveRight inserted_port(ReceiveUInt32(client_port)); | 202 base::mac::ScopedMachReceiveRight inserted_port( |
203 base::mac::ScopedMachSendRight memory_object(ReceiveMachPort(inserted_port)); | 203 ReceiveUInt32(client_port.get())); |
| 204 base::mac::ScopedMachSendRight memory_object( |
| 205 ReceiveMachPort(inserted_port.get())); |
204 inserted_port.reset(); | 206 inserted_port.reset(); |
205 | 207 |
206 // The server should have inserted a right into this process. | 208 // The server should have inserted a right into this process. |
207 EXPECT_EQ(original_name_count + 1, GetActiveNameCount()); | 209 EXPECT_EQ(original_name_count + 1, GetActiveNameCount()); |
208 | 210 |
209 // Map the memory object and check its contents. | 211 // Map the memory object and check its contents. |
210 scoped_ptr<base::SharedMemory> shared_memory(MapMemoryObject( | 212 scoped_ptr<base::SharedMemory> shared_memory(MapMemoryObject( |
211 memory_object.release(), | 213 memory_object.release(), |
212 AttachmentBrokerPrivilegedMacMultiProcessTest::s_memory_size)); | 214 AttachmentBrokerPrivilegedMacMultiProcessTest::s_memory_size)); |
213 const char* start = static_cast<const char*>(shared_memory->memory()); | 215 const char* start = static_cast<const char*>(shared_memory->memory()); |
(...skipping 20 matching lines...) Expand all Loading... |
234 scoped_ptr<base::SharedMemory> shared_memory = | 236 scoped_ptr<base::SharedMemory> shared_memory = |
235 CreateAndPopulateSharedMemoryHandle(s_memory_size); | 237 CreateAndPopulateSharedMemoryHandle(s_memory_size); |
236 ASSERT_TRUE(shared_memory->handle().IsValid()); | 238 ASSERT_TRUE(shared_memory->handle().IsValid()); |
237 | 239 |
238 // Insert the memory object into the destination task, via an intermediate | 240 // Insert the memory object into the destination task, via an intermediate |
239 // port, twice. | 241 // port, twice. |
240 for (int i = 0; i < 2; ++i) { | 242 for (int i = 0; i < 2; ++i) { |
241 IncrementMachRefCount(shared_memory->handle().GetMemoryObject(), | 243 IncrementMachRefCount(shared_memory->handle().GetMemoryObject(), |
242 MACH_PORT_RIGHT_SEND); | 244 MACH_PORT_RIGHT_SEND); |
243 mach_port_name_t inserted_memory_object = broker.CreateIntermediateMachPort( | 245 mach_port_name_t inserted_memory_object = broker.CreateIntermediateMachPort( |
244 client_task_port_, base::mac::ScopedMachSendRight( | 246 client_task_port_.get(), |
245 shared_memory->handle().GetMemoryObject())); | 247 base::mac::ScopedMachSendRight( |
| 248 shared_memory->handle().GetMemoryObject())); |
246 EXPECT_NE(inserted_memory_object, | 249 EXPECT_NE(inserted_memory_object, |
247 static_cast<mach_port_name_t>(MACH_PORT_NULL)); | 250 static_cast<mach_port_name_t>(MACH_PORT_NULL)); |
248 SendUInt32(client_port_, inserted_memory_object); | 251 SendUInt32(client_port_.get(), inserted_memory_object); |
249 } | 252 } |
250 | 253 |
251 // Check that no names have been leaked. | 254 // Check that no names have been leaked. |
252 shared_memory.reset(); | 255 shared_memory.reset(); |
253 EXPECT_EQ(original_name_count, GetActiveNameCount()); | 256 EXPECT_EQ(original_name_count, GetActiveNameCount()); |
254 | 257 |
255 int rv = -1; | 258 int rv = -1; |
256 ASSERT_TRUE(child_process_.WaitForExitWithTimeout( | 259 ASSERT_TRUE(child_process_.WaitForExitWithTimeout( |
257 TestTimeouts::action_timeout(), &rv)); | 260 TestTimeouts::action_timeout(), &rv)); |
258 EXPECT_EQ(0, rv); | 261 EXPECT_EQ(0, rv); |
259 } | 262 } |
260 | 263 |
261 MULTIPROCESS_TEST_MAIN(InsertSameRightTwiceClient) { | 264 MULTIPROCESS_TEST_MAIN(InsertSameRightTwiceClient) { |
262 mach_msg_type_number_t original_name_count = 0; | 265 mach_msg_type_number_t original_name_count = 0; |
263 base::mac::ScopedMachReceiveRight client_port( | 266 base::mac::ScopedMachReceiveRight client_port( |
264 CommonChildProcessSetUp(&original_name_count).release()); | 267 CommonChildProcessSetUp(&original_name_count).release()); |
265 | 268 |
266 // Receive two memory objects. | 269 // Receive two memory objects. |
267 base::mac::ScopedMachReceiveRight inserted_port(ReceiveUInt32(client_port)); | 270 base::mac::ScopedMachReceiveRight inserted_port( |
268 base::mac::ScopedMachReceiveRight inserted_port2(ReceiveUInt32(client_port)); | 271 ReceiveUInt32(client_port.get())); |
269 base::mac::ScopedMachSendRight memory_object(ReceiveMachPort(inserted_port)); | 272 base::mac::ScopedMachReceiveRight inserted_port2( |
| 273 ReceiveUInt32(client_port.get())); |
| 274 base::mac::ScopedMachSendRight memory_object( |
| 275 ReceiveMachPort(inserted_port.get())); |
270 base::mac::ScopedMachSendRight memory_object2( | 276 base::mac::ScopedMachSendRight memory_object2( |
271 ReceiveMachPort(inserted_port2)); | 277 ReceiveMachPort(inserted_port2.get())); |
272 inserted_port.reset(); | 278 inserted_port.reset(); |
273 inserted_port2.reset(); | 279 inserted_port2.reset(); |
274 | 280 |
275 // Both rights are for the same Mach port, so only one new name should appear. | 281 // Both rights are for the same Mach port, so only one new name should appear. |
276 EXPECT_EQ(original_name_count + 1, GetActiveNameCount()); | 282 EXPECT_EQ(original_name_count + 1, GetActiveNameCount()); |
277 | 283 |
278 // Map both memory objects and check their contents. | 284 // Map both memory objects and check their contents. |
279 scoped_ptr<base::SharedMemory> shared_memory(MapMemoryObject( | 285 scoped_ptr<base::SharedMemory> shared_memory(MapMemoryObject( |
280 memory_object.release(), | 286 memory_object.release(), |
281 AttachmentBrokerPrivilegedMacMultiProcessTest::s_memory_size)); | 287 AttachmentBrokerPrivilegedMacMultiProcessTest::s_memory_size)); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
322 // Create some shared memory. | 328 // Create some shared memory. |
323 scoped_ptr<base::SharedMemory> shared_memory = | 329 scoped_ptr<base::SharedMemory> shared_memory = |
324 CreateAndPopulateSharedMemoryHandle(s_memory_size); | 330 CreateAndPopulateSharedMemoryHandle(s_memory_size); |
325 ASSERT_TRUE(shared_memory->handle().IsValid()); | 331 ASSERT_TRUE(shared_memory->handle().IsValid()); |
326 | 332 |
327 // Insert the memory object into the destination task, via an intermediate | 333 // Insert the memory object into the destination task, via an intermediate |
328 // port. | 334 // port. |
329 IncrementMachRefCount(shared_memory->handle().GetMemoryObject(), | 335 IncrementMachRefCount(shared_memory->handle().GetMemoryObject(), |
330 MACH_PORT_RIGHT_SEND); | 336 MACH_PORT_RIGHT_SEND); |
331 mach_port_name_t inserted_memory_object = broker.CreateIntermediateMachPort( | 337 mach_port_name_t inserted_memory_object = broker.CreateIntermediateMachPort( |
332 client_task_port_, base::mac::ScopedMachSendRight( | 338 client_task_port_.get(), |
333 shared_memory->handle().GetMemoryObject())); | 339 base::mac::ScopedMachSendRight( |
| 340 shared_memory->handle().GetMemoryObject())); |
334 EXPECT_NE(inserted_memory_object, | 341 EXPECT_NE(inserted_memory_object, |
335 static_cast<mach_port_name_t>(MACH_PORT_NULL)); | 342 static_cast<mach_port_name_t>(MACH_PORT_NULL)); |
336 SendUInt32(client_port_, inserted_memory_object); | 343 SendUInt32(client_port_.get(), inserted_memory_object); |
337 } | 344 } |
338 | 345 |
339 // Check that no names have been leaked. | 346 // Check that no names have been leaked. |
340 EXPECT_EQ(original_name_count, GetActiveNameCount()); | 347 EXPECT_EQ(original_name_count, GetActiveNameCount()); |
341 | 348 |
342 int rv = -1; | 349 int rv = -1; |
343 ASSERT_TRUE(child_process_.WaitForExitWithTimeout( | 350 ASSERT_TRUE(child_process_.WaitForExitWithTimeout( |
344 TestTimeouts::action_timeout(), &rv)); | 351 TestTimeouts::action_timeout(), &rv)); |
345 EXPECT_EQ(0, rv); | 352 EXPECT_EQ(0, rv); |
346 } | 353 } |
347 | 354 |
348 MULTIPROCESS_TEST_MAIN(InsertTwoRightsClient) { | 355 MULTIPROCESS_TEST_MAIN(InsertTwoRightsClient) { |
349 mach_msg_type_number_t original_name_count = 0; | 356 mach_msg_type_number_t original_name_count = 0; |
350 base::mac::ScopedMachReceiveRight client_port( | 357 base::mac::ScopedMachReceiveRight client_port( |
351 CommonChildProcessSetUp(&original_name_count).release()); | 358 CommonChildProcessSetUp(&original_name_count).release()); |
352 | 359 |
353 // Receive two memory objects. | 360 // Receive two memory objects. |
354 base::mac::ScopedMachReceiveRight inserted_port(ReceiveUInt32(client_port)); | 361 base::mac::ScopedMachReceiveRight inserted_port( |
355 base::mac::ScopedMachReceiveRight inserted_port2(ReceiveUInt32(client_port)); | 362 ReceiveUInt32(client_port.get())); |
356 base::mac::ScopedMachSendRight memory_object(ReceiveMachPort(inserted_port)); | 363 base::mac::ScopedMachReceiveRight inserted_port2( |
| 364 ReceiveUInt32(client_port.get())); |
| 365 base::mac::ScopedMachSendRight memory_object( |
| 366 ReceiveMachPort(inserted_port.get())); |
357 base::mac::ScopedMachSendRight memory_object2( | 367 base::mac::ScopedMachSendRight memory_object2( |
358 ReceiveMachPort(inserted_port2)); | 368 ReceiveMachPort(inserted_port2.get())); |
359 inserted_port.reset(); | 369 inserted_port.reset(); |
360 inserted_port2.reset(); | 370 inserted_port2.reset(); |
361 | 371 |
362 // There should be two new names to reflect the two new shared memory regions. | 372 // There should be two new names to reflect the two new shared memory regions. |
363 EXPECT_EQ(original_name_count + 2, GetActiveNameCount()); | 373 EXPECT_EQ(original_name_count + 2, GetActiveNameCount()); |
364 | 374 |
365 // Map both memory objects and check their contents. | 375 // Map both memory objects and check their contents. |
366 scoped_ptr<base::SharedMemory> shared_memory(MapMemoryObject( | 376 scoped_ptr<base::SharedMemory> shared_memory(MapMemoryObject( |
367 memory_object.release(), | 377 memory_object.release(), |
368 AttachmentBrokerPrivilegedMacMultiProcessTest::s_memory_size)); | 378 AttachmentBrokerPrivilegedMacMultiProcessTest::s_memory_size)); |
(...skipping 19 matching lines...) Expand all Loading... |
388 // After releasing one shared memory region, the name count should decrement. | 398 // After releasing one shared memory region, the name count should decrement. |
389 shared_memory.reset(); | 399 shared_memory.reset(); |
390 EXPECT_EQ(original_name_count + 1, GetActiveNameCount()); | 400 EXPECT_EQ(original_name_count + 1, GetActiveNameCount()); |
391 shared_memory2.reset(); | 401 shared_memory2.reset(); |
392 EXPECT_EQ(original_name_count, GetActiveNameCount()); | 402 EXPECT_EQ(original_name_count, GetActiveNameCount()); |
393 | 403 |
394 return 0; | 404 return 0; |
395 } | 405 } |
396 | 406 |
397 } // namespace IPC | 407 } // namespace IPC |
OLD | NEW |