Browse files

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
  • Loading branch information...
1 parent 901ece8 commit bd267a79db3433f432a28c744349cdadf51df633 jeremy@chromium.org committed Feb 10, 2009
View
2 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>";
};
View
140 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,49 +19,56 @@
#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;
FileDescriptor descriptor;
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)
View
6 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,
View
1 chrome/common/ipc_tests.h
@@ -13,6 +13,7 @@
enum ChildType {
TEST_CLIENT,
TEST_DESCRIPTOR_CLIENT,
+ TEST_DESCRIPTOR_CLIENT_SANDBOXED,
TEST_REFLECTOR,
FUZZER_SERVER
};

0 comments on commit bd267a7

Please sign in to comment.