| 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 |