Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(349)

Side by Side Diff: chrome/common/ipc_send_fds_test.cc

Issue 21223: Add test to check that FDs are sent through the OS X Sandbox ok. (Closed)
Patch Set: Created 11 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/chrome.xcodeproj/project.pbxproj ('k') | chrome/common/ipc_tests.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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
John Grabowski 2009/02/10 20:54:29 Perhaps add the bug name to the top of this file f
5 #include "build/build_config.h" 5 #include "build/build_config.h"
6 6
7 #include "chrome/common/ipc_tests.h" 7 #include "chrome/common/ipc_tests.h"
8 8
9 #if defined(OS_MACOSX)
10 extern "C" {
11 #include <sandbox.h>
12 }
13 #endif
9 #include <sys/stat.h> 14 #include <sys/stat.h>
10 15
11 #include "base/message_loop.h" 16 #include "base/message_loop.h"
12 #include "chrome/common/ipc_channel.h" 17 #include "chrome/common/ipc_channel.h"
13 #include "chrome/common/ipc_message_utils.h" 18 #include "chrome/common/ipc_message_utils.h"
14 19
15 #if defined(OS_POSIX) 20 #if defined(OS_POSIX)
16 21
22 namespace {
23
24 const char* kDevRandomPath = "/dev/random";
25
26 static void VerifyAndCloseDescriptor(int fd, ino_t inode_num) {
John Grabowski 2009/02/10 20:54:29 Perhaps a comment explaining why we need to compar
27 // Check that we can read from the FD.
28 char buf;
29 ssize_t amt_read = read(fd, &buf, 1);
30 ASSERT_EQ(amt_read, 1);
31
32 struct stat st;
33 ASSERT_EQ(fstat(fd, &st), 0);
34
35 ASSERT_EQ(close(fd), 0);
36 ASSERT_EQ(inode_num, st.st_ino);
37 }
38
17 class MyChannelDescriptorListener : public IPC::Channel::Listener { 39 class MyChannelDescriptorListener : public IPC::Channel::Listener {
18 public: 40 public:
41 MyChannelDescriptorListener(ino_t expected_inode_num)
42 : expected_inode_num_(expected_inode_num) {}
43
19 virtual void OnMessageReceived(const IPC::Message& message) { 44 virtual void OnMessageReceived(const IPC::Message& message) {
20 void* iter = NULL; 45 void* iter = NULL;
21 46
22 FileDescriptor descriptor; 47 FileDescriptor descriptor;
23 48
24 ASSERT_TRUE( 49 ASSERT_TRUE(
25 IPC::ParamTraits<FileDescriptor>::Read(&message, &iter, &descriptor)); 50 IPC::ParamTraits<FileDescriptor>::Read(&message, &iter, &descriptor));
26 VerifyDescriptor(&descriptor); 51
52 VerifyAndCloseDescriptor(descriptor.fd, expected_inode_num_);
27 MessageLoop::current()->Quit(); 53 MessageLoop::current()->Quit();
28 } 54 }
29 55
30 virtual void OnChannelError() { 56 virtual void OnChannelError() {
31 MessageLoop::current()->Quit(); 57 MessageLoop::current()->Quit();
32 } 58 }
33 59 private:
34 private: 60 ino_t expected_inode_num_;
35 static void VerifyDescriptor(FileDescriptor* descriptor) {
36 const int fd = open("/dev/null", O_RDONLY);
37 struct stat st1, st2;
38 fstat(fd, &st1);
39 close(fd);
40 fstat(descriptor->fd, &st2);
41 close(descriptor->fd);
42 ASSERT_EQ(st1.st_ino, st2.st_ino);
43 }
44 }; 61 };
45 62
46 TEST_F(IPCChannelTest, DescriptorTest) { 63 void TestDescriptorServer(IPC::Channel &chan,
47 // Setup IPC channel. 64 base::ProcessHandle process_handle) {
48 MyChannelDescriptorListener listener;
49
50 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
51 &listener);
52 chan.Connect();
53
54 base::ProcessHandle process_handle = SpawnChild(TEST_DESCRIPTOR_CLIENT,
55 &chan);
56 ASSERT_TRUE(process_handle); 65 ASSERT_TRUE(process_handle);
57 66
58 FileDescriptor descriptor; 67 FileDescriptor descriptor;
59 const int fd = open("/dev/null", O_RDONLY); 68 const int fd = open(kDevRandomPath, O_RDONLY);
60 ASSERT_GE(fd, 0); 69 ASSERT_GE(fd, 0);
61 descriptor.auto_close = true; 70 descriptor.auto_close = true;
62 descriptor.fd = fd; 71 descriptor.fd = fd;
63 72
64 IPC::Message* message = new IPC::Message(0, // routing_id 73 IPC::Message* message = new IPC::Message(0, // routing_id
65 3, // message type 74 3, // message type
66 IPC::Message::PRIORITY_NORMAL); 75 IPC::Message::PRIORITY_NORMAL);
67 IPC::ParamTraits<FileDescriptor>::Write(message, descriptor); 76 IPC::ParamTraits<FileDescriptor>::Write(message, descriptor);
68 chan.Send(message); 77 chan.Send(message);
69 78
70 // Run message loop. 79 // Run message loop.
71 MessageLoop::current()->Run(); 80 MessageLoop::current()->Run();
72 81
73 // Close Channel so client gets its OnChannelError() callback fired. 82 // Close Channel so client gets its OnChannelError() callback fired.
74 chan.Close(); 83 chan.Close();
75 84
76 // Cleanup child process. 85 // Cleanup child process.
77 EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000)); 86 EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000));
78 } 87 }
79 88
80 MULTIPROCESS_TEST_MAIN(RunTestDescriptorClient) { 89 int TestDescriptorClient(ino_t expected_inode_num) {
81 MessageLoopForIO main_message_loop; 90 MessageLoopForIO main_message_loop;
82 MyChannelDescriptorListener listener; 91 MyChannelDescriptorListener listener(expected_inode_num);
83 92
84 // setup IPC channel 93 // Setup IPC channel.
85 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT, 94 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT,
86 &listener); 95 &listener);
87 chan.Connect(); 96 chan.Connect();
97 MessageLoop::current()->Run();
88 98
89 // run message loop 99 return 0;
90 MessageLoop::current()->Run(); 100 }
91 // return true; 101
92 return NULL; 102 } // namespace
103
104 // ---------------------------------------------------------------------------
105 #if defined(OS_MACOSX)
106 // TODO(port): Make this test cross-platform.
107 MULTIPROCESS_TEST_MAIN(RunTestDescriptorClientSandboxed) {
108 struct stat st;
109 const int fd = open(kDevRandomPath, O_RDONLY);
110 fstat(fd, &st);
111 close(fd);
112
113 // Enable the Sandbox.
114 char* error_buff = NULL;
115 int error = sandbox_init(kSBXProfilePureComputation, SANDBOX_NAMED,
116 &error_buff);
117 bool success = (error == 0 && error_buff == NULL);
118 if (!success) {
119 return -1;
120 }
121
122 sandbox_free_error(error_buff);
123
124 // Make sure Sandbox is really enabled.
125 if (open(kDevRandomPath, O_RDONLY) != -1) {
126 LOG(ERROR) << "Sandbox wasn't properly enabled";
127 return -1;
128 }
129
130 // See if we can receive a file descriptor.
131 return TestDescriptorClient(st.st_ino);
132 }
133
134 TEST_F(IPCChannelTest, DescriptorTestSandboxed) {
135 // Setup IPC channel.
136 MyChannelDescriptorListener listener(-1);
137
138 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
139 &listener);
140 chan.Connect();
141
142 base::ProcessHandle process_handle = SpawnChild(
143 TEST_DESCRIPTOR_CLIENT_SANDBOXED,
144 &chan);
145 TestDescriptorServer(chan, process_handle);
146 }
147 #endif // defined(OS_MACOSX)
148
149 MULTIPROCESS_TEST_MAIN(RunTestDescriptorClient) {
150 struct stat st;
151 const int fd = open(kDevRandomPath, O_RDONLY);
152 fstat(fd, &st);
153 close(fd);
154
155 return TestDescriptorClient(st.st_ino);
156 }
157
158 TEST_F(IPCChannelTest, DescriptorTest) {
159 // Setup IPC channel.
160 MyChannelDescriptorListener listener(-1);
161
162 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
163 &listener);
164 chan.Connect();
165
166 base::ProcessHandle process_handle = SpawnChild(TEST_DESCRIPTOR_CLIENT,
167 &chan);
168 TestDescriptorServer(chan, process_handle);
93 } 169 }
94 170
95 #endif // defined(OS_POSIX) 171 #endif // defined(OS_POSIX)
OLDNEW
« no previous file with comments | « chrome/chrome.xcodeproj/project.pbxproj ('k') | chrome/common/ipc_tests.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698