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

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

Issue 155905: Separates ipc code from common (http://crbug.com/16829) (Closed)
Patch Set: Fixes reference to 'common_message_traits' it's actually 'common_param_traits' Created 11 years, 5 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/common/ipc_message_utils.cc ('k') | chrome/common/ipc_sync_channel.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "build/build_config.h"
6
7 #include "chrome/common/ipc_tests.h"
8
9 #if defined(OS_MACOSX)
10 extern "C" {
11 #include <sandbox.h>
12 }
13 #endif
14 #include <fcntl.h>
15 #include <sys/stat.h>
16
17 #include "base/eintr_wrapper.h"
18 #include "base/message_loop.h"
19 #include "chrome/common/ipc_channel.h"
20 #include "chrome/common/ipc_message_utils.h"
21
22 #if defined(OS_POSIX)
23
24 namespace {
25
26 const unsigned kNumFDsToSend = 20;
27 const char* kDevZeroPath = "/dev/zero";
28
29 static void VerifyAndCloseDescriptor(int fd, ino_t inode_num) {
30 // Check that we can read from the FD.
31 char buf;
32 ssize_t amt_read = read(fd, &buf, 1);
33 ASSERT_EQ(amt_read, 1);
34 ASSERT_EQ(buf, 0); // /dev/zero always reads NUL bytes.
35
36 struct stat st;
37 ASSERT_EQ(fstat(fd, &st), 0);
38
39 ASSERT_EQ(close(fd), 0);
40
41 // We compare iNode numbers to check that the file sent over the wire
42 // was actually the same physical file as the one we were expecting.
43 ASSERT_EQ(inode_num, st.st_ino);
44 }
45
46 class MyChannelDescriptorListener : public IPC::Channel::Listener {
47 public:
48 MyChannelDescriptorListener(ino_t expected_inode_num)
49 : expected_inode_num_(expected_inode_num),
50 num_fds_received_(0) {}
51
52 virtual void OnMessageReceived(const IPC::Message& message) {
53 void* iter = NULL;
54
55 ++num_fds_received_;
56 base::FileDescriptor descriptor;
57
58 ASSERT_TRUE(
59 IPC::ParamTraits<base::FileDescriptor>::Read(
60 &message, &iter, &descriptor));
61
62 VerifyAndCloseDescriptor(descriptor.fd, expected_inode_num_);
63 if (num_fds_received_ == kNumFDsToSend) {
64 MessageLoop::current()->Quit();
65 }
66 }
67
68 virtual void OnChannelError() {
69 MessageLoop::current()->Quit();
70 }
71 private:
72 ino_t expected_inode_num_;
73 unsigned num_fds_received_;
74 };
75
76 void TestDescriptorServer(IPC::Channel &chan,
77 base::ProcessHandle process_handle) {
78 ASSERT_TRUE(process_handle);
79
80 for (unsigned i = 0; i < kNumFDsToSend; ++i) {
81 base::FileDescriptor descriptor;
82 const int fd = open(kDevZeroPath, O_RDONLY);
83 ASSERT_GE(fd, 0);
84 descriptor.auto_close = true;
85 descriptor.fd = fd;
86
87 IPC::Message* message = new IPC::Message(0, // routing_id
88 3, // message type
89 IPC::Message::PRIORITY_NORMAL);
90 IPC::ParamTraits<base::FileDescriptor>::Write(message, descriptor);
91 chan.Send(message);
92 }
93
94 // Run message loop.
95 MessageLoop::current()->Run();
96
97 // Close Channel so client gets its OnChannelError() callback fired.
98 chan.Close();
99
100 // Cleanup child process.
101 EXPECT_TRUE(base::WaitForSingleProcess(process_handle, 5000));
102 }
103
104 int TestDescriptorClient(ino_t expected_inode_num) {
105 MessageLoopForIO main_message_loop;
106 MyChannelDescriptorListener listener(expected_inode_num);
107
108 // Setup IPC channel.
109 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_CLIENT,
110 &listener);
111 chan.Connect();
112 MessageLoop::current()->Run();
113
114 return 0;
115 }
116
117 } // namespace
118
119 // ---------------------------------------------------------------------------
120 #if defined(OS_MACOSX)
121 // TODO(port): Make this test cross-platform.
122 MULTIPROCESS_TEST_MAIN(RunTestDescriptorClientSandboxed) {
123 struct stat st;
124 const int fd = open(kDevZeroPath, O_RDONLY);
125 fstat(fd, &st);
126 HANDLE_EINTR(close(fd));
127
128 // Enable the Sandbox.
129 char* error_buff = NULL;
130 int error = sandbox_init(kSBXProfilePureComputation, SANDBOX_NAMED,
131 &error_buff);
132 bool success = (error == 0 && error_buff == NULL);
133 if (!success) {
134 return -1;
135 }
136
137 sandbox_free_error(error_buff);
138
139 // Make sure Sandbox is really enabled.
140 if (open(kDevZeroPath, O_RDONLY) != -1) {
141 LOG(ERROR) << "Sandbox wasn't properly enabled";
142 return -1;
143 }
144
145 // See if we can receive a file descriptor.
146 return TestDescriptorClient(st.st_ino);
147 }
148
149 // Test that FDs are correctly sent to a sandboxed process.
150 TEST_F(IPCChannelTest, DescriptorTestSandboxed) {
151 // Setup IPC channel.
152 MyChannelDescriptorListener listener(-1);
153
154 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
155 &listener);
156 chan.Connect();
157
158 base::ProcessHandle process_handle = SpawnChild(
159 TEST_DESCRIPTOR_CLIENT_SANDBOXED,
160 &chan);
161 TestDescriptorServer(chan, process_handle);
162 }
163 #endif // defined(OS_MACOSX)
164
165 MULTIPROCESS_TEST_MAIN(RunTestDescriptorClient) {
166 struct stat st;
167 const int fd = open(kDevZeroPath, O_RDONLY);
168 fstat(fd, &st);
169 HANDLE_EINTR(close(fd));
170
171 return TestDescriptorClient(st.st_ino);
172 }
173
174 TEST_F(IPCChannelTest, DescriptorTest) {
175 // Setup IPC channel.
176 MyChannelDescriptorListener listener(-1);
177
178 IPC::Channel chan(kTestClientChannel, IPC::Channel::MODE_SERVER,
179 &listener);
180 chan.Connect();
181
182 base::ProcessHandle process_handle = SpawnChild(TEST_DESCRIPTOR_CLIENT,
183 &chan);
184 TestDescriptorServer(chan, process_handle);
185 }
186
187 #endif // defined(OS_POSIX)
OLDNEW
« no previous file with comments | « chrome/common/ipc_message_utils.cc ('k') | chrome/common/ipc_sync_channel.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698