diff options
author | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-10 22:25:39 +0000 |
---|---|---|
committer | jeremy@chromium.org <jeremy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-10 22:25:39 +0000 |
commit | e8351b7e9c8e21bdee7f7e34bc57a99023b03b49 (patch) | |
tree | b2b56bbe11a0cdf82d7489d1920164e044cd49ea /chrome | |
parent | 3eac70b953bd3bf9b1aeccc84b6a92bcbf85d0eb (diff) | |
download | chromium_src-e8351b7e9c8e21bdee7f7e34bc57a99023b03b49.zip chromium_src-e8351b7e9c8e21bdee7f7e34bc57a99023b03b49.tar.gz chromium_src-e8351b7e9c8e21bdee7f7e34bc57a99023b03b49.tar.bz2 |
Add test to check that FDs are sent through the OS X Sandbox ok.
Review URL: http://codereview.chromium.org/21223
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9519 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/chrome.xcodeproj/project.pbxproj | 2 | ||||
-rw-r--r-- | chrome/common/ipc_send_fds_test.cc | 140 | ||||
-rw-r--r-- | chrome/common/ipc_tests.cc | 6 | ||||
-rw-r--r-- | chrome/common/ipc_tests.h | 1 |
4 files changed, 119 insertions, 30 deletions
diff --git a/chrome/chrome.xcodeproj/project.pbxproj b/chrome/chrome.xcodeproj/project.pbxproj index 2423445..44e3a1f 100644 --- a/chrome/chrome.xcodeproj/project.pbxproj +++ b/chrome/chrome.xcodeproj/project.pbxproj @@ -2421,6 +2421,7 @@ B5D16EF40F2145C600861FAC /* url_fixer_upper.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = url_fixer_upper.cc; sourceTree = "<group>"; }; B5D16EF50F2145C600861FAC /* url_fixer_upper_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = url_fixer_upper_unittest.cc; sourceTree = "<group>"; }; B5D7CD350EF0702F00EE645F /* ipc_channel_posix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ipc_channel_posix.h; sourceTree = "<group>"; }; + B5EEB5E00F42044300CD3A28 /* System.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = System.framework; path = System/Library/Frameworks/System.framework; sourceTree = SDKROOT; }; B5FDBFAE0EE4623000BEC6E6 /* ipc_tests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ipc_tests; sourceTree = BUILT_PRODUCTS_DIR; }; B5FDC0570EE488E500BEC6E6 /* ipc_channel_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ipc_channel_posix.cc; sourceTree = "<group>"; }; B6CCB9CE0F1EC32700106F0D /* constrained_window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = constrained_window.h; path = tab_contents/constrained_window.h; sourceTree = "<group>"; }; @@ -2974,6 +2975,7 @@ 56E1D7DF17D327BFCB0B895D /* test_web_contents.cc */, 699499C4FBA07FB2D7B298A2 /* user_script.cc */, 37521A11B07C479E93A39D52 /* user_script_unittest.cc */, + B5EEB5E00F42044300CD3A28 /* System.framework */, ); sourceTree = "<group>"; }; diff --git a/chrome/common/ipc_send_fds_test.cc b/chrome/common/ipc_send_fds_test.cc index 2c31f01..ca22bd5 100644 --- a/chrome/common/ipc_send_fds_test.cc +++ b/chrome/common/ipc_send_fds_test.cc @@ -6,6 +6,11 @@ #include "chrome/common/ipc_tests.h" +#if defined(OS_MACOSX) +extern "C" { +#include <sandbox.h> +} +#endif #include <sys/stat.h> #include "base/message_loop.h" @@ -14,8 +19,31 @@ #if defined(OS_POSIX) +namespace { + +const char* kDevRandomPath = "/dev/random"; + +static void VerifyAndCloseDescriptor(int fd, ino_t inode_num) { + // Check that we can read from the FD. + char buf; + ssize_t amt_read = read(fd, &buf, 1); + ASSERT_EQ(amt_read, 1); + + struct stat st; + ASSERT_EQ(fstat(fd, &st), 0); + + ASSERT_EQ(close(fd), 0); + + // We compare iNode numbers to check that the file sent over the wire + // was actually the same physical file as the one we were expecting. + ASSERT_EQ(inode_num, st.st_ino); +} + class MyChannelDescriptorListener : public IPC::Channel::Listener { public: + MyChannelDescriptorListener(ino_t expected_inode_num) + : expected_inode_num_(expected_inode_num) {} + virtual void OnMessageReceived(const IPC::Message& message) { void* iter = NULL; @@ -23,40 +51,24 @@ class MyChannelDescriptorListener : public IPC::Channel::Listener { ASSERT_TRUE( IPC::ParamTraits<FileDescriptor>::Read(&message, &iter, &descriptor)); - VerifyDescriptor(&descriptor); + + VerifyAndCloseDescriptor(descriptor.fd, expected_inode_num_); MessageLoop::current()->Quit(); } virtual void OnChannelError() { MessageLoop::current()->Quit(); } - -private: - static void VerifyDescriptor(FileDescriptor* descriptor) { - const int fd = open("/dev/null", O_RDONLY); - struct stat st1, st2; - fstat(fd, &st1); - close(fd); - fstat(descriptor->fd, &st2); - close(descriptor->fd); - ASSERT_EQ(st1.st_ino, st2.st_ino); - } + private: + ino_t expected_inode_num_; }; -TEST_F(IPCChannelTest, DescriptorTest) { - // Setup IPC channel. - MyChannelDescriptorListener listener; - - IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER, - &listener); - chan.Connect(); - - base::ProcessHandle process_handle = SpawnChild(TEST_DESCRIPTOR_CLIENT, - &chan); +void TestDescriptorServer(IPC::Channel &chan, + base::ProcessHandle process_handle) { ASSERT_TRUE(process_handle); FileDescriptor descriptor; - const int fd = open("/dev/null", O_RDONLY); + const int fd = open(kDevRandomPath, O_RDONLY); ASSERT_GE(fd, 0); descriptor.auto_close = true; descriptor.fd = fd; @@ -77,19 +89,87 @@ TEST_F(IPCChannelTest, DescriptorTest) { EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000)); } -MULTIPROCESS_TEST_MAIN(RunTestDescriptorClient) { +int TestDescriptorClient(ino_t expected_inode_num) { MessageLoopForIO main_message_loop; - MyChannelDescriptorListener listener; + MyChannelDescriptorListener listener(expected_inode_num); - // setup IPC channel + // Setup IPC channel. IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT, &listener); chan.Connect(); - - // run message loop MessageLoop::current()->Run(); - // return true; - return NULL; + + return 0; +} + +} // namespace + +// --------------------------------------------------------------------------- +#if defined(OS_MACOSX) +// TODO(port): Make this test cross-platform. +MULTIPROCESS_TEST_MAIN(RunTestDescriptorClientSandboxed) { + struct stat st; + const int fd = open(kDevRandomPath, O_RDONLY); + fstat(fd, &st); + close(fd); + + // Enable the Sandbox. + char* error_buff = NULL; + int error = sandbox_init(kSBXProfilePureComputation, SANDBOX_NAMED, + &error_buff); + bool success = (error == 0 && error_buff == NULL); + if (!success) { + return -1; + } + + sandbox_free_error(error_buff); + + // Make sure Sandbox is really enabled. + if (open(kDevRandomPath, O_RDONLY) != -1) { + LOG(ERROR) << "Sandbox wasn't properly enabled"; + return -1; + } + + // See if we can receive a file descriptor. + return TestDescriptorClient(st.st_ino); +} + +// Test that FDs are correctly sent to a sandboxed process. +TEST_F(IPCChannelTest, DescriptorTestSandboxed) { + // Setup IPC channel. + MyChannelDescriptorListener listener(-1); + + IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER, + &listener); + chan.Connect(); + + base::ProcessHandle process_handle = SpawnChild( + TEST_DESCRIPTOR_CLIENT_SANDBOXED, + &chan); + TestDescriptorServer(chan, process_handle); +} +#endif // defined(OS_MACOSX) + +MULTIPROCESS_TEST_MAIN(RunTestDescriptorClient) { + struct stat st; + const int fd = open(kDevRandomPath, O_RDONLY); + fstat(fd, &st); + close(fd); + + return TestDescriptorClient(st.st_ino); +} + +TEST_F(IPCChannelTest, DescriptorTest) { + // Setup IPC channel. + MyChannelDescriptorListener listener(-1); + + IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER, + &listener); + chan.Connect(); + + base::ProcessHandle process_handle = SpawnChild(TEST_DESCRIPTOR_CLIENT, + &chan); + TestDescriptorServer(chan, process_handle); } #endif // defined(OS_POSIX) diff --git a/chrome/common/ipc_tests.cc b/chrome/common/ipc_tests.cc index f3a92ca..2544e43 100644 --- a/chrome/common/ipc_tests.cc +++ b/chrome/common/ipc_tests.cc @@ -110,6 +110,12 @@ base::ProcessHandle IPCChannelTest::SpawnChild(ChildType child_type, debug_on_start); channel->OnClientConnected(); break; + case TEST_DESCRIPTOR_CLIENT_SANDBOXED: + ret = MultiProcessTest::SpawnChild(L"RunTestDescriptorClientSandboxed", + fds_to_map, + debug_on_start); + channel->OnClientConnected(); + break; case TEST_REFLECTOR: ret = MultiProcessTest::SpawnChild(L"RunReflector", fds_to_map, diff --git a/chrome/common/ipc_tests.h b/chrome/common/ipc_tests.h index 609ebc6..3cefafe 100644 --- a/chrome/common/ipc_tests.h +++ b/chrome/common/ipc_tests.h @@ -13,6 +13,7 @@ enum ChildType { TEST_CLIENT, TEST_DESCRIPTOR_CLIENT, + TEST_DESCRIPTOR_CLIENT_SANDBOXED, TEST_REFLECTOR, FUZZER_SERVER }; |