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

Side by Side Diff: sandbox/linux/services/broker_process_unittest.cc

Issue 11557025: Linux sandbox: add a new low-level broker process mechanism. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add file writing test. Created 8 years 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 #include "sandbox/linux/services/broker_process.h"
2
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 #include <sys/wait.h>
8 #include <string>
9 #include <vector>
10
11 #include "base/logging.h"
12 #include "sandbox/linux/tests/unit_tests.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace sandbox {
16
17 TEST(BrokerProcess, CreateAndDestroy) {
18 std::vector<std::string> read_whitelist;
19 read_whitelist.push_back("/proc/cpuinfo");
20
21 BrokerProcess* open_broker = new BrokerProcess(read_whitelist,
22 std::vector<std::string>());
23 ASSERT_TRUE(open_broker->Init(NULL));
24 pid_t broker_pid = open_broker->broker_pid();
25 delete(open_broker);
26
27 // Now we check that the broker has exited properly.
28 int status = 0;
29 EXPECT_EQ(waitpid(broker_pid, &status, 0), broker_pid);
30 EXPECT_TRUE(WIFEXITED(status));
31 EXPECT_EQ(WEXITSTATUS(status), 0);
32 }
33
34 TEST(BrokerProcess, TestOpenNull) {
35 const std::vector<std::string> empty;
36 BrokerProcess open_broker(empty, empty);
37 ASSERT_TRUE(open_broker.Init(NULL));
38
39 int fd = open_broker.Open(NULL, O_RDONLY);
40 EXPECT_EQ(fd, -EFAULT);
41 }
42
43 void TestOpenFilePerms(bool fast_check_in_client) {
44 const char kR_WhiteListed[] = "/proc/DOESNOTEXIST1";
45 const char kW_WhiteListed[] = "/proc/DOESNOTEXIST2";
46 const char kRW_WhiteListed[] = "/proc/DOESNOTEXIST3";
47 const char k_NotWhitelisted[] = "/proc/DOESNOTEXIST4";
48
49 std::vector<std::string> read_whitelist;
50 read_whitelist.push_back(kR_WhiteListed);
51 read_whitelist.push_back(kRW_WhiteListed);
52
53 std::vector<std::string> write_whitelist;
54 write_whitelist.push_back(kW_WhiteListed);
55 write_whitelist.push_back(kRW_WhiteListed);
56
57 BrokerProcess open_broker(read_whitelist,
58 write_whitelist,
59 fast_check_in_client);
60 ASSERT_TRUE(open_broker.Init(NULL));
61
62 int fd = -1;
63 fd = open_broker.Open(kR_WhiteListed, O_RDONLY);
64 EXPECT_EQ(fd, -ENOENT);
65 fd = open_broker.Open(kR_WhiteListed, O_WRONLY);
66 EXPECT_EQ(fd, -EPERM);
67 fd = open_broker.Open(kR_WhiteListed, O_RDWR);
68 EXPECT_EQ(fd, -EPERM);
69
70 fd = open_broker.Open(kW_WhiteListed, O_RDONLY);
71 EXPECT_EQ(fd, -EPERM);
72 fd = open_broker.Open(kW_WhiteListed, O_WRONLY);
73 EXPECT_EQ(fd, -ENOENT);
74 fd = open_broker.Open(kW_WhiteListed, O_RDWR);
75 EXPECT_EQ(fd, -EPERM);
76
77 fd = open_broker.Open(kRW_WhiteListed, O_RDONLY);
78 EXPECT_EQ(fd, -ENOENT);
79 fd = open_broker.Open(kRW_WhiteListed, O_WRONLY);
80 EXPECT_EQ(fd, -ENOENT);
81 fd = open_broker.Open(kRW_WhiteListed, O_RDWR);
82 EXPECT_EQ(fd, -ENOENT);
83
84 fd = open_broker.Open(k_NotWhitelisted, O_RDONLY);
85 EXPECT_EQ(fd, -EPERM);
86 fd = open_broker.Open(k_NotWhitelisted, O_WRONLY);
87 EXPECT_EQ(fd, -EPERM);
88 fd = open_broker.Open(k_NotWhitelisted, O_RDWR);
89 EXPECT_EQ(fd, -EPERM);
90 }
Markus (顧孟勤) 2012/12/14 00:40:34 Can you test with some invalid value too? E.g. O_R
jln (very slow on Chromium) 2012/12/14 01:11:29 Done.
91
92 // Run the same thing twice. The second time, we make sure that no security
93 // check is performed on the client.
94 TEST(BrokerProcess, OpenFilePermsWithClientCheck) {
95 TestOpenFilePerms(true /* fast_check_in_client */);
96 }
97
98 TEST(BrokerProcess, OpenOpenFilePermsNoClientCheck) {
99 TestOpenFilePerms(false /* fast_check_in_client */);
100 }
101
102
103 void TestOpenCpuinfo(bool fast_check_in_client) {
104 const char kFileCpuInfo[] = "/proc/cpuinfo";
105 std::vector<std::string> read_whitelist;
106 read_whitelist.push_back(kFileCpuInfo);
107
108 BrokerProcess* open_broker = new BrokerProcess(read_whitelist,
109 std::vector<std::string>(),
110 fast_check_in_client);
111 ASSERT_TRUE(open_broker->Init(NULL));
112 pid_t broker_pid = open_broker->broker_pid();
113
114 int fd = -1;
115 fd = open_broker->Open(kFileCpuInfo, O_RDWR);
116 EXPECT_EQ(fd, -EPERM);
117
118 // Open cpuinfo via the broker.
119 int cpuinfo_fd = open_broker->Open(kFileCpuInfo, O_RDONLY);
120 ASSERT_GE(cpuinfo_fd, 0);
121 char buf[3];
122 memset(buf, 0, sizeof(buf));
123 int read_len1 = read(cpuinfo_fd, buf, sizeof(buf));
124 EXPECT_GT(read_len1, 0);
125
126 // Open cpuinfo directly.
127 int cpuinfo_fd2 = open(kFileCpuInfo, O_RDONLY);
128 ASSERT_GE(cpuinfo_fd2, 0);
129 char buf2[3];
130 memset(buf2, 1, sizeof(buf2));
131 int read_len2 = read(cpuinfo_fd2, buf2, sizeof(buf2));
132 EXPECT_GT(read_len1, 0);
133
134 // The following is not guaranteed true, but will be in practice.
135 EXPECT_EQ(read_len1, read_len2);
136 // Compare the cpuinfo as returned by the broker with the one we opened
137 // ourselves.
138 EXPECT_EQ(memcmp(buf, buf2, read_len1), 0);
139
140 if (fd >= 0)
141 close(fd);
142 if (cpuinfo_fd >= 0)
143 close(cpuinfo_fd);
144 if (cpuinfo_fd2 >= 0)
145 close(cpuinfo_fd);
146
147 delete(open_broker);
148
149 // Now we check that the broker has exited properly.
150 int status = 0;
151 EXPECT_EQ(waitpid(broker_pid, &status, 0), broker_pid);
152 EXPECT_TRUE(WIFEXITED(status));
153 EXPECT_EQ(WEXITSTATUS(status), 0);
154 }
155
156 // Run the same thing twice. The second time, we make sure that no security
157 // check is performed on the client.
158 TEST(BrokerProcess, OpenCpuinfoWithClientCheck) {
159 TestOpenCpuinfo(true /* fast_check_in_client */);
160 }
161
162 TEST(BrokerProcess, OpenCpuinfoNoClientCheck) {
163 TestOpenCpuinfo(false /* fast_check_in_client */);
164 }
165
166 TEST(BrokerProcess, OpenFileRW) {
167 char templatename[] = "BrokerProcessXXXXXX";
168 int tempfile = mkstemp(templatename);
169 ASSERT_GE(tempfile, 0);
170 char tempfile_name[2048];
171 int written = snprintf(tempfile_name, sizeof(tempfile_name),
172 "/proc/self/fd/%d", tempfile);
173 ASSERT_LT(written, static_cast<int>(sizeof(tempfile_name)));
174
175 std::vector<std::string> whitelist;
176 whitelist.push_back(tempfile_name);
177
178 BrokerProcess open_broker(whitelist, whitelist);
179 ASSERT_TRUE(open_broker.Init(NULL));
180
181 int tempfile2 = -1;
182 tempfile2 = open_broker.Open(tempfile_name, O_RDWR);
183 ASSERT_GE(tempfile2, 0);
184
185 // Write to the descriptor opened by the broker.
186 char test_text[] = "TESTTESTTEST";
187 ssize_t len = write(tempfile2, test_text, sizeof(test_text));
188 ASSERT_EQ(len, static_cast<ssize_t>(sizeof(test_text)));
189
190 ASSERT_EQ(close(tempfile2), 0);
191
192 // Read back from the original file descriptor what we wrote through
193 // the descriptor provided by the broker.
194 char buf[1024];
195 len = read(tempfile, buf, sizeof(buf));
196
197 ASSERT_EQ(len, static_cast<ssize_t>(sizeof(test_text)));
198 ASSERT_EQ(memcmp(test_text, buf, sizeof(test_text)), 0);
199
200 // Cleanup the temporary file.
201 char tempfile_full_path[2048];
202 // Make sure tempfile_full_path will terminate with a 0.
203 bzero(tempfile_full_path, sizeof(tempfile_full_path));
Markus (顧孟勤) 2012/12/14 00:40:34 bzero()? Really? Do we use that anywhere else? I
jln (very slow on Chromium) 2012/12/14 01:11:29 Done.
204 ssize_t ret = readlink(tempfile_name, tempfile_full_path,
205 sizeof(tempfile_full_path));
206 ASSERT_GT(ret, 0);
207 // Make sure we still have a trailing zero in tempfile_full_path.
208 ASSERT_LT(ret, static_cast<ssize_t>(sizeof(tempfile_full_path)));
209 ASSERT_EQ(unlink(tempfile_full_path), 0);
210 }
211
212 // Sandbox test because we could get a SIGPIPE.
213 SANDBOX_TEST(BrokerProcess, BrokerDied) {
214 std::vector<std::string> read_whitelist;
215 read_whitelist.push_back("/proc/cpuinfo");
216
217 BrokerProcess open_broker(read_whitelist,
218 std::vector<std::string>(),
219 true /* fast_check_in_client */,
220 true /* quiet_failures_for_tests */);
221 SANDBOX_ASSERT(open_broker.Init(NULL));
222 pid_t broker_pid = open_broker.broker_pid();
223 SANDBOX_ASSERT(kill(broker_pid, SIGKILL) == 0);
224
225 // Now we check that the broker has exited properly.
226 int status = 0;
227 SANDBOX_ASSERT(waitpid(broker_pid, &status, 0) == broker_pid);
228 SANDBOX_ASSERT(WIFSIGNALED(status));
229 SANDBOX_ASSERT(WTERMSIG(status) == SIGKILL);
230 // Hopefully doing Open with a dead broker won't SIGPIPE us.
231 SANDBOX_ASSERT(open_broker.Open("/proc/cpuinfo", O_RDONLY) == -ENOMEM);
232 }
233
234 } // namespace sandbox
OLDNEW
« sandbox/linux/services/broker_process.cc ('K') | « sandbox/linux/services/broker_process.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698