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

Side by Side Diff: ipc/attachment_broker_mac_unittest.cc

Issue 1418113003: mac: Add auto-close and share-read-only functionality to SharedMemory. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 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 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 "build/build_config.h" 5 #include "build/build_config.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <sys/mman.h> 8 #include <sys/mman.h>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
104 return false; 104 return false;
105 } 105 }
106 106
107 *handle1 = base::get<0>(p); 107 *handle1 = base::get<0>(p);
108 *handle2 = base::get<1>(p); 108 *handle2 = base::get<1>(p);
109 return true; 109 return true;
110 } 110 }
111 111
112 // Returns |nullptr| on error. 112 // Returns |nullptr| on error.
113 scoped_ptr<base::SharedMemory> MapSharedMemoryHandle( 113 scoped_ptr<base::SharedMemory> MapSharedMemoryHandle(
114 const base::SharedMemoryHandle& shm) { 114 const base::SharedMemoryHandle& shm,
115 bool read_only) {
115 if (!shm.IsValid()) { 116 if (!shm.IsValid()) {
116 LOG(ERROR) << "Invalid SharedMemoryHandle"; 117 LOG(ERROR) << "Invalid SharedMemoryHandle";
117 return nullptr; 118 return nullptr;
118 } 119 }
119 120
120 size_t size; 121 size_t size;
121 if (!shm.GetSize(&size)) { 122 if (!shm.GetSize(&size)) {
122 LOG(ERROR) << "Couldn't get size of SharedMemoryHandle"; 123 LOG(ERROR) << "Couldn't get size of SharedMemoryHandle";
123 return nullptr; 124 return nullptr;
124 } 125 }
125 126
126 scoped_ptr<base::SharedMemory> shared_memory( 127 scoped_ptr<base::SharedMemory> shared_memory(
127 new base::SharedMemory(shm, false)); 128 new base::SharedMemory(shm, read_only));
128 shared_memory->Map(size); 129 shared_memory->Map(size);
129 return shared_memory; 130 return shared_memory;
130 } 131 }
131 132
132 // This method maps the SharedMemoryHandle, checks the contents, and then 133 // This method maps the SharedMemoryHandle, checks the contents, and then
133 // consumes a reference to the underlying Mach port. 134 // consumes a reference to the underlying Mach port.
134 bool CheckContentsOfSharedMemoryHandle(const base::SharedMemoryHandle& shm, 135 bool CheckContentsOfSharedMemoryHandle(const base::SharedMemoryHandle& shm,
135 const std::string& contents) { 136 const std::string& contents) {
136 scoped_ptr<base::SharedMemory> shared_memory(MapSharedMemoryHandle(shm)); 137 scoped_ptr<base::SharedMemory> shared_memory(
138 MapSharedMemoryHandle(shm, false));
137 139
138 if (memcmp(shared_memory->memory(), contents.c_str(), contents.size()) != 0) { 140 if (memcmp(shared_memory->memory(), contents.c_str(), contents.size()) != 0) {
139 LOG(ERROR) << "Shared Memory contents not equivalent"; 141 LOG(ERROR) << "Shared Memory contents not equivalent";
140 return false; 142 return false;
141 } 143 }
142 return true; 144 return true;
143 } 145 }
144 146
145 // This method mmaps the FileDescriptor, checks the contents, and then munmaps 147 // This method mmaps the FileDescriptor, checks the contents, and then munmaps
146 // the FileDescriptor and closes the underlying fd. 148 // the FileDescriptor and closes the underlying fd.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 return base::FileDescriptor(fd_closer.release(), true); 183 return base::FileDescriptor(fd_closer.release(), true);
182 } 184 }
183 185
184 // Maps both handles, then checks that their contents matches |contents|. Then 186 // Maps both handles, then checks that their contents matches |contents|. Then
185 // checks that changes to one are reflected in the other. Then consumes 187 // checks that changes to one are reflected in the other. Then consumes
186 // references to both underlying Mach ports. 188 // references to both underlying Mach ports.
187 bool CheckContentsOfTwoEquivalentSharedMemoryHandles( 189 bool CheckContentsOfTwoEquivalentSharedMemoryHandles(
188 const base::SharedMemoryHandle& handle1, 190 const base::SharedMemoryHandle& handle1,
189 const base::SharedMemoryHandle& handle2, 191 const base::SharedMemoryHandle& handle2,
190 const std::string& contents) { 192 const std::string& contents) {
191 scoped_ptr<base::SharedMemory> shared_memory1(MapSharedMemoryHandle(handle1)); 193 scoped_ptr<base::SharedMemory> shared_memory1(
192 scoped_ptr<base::SharedMemory> shared_memory2(MapSharedMemoryHandle(handle2)); 194 MapSharedMemoryHandle(handle1, false));
195 scoped_ptr<base::SharedMemory> shared_memory2(
196 MapSharedMemoryHandle(handle2, false));
193 197
194 if (memcmp(shared_memory1->memory(), contents.c_str(), contents.size()) != 198 if (memcmp(shared_memory1->memory(), contents.c_str(), contents.size()) !=
195 0) { 199 0) {
196 LOG(ERROR) << "Incorrect contents in shared_memory1"; 200 LOG(ERROR) << "Incorrect contents in shared_memory1";
197 return false; 201 return false;
198 } 202 }
199 203
200 if (memcmp(shared_memory1->memory(), shared_memory2->memory(), 204 if (memcmp(shared_memory1->memory(), shared_memory2->memory(),
201 contents.size()) != 0) { 205 contents.size()) != 0) {
202 LOG(ERROR) << "Incorrect contents in shared_memory2"; 206 LOG(ERROR) << "Incorrect contents in shared_memory2";
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 bool success = CheckContentsOfMessage1(message, kDataBuffer1); 897 bool success = CheckContentsOfMessage1(message, kDataBuffer1);
894 SendControlMessage(sender, success); 898 SendControlMessage(sender, success);
895 } 899 }
896 900
897 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendSharedMemoryHandleChannelProxy) { 901 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendSharedMemoryHandleChannelProxy) {
898 return CommonPrivilegedProcessMain( 902 return CommonPrivilegedProcessMain(
899 &SendSharedMemoryHandleChannelProxyCallback, 903 &SendSharedMemoryHandleChannelProxyCallback,
900 "SendSharedMemoryHandleChannelProxy"); 904 "SendSharedMemoryHandleChannelProxy");
901 } 905 }
902 906
907 // Similar to SendSharedMemoryHandle, but first makes a copy of the handle using
908 // ShareToProcess().
909 TEST_F(IPCAttachmentBrokerMacTest, ShareToProcess) {
910 CommonSetUp("ShareToProcess");
911
912 {
913 scoped_ptr<base::SharedMemory> shared_memory(
914 MakeSharedMemory(kDataBuffer1));
915 base::SharedMemoryHandle new_handle;
916 ASSERT_TRUE(shared_memory->ShareToProcess(0, &new_handle));
917 IPC::Message* message =
918 new TestSharedMemoryHandleMsg1(100, new_handle, 200);
919 sender()->Send(message);
920 }
921
922 base::MessageLoop::current()->Run();
923 CommonTearDown();
924 }
925
926 void ShareToProcessCallback(IPC::Sender* sender, const IPC::Message& message) {
927 bool success = CheckContentsOfMessage1(message, kDataBuffer1);
928 SendControlMessage(sender, success);
929 }
930
931 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ShareToProcess) {
932 return CommonPrivilegedProcessMain(&ShareToProcessCallback, "ShareToProcess");
933 }
934
935 // Similar to ShareToProcess, but instead shares the memory object only with
936 // read permissions.
937 TEST_F(IPCAttachmentBrokerMacTest, ShareReadOnlyToProcess) {
938 CommonSetUp("ShareReadOnlyToProcess");
939
940 {
941 scoped_ptr<base::SharedMemory> shared_memory(
942 MakeSharedMemory(kDataBuffer1));
943 base::SharedMemoryHandle new_handle;
944 ASSERT_TRUE(shared_memory->ShareReadOnlyToProcess(0, &new_handle));
945 IPC::Message* message =
946 new TestSharedMemoryHandleMsg1(100, new_handle, 200);
947 sender()->Send(message);
948 }
949
950 base::MessageLoop::current()->Run();
951 CommonTearDown();
952 }
953
954 void ShareReadOnlyToProcessCallback(IPC::Sender* sender,
955 const IPC::Message& message) {
956 base::SharedMemoryHandle shm(GetSharedMemoryHandleFromMsg1(message));
957
958 // Try to map the memory as writable.
959 scoped_ptr<base::SharedMemory> shared_memory(
960 MapSharedMemoryHandle(shm, false));
961 ASSERT_EQ(nullptr, shared_memory->memory());
962
963 // Now try as read-only.
964 scoped_ptr<base::SharedMemory> shared_memory2(
965 MapSharedMemoryHandle(shm.Duplicate(), true));
966 int current_prot, max_prot;
967 ASSERT_TRUE(IPC::GetMachProtections(shared_memory2->memory(),
968 shared_memory2->mapped_size(),
969 &current_prot, &max_prot));
970 ASSERT_EQ(VM_PROT_READ, current_prot);
971 ASSERT_EQ(VM_PROT_READ, max_prot);
972
973 bool success =
974 memcmp(shared_memory2->memory(), kDataBuffer1, strlen(kDataBuffer1)) == 0;
975 SendControlMessage(sender, success);
976 }
977
978 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(ShareReadOnlyToProcess) {
979 return CommonPrivilegedProcessMain(&ShareReadOnlyToProcessCallback,
980 "ShareReadOnlyToProcess");
981 }
982
903 } // namespace 983 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698