OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
8 #if defined(OS_MACOSX) | 8 #if defined(OS_MACOSX) |
9 extern "C" { | 9 extern "C" { |
10 #include <sandbox.h> | 10 #include <sandbox.h> |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 ++num_fds_received_; | 106 ++num_fds_received_; |
107 if (num_fds_received_ == kNumFDsToSend * kNumMessages) | 107 if (num_fds_received_ == kNumFDsToSend * kNumMessages) |
108 base::MessageLoop::current()->QuitWhenIdle(); | 108 base::MessageLoop::current()->QuitWhenIdle(); |
109 } | 109 } |
110 | 110 |
111 private: | 111 private: |
112 ino_t expected_inode_num_; | 112 ino_t expected_inode_num_; |
113 unsigned num_fds_received_; | 113 unsigned num_fds_received_; |
114 }; | 114 }; |
115 | 115 |
116 | 116 class IPCSendFdsTest : public IPCChannelMojoTestBase { |
117 class IPCSendFdsTest : public IPCTestBase { | |
118 protected: | 117 protected: |
119 void RunServer() { | 118 void RunServer() { |
120 // Set up IPC channel and start client. | 119 // Set up IPC channel and start client. |
121 MyChannelDescriptorListener listener(-1); | 120 MyChannelDescriptorListener listener(-1); |
122 CreateChannel(&listener); | 121 CreateChannel(&listener); |
123 ASSERT_TRUE(ConnectChannel()); | 122 ASSERT_TRUE(ConnectChannel()); |
124 ASSERT_TRUE(StartClient()); | |
125 | 123 |
126 for (unsigned i = 0; i < kNumMessages; ++i) { | 124 for (unsigned i = 0; i < kNumMessages; ++i) { |
127 IPC::Message* message = | 125 IPC::Message* message = |
128 new IPC::Message(0, 3, IPC::Message::PRIORITY_NORMAL); | 126 new IPC::Message(0, 3, IPC::Message::PRIORITY_NORMAL); |
129 for (unsigned j = 0; j < kNumFDsToSend; ++j) { | 127 for (unsigned j = 0; j < kNumFDsToSend; ++j) { |
130 const int fd = open(kDevZeroPath, O_RDONLY); | 128 const int fd = open(kDevZeroPath, O_RDONLY); |
131 ASSERT_GE(fd, 0); | 129 ASSERT_GE(fd, 0); |
132 base::FileDescriptor descriptor(fd, true); | 130 base::FileDescriptor descriptor(fd, true); |
133 IPC::ParamTraits<base::FileDescriptor>::Write(message, descriptor); | 131 IPC::ParamTraits<base::FileDescriptor>::Write(message, descriptor); |
134 } | 132 } |
135 ASSERT_TRUE(sender()->Send(message)); | 133 ASSERT_TRUE(sender()->Send(message)); |
136 } | 134 } |
137 | 135 |
138 // Run message loop. | 136 // Run message loop. |
139 base::RunLoop().Run(); | 137 base::RunLoop().Run(); |
140 | 138 |
141 // Close the channel so the client's OnChannelError() gets fired. | 139 // Close the channel so the client's OnChannelError() gets fired. |
142 channel()->Close(); | 140 channel()->Close(); |
143 | 141 |
144 EXPECT_TRUE(WaitForClientShutdown()); | 142 EXPECT_TRUE(WaitForClientShutdown()); |
145 DestroyChannel(); | 143 DestroyChannel(); |
146 } | 144 } |
147 }; | 145 }; |
148 | 146 |
149 TEST_F(IPCSendFdsTest, DescriptorTest) { | 147 TEST_F(IPCSendFdsTest, DescriptorTest) { |
150 Init("SendFdsClient"); | 148 Init("SendFdsClient"); |
151 RunServer(); | 149 RunServer(); |
152 } | 150 } |
153 | 151 |
154 int SendFdsClientCommon(const std::string& test_client_name, | 152 class SendFdsTestClientFixture : public IpcChannelMojoTestClient { |
155 ino_t expected_inode_num) { | 153 protected: |
156 base::MessageLoopForIO main_message_loop; | 154 void SendFdsClientCommon(const std::string& test_client_name, |
157 MyChannelDescriptorListener listener(expected_inode_num); | 155 ino_t expected_inode_num) { |
| 156 MyChannelDescriptorListener listener(expected_inode_num); |
158 | 157 |
159 // Set up IPC channel. | 158 // Set up IPC channel. |
160 std::unique_ptr<IPC::Channel> channel(IPC::Channel::CreateClient( | 159 Connect(&listener); |
161 IPCTestBase::GetChannelName(test_client_name), &listener, | |
162 main_message_loop.task_runner())); | |
163 CHECK(channel->Connect()); | |
164 | 160 |
165 // Run message loop. | 161 // Run message loop. |
166 base::RunLoop().Run(); | 162 base::RunLoop().Run(); |
167 | 163 |
168 // Verify that the message loop was exited due to getting the correct number | 164 // Verify that the message loop was exited due to getting the correct number |
169 // of descriptors, and not because of the channel closing unexpectedly. | 165 // of descriptors, and not because of the channel closing unexpectedly. |
170 CHECK(listener.GotExpectedNumberOfDescriptors()); | 166 EXPECT_TRUE(listener.GotExpectedNumberOfDescriptors()); |
171 | 167 |
172 return 0; | 168 Close(); |
173 } | 169 } |
| 170 }; |
174 | 171 |
175 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendFdsClient) { | 172 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE( |
| 173 SendFdsClient, |
| 174 SendFdsTestClientFixture) { |
176 struct stat st; | 175 struct stat st; |
177 int fd = open(kDevZeroPath, O_RDONLY); | 176 int fd = open(kDevZeroPath, O_RDONLY); |
178 fstat(fd, &st); | 177 fstat(fd, &st); |
179 EXPECT_GE(IGNORE_EINTR(close(fd)), 0); | 178 EXPECT_GE(IGNORE_EINTR(close(fd)), 0); |
180 return SendFdsClientCommon("SendFdsClient", st.st_ino); | 179 SendFdsClientCommon("SendFdsClient", st.st_ino); |
181 } | 180 } |
182 | 181 |
183 #if defined(OS_MACOSX) | 182 #if defined(OS_MACOSX) |
184 // Test that FDs are correctly sent to a sandboxed process. | 183 // Test that FDs are correctly sent to a sandboxed process. |
185 // TODO(port): Make this test cross-platform. | 184 // TODO(port): Make this test cross-platform. |
186 TEST_F(IPCSendFdsTest, DescriptorTestSandboxed) { | 185 TEST_F(IPCSendFdsTest, DescriptorTestSandboxed) { |
187 Init("SendFdsSandboxedClient"); | 186 Init("SendFdsSandboxedClient"); |
188 RunServer(); | 187 RunServer(); |
189 } | 188 } |
190 | 189 |
191 MULTIPROCESS_IPC_TEST_CLIENT_MAIN(SendFdsSandboxedClient) { | 190 DEFINE_IPC_CHANNEL_MOJO_TEST_CLIENT_WITH_CUSTOM_FIXTURE( |
| 191 SendFdsSandboxedClient, |
| 192 SendFdsTestClientFixture) { |
192 struct stat st; | 193 struct stat st; |
193 const int fd = open(kDevZeroPath, O_RDONLY); | 194 const int fd = open(kDevZeroPath, O_RDONLY); |
194 fstat(fd, &st); | 195 fstat(fd, &st); |
195 if (IGNORE_EINTR(close(fd)) < 0) | 196 ASSERT_LE(0, IGNORE_EINTR(close(fd))); |
196 return -1; | |
197 | 197 |
198 // Enable the sandbox. | 198 // Enable the sandbox. |
199 char* error_buff = NULL; | 199 char* error_buff = NULL; |
200 int error = sandbox::Seatbelt::Init( | 200 int error = sandbox::Seatbelt::Init( |
201 sandbox::Seatbelt::kProfilePureComputation, SANDBOX_NAMED, &error_buff); | 201 sandbox::Seatbelt::kProfilePureComputation, SANDBOX_NAMED, &error_buff); |
202 bool success = (error == 0 && error_buff == NULL); | 202 ASSERT_EQ(0, error); |
203 if (!success) | 203 ASSERT_FALSE(error_buff); |
204 return -1; | |
205 | 204 |
206 sandbox::Seatbelt::FreeError(error_buff); | 205 sandbox::Seatbelt::FreeError(error_buff); |
207 | 206 |
208 // Make sure sandbox is really enabled. | 207 // Make sure sandbox is really enabled. |
209 if (open(kDevZeroPath, O_RDONLY) != -1) { | 208 ASSERT_EQ(-1, open(kDevZeroPath, O_RDONLY)) |
210 LOG(ERROR) << "Sandbox wasn't properly enabled"; | 209 << "Sandbox wasn't properly enabled"; |
211 return -1; | |
212 } | |
213 | 210 |
214 // See if we can receive a file descriptor. | 211 // See if we can receive a file descriptor. |
215 return SendFdsClientCommon("SendFdsSandboxedClient", st.st_ino); | 212 SendFdsClientCommon("SendFdsSandboxedClient", st.st_ino); |
216 } | 213 } |
217 #endif // defined(OS_MACOSX) | 214 #endif // defined(OS_MACOSX) |
218 | 215 |
219 | 216 |
220 class MyCBListener : public MyChannelDescriptorListenerBase { | 217 class MyCBListener : public MyChannelDescriptorListenerBase { |
221 public: | 218 public: |
222 MyCBListener(base::Callback<void(int)> cb, int fds_to_send) | 219 MyCBListener(base::Callback<void(int)> cb, int fds_to_send) |
223 : MyChannelDescriptorListenerBase(), | 220 : MyChannelDescriptorListenerBase(), |
224 cb_(cb) { | 221 cb_(cb) { |
225 } | 222 } |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 base::WaitableEvent received_; | 385 base::WaitableEvent received_; |
389 }; | 386 }; |
390 | 387 |
391 TEST_F(IPCMultiSendingFdsTest, StressTest) { | 388 TEST_F(IPCMultiSendingFdsTest, StressTest) { |
392 Run(); | 389 Run(); |
393 } | 390 } |
394 | 391 |
395 } // namespace | 392 } // namespace |
396 | 393 |
397 #endif // defined(OS_POSIX) | 394 #endif // defined(OS_POSIX) |
OLD | NEW |