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