| Index: ipc/attachment_broker_mac_unittest.cc
|
| diff --git a/ipc/attachment_broker_mac_unittest.cc b/ipc/attachment_broker_mac_unittest.cc
|
| index 795a165312721a673c79daddf803209166e38bf0..7ee97f1effa7689bc3001e8ca310e5972d32d899 100644
|
| --- a/ipc/attachment_broker_mac_unittest.cc
|
| +++ b/ipc/attachment_broker_mac_unittest.cc
|
| @@ -111,7 +111,8 @@ bool GetSharedMemoryHandlesFromMsg2(const IPC::Message& message,
|
|
|
| // Returns |nullptr| on error.
|
| scoped_ptr<base::SharedMemory> MapSharedMemoryHandle(
|
| - const base::SharedMemoryHandle& shm) {
|
| + const base::SharedMemoryHandle& shm,
|
| + bool read_only) {
|
| if (!shm.IsValid()) {
|
| LOG(ERROR) << "Invalid SharedMemoryHandle";
|
| return nullptr;
|
| @@ -124,7 +125,7 @@ scoped_ptr<base::SharedMemory> MapSharedMemoryHandle(
|
| }
|
|
|
| scoped_ptr<base::SharedMemory> shared_memory(
|
| - new base::SharedMemory(shm, false));
|
| + new base::SharedMemory(shm, read_only));
|
| shared_memory->Map(size);
|
| return shared_memory;
|
| }
|
| @@ -133,7 +134,8 @@ scoped_ptr<base::SharedMemory> MapSharedMemoryHandle(
|
| // consumes a reference to the underlying Mach port.
|
| bool CheckContentsOfSharedMemoryHandle(const base::SharedMemoryHandle& shm,
|
| const std::string& contents) {
|
| - scoped_ptr<base::SharedMemory> shared_memory(MapSharedMemoryHandle(shm));
|
| + scoped_ptr<base::SharedMemory> shared_memory(
|
| + MapSharedMemoryHandle(shm, false));
|
|
|
| if (memcmp(shared_memory->memory(), contents.c_str(), contents.size()) != 0) {
|
| LOG(ERROR) << "Shared Memory contents not equivalent";
|
| @@ -188,8 +190,10 @@ bool CheckContentsOfTwoEquivalentSharedMemoryHandles(
|
| const base::SharedMemoryHandle& handle1,
|
| const base::SharedMemoryHandle& handle2,
|
| const std::string& contents) {
|
| - scoped_ptr<base::SharedMemory> shared_memory1(MapSharedMemoryHandle(handle1));
|
| - scoped_ptr<base::SharedMemory> shared_memory2(MapSharedMemoryHandle(handle2));
|
| + scoped_ptr<base::SharedMemory> shared_memory1(
|
| + MapSharedMemoryHandle(handle1, false));
|
| + scoped_ptr<base::SharedMemory> shared_memory2(
|
| + MapSharedMemoryHandle(handle2, false));
|
|
|
| if (memcmp(shared_memory1->memory(), contents.c_str(), contents.size()) !=
|
| 0) {
|
| @@ -900,4 +904,80 @@ MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendSharedMemoryHandleChannelProxy) {
|
| "SendSharedMemoryHandleChannelProxy");
|
| }
|
|
|
| +// Similar to SendSharedMemoryHandle, but first makes a copy of the handle using
|
| +// ShareToProcess().
|
| +TEST_F(IPCAttachmentBrokerMacTest, ShareToProcess) {
|
| + CommonSetUp("ShareToProcess");
|
| +
|
| + {
|
| + scoped_ptr<base::SharedMemory> shared_memory(
|
| + MakeSharedMemory(kDataBuffer1));
|
| + base::SharedMemoryHandle new_handle;
|
| + ASSERT_TRUE(shared_memory->ShareToProcess(0, &new_handle));
|
| + IPC::Message* message =
|
| + new TestSharedMemoryHandleMsg1(100, new_handle, 200);
|
| + sender()->Send(message);
|
| + }
|
| +
|
| + base::MessageLoop::current()->Run();
|
| + CommonTearDown();
|
| +}
|
| +
|
| +void ShareToProcessCallback(IPC::Sender* sender, const IPC::Message& message) {
|
| + bool success = CheckContentsOfMessage1(message, kDataBuffer1);
|
| + SendControlMessage(sender, success);
|
| +}
|
| +
|
| +MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ShareToProcess) {
|
| + return CommonPrivilegedProcessMain(&ShareToProcessCallback, "ShareToProcess");
|
| +}
|
| +
|
| +// Similar to ShareToProcess, but instead shares the memory object only with
|
| +// read permissions.
|
| +TEST_F(IPCAttachmentBrokerMacTest, ShareReadOnlyToProcess) {
|
| + CommonSetUp("ShareReadOnlyToProcess");
|
| +
|
| + {
|
| + scoped_ptr<base::SharedMemory> shared_memory(
|
| + MakeSharedMemory(kDataBuffer1));
|
| + base::SharedMemoryHandle new_handle;
|
| + ASSERT_TRUE(shared_memory->ShareReadOnlyToProcess(0, &new_handle));
|
| + IPC::Message* message =
|
| + new TestSharedMemoryHandleMsg1(100, new_handle, 200);
|
| + sender()->Send(message);
|
| + }
|
| +
|
| + base::MessageLoop::current()->Run();
|
| + CommonTearDown();
|
| +}
|
| +
|
| +void ShareReadOnlyToProcessCallback(IPC::Sender* sender,
|
| + const IPC::Message& message) {
|
| + base::SharedMemoryHandle shm(GetSharedMemoryHandleFromMsg1(message));
|
| +
|
| + // Try to map the memory as writable.
|
| + scoped_ptr<base::SharedMemory> shared_memory(
|
| + MapSharedMemoryHandle(shm, false));
|
| + ASSERT_EQ(nullptr, shared_memory->memory());
|
| +
|
| + // Now try as read-only.
|
| + scoped_ptr<base::SharedMemory> shared_memory2(
|
| + MapSharedMemoryHandle(shm.Duplicate(), true));
|
| + int current_prot, max_prot;
|
| + ASSERT_TRUE(IPC::GetMachProtections(shared_memory2->memory(),
|
| + shared_memory2->mapped_size(),
|
| + ¤t_prot, &max_prot));
|
| + ASSERT_EQ(VM_PROT_READ, current_prot);
|
| + ASSERT_EQ(VM_PROT_READ, max_prot);
|
| +
|
| + bool success =
|
| + memcmp(shared_memory2->memory(), kDataBuffer1, strlen(kDataBuffer1)) == 0;
|
| + SendControlMessage(sender, success);
|
| +}
|
| +
|
| +MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ShareReadOnlyToProcess) {
|
| + return CommonPrivilegedProcessMain(&ShareReadOnlyToProcessCallback,
|
| + "ShareReadOnlyToProcess");
|
| +}
|
| +
|
| } // namespace
|
|
|