blob: f4fc25c387ff19b86709feaa55f5f0044436704c [file] [log] [blame]
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -04001// libminijail_unittest.cpp
2// Copyright (C) 2016 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16// Test platform independent logic of Minijail using gtest.
17
18#include <errno.h>
19
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040020#include <fcntl.h>
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040021#include <sys/types.h>
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040022#include <sys/stat.h>
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040023#include <sys/wait.h>
24
25#include <gtest/gtest.h>
26
27#include "libminijail.h"
28#include "libminijail-private.h"
29#include "util.h"
30
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040031#if defined(__ANDROID__)
32const char *kShellPath = "/system/bin/sh";
33#else
34const char *kShellPath = "/bin/sh";
35#endif
36
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040037/* Prototypes needed only by test. */
38void *consumebytes(size_t length, char **buf, size_t *buflength);
39char *consumestr(char **buf, size_t *buflength);
Martin Pelikánab9eb442017-01-25 11:53:58 +110040size_t minijail_get_tmpfs_size(const struct minijail *);
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040041
42/* Silence unused variable warnings. */
43TEST(silence, silence_unused) {
44 EXPECT_STREQ(kLdPreloadEnvVar, kLdPreloadEnvVar);
45 EXPECT_STREQ(kFdEnvVar, kFdEnvVar);
46 EXPECT_STRNE(kFdEnvVar, kLdPreloadEnvVar);
47}
48
49TEST(consumebytes, zero) {
50 char buf[1024];
51 size_t len = sizeof(buf);
52 char *pos = &buf[0];
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040053 EXPECT_NE(nullptr, consumebytes(0, &pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040054 EXPECT_EQ(&buf[0], pos);
55 EXPECT_EQ(sizeof(buf), len);
56}
57
58TEST(consumebytes, exact) {
59 char buf[1024];
60 size_t len = sizeof(buf);
61 char *pos = &buf[0];
62 /* One past the end since it consumes the whole buffer. */
63 char *end = &buf[sizeof(buf)];
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040064 EXPECT_NE(nullptr, consumebytes(len, &pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040065 EXPECT_EQ((size_t)0, len);
66 EXPECT_EQ(end, pos);
67}
68
69TEST(consumebytes, half) {
70 char buf[1024];
71 size_t len = sizeof(buf);
72 char *pos = &buf[0];
73 /* One past the end since it consumes the whole buffer. */
74 char *end = &buf[sizeof(buf) / 2];
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040075 EXPECT_NE(nullptr, consumebytes(len / 2, &pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040076 EXPECT_EQ(sizeof(buf) / 2, len);
77 EXPECT_EQ(end, pos);
78}
79
80TEST(consumebytes, toolong) {
81 char buf[1024];
82 size_t len = sizeof(buf);
83 char *pos = &buf[0];
84 /* One past the end since it consumes the whole buffer. */
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040085 EXPECT_EQ(nullptr, consumebytes(len + 1, &pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040086 EXPECT_EQ(sizeof(buf), len);
87 EXPECT_EQ(&buf[0], pos);
88}
89
90TEST(consumestr, zero) {
91 char buf[1024];
92 size_t len = 0;
93 char *pos = &buf[0];
94 memset(buf, 0xff, sizeof(buf));
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040095 EXPECT_EQ(nullptr, consumestr(&pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040096 EXPECT_EQ((size_t)0, len);
97 EXPECT_EQ(&buf[0], pos);
98}
99
100TEST(consumestr, nonul) {
101 char buf[1024];
102 size_t len = sizeof(buf);
103 char *pos = &buf[0];
104 memset(buf, 0xff, sizeof(buf));
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400105 EXPECT_EQ(nullptr, consumestr(&pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -0400106 EXPECT_EQ(sizeof(buf), len);
107 EXPECT_EQ(&buf[0], pos);
108}
109
110TEST(consumestr, full) {
111 char buf[1024];
112 size_t len = sizeof(buf);
113 char *pos = &buf[0];
114 memset(buf, 0xff, sizeof(buf));
115 buf[sizeof(buf)-1] = '\0';
116 EXPECT_EQ((void *)buf, consumestr(&pos, &len));
117 EXPECT_EQ((size_t)0, len);
118 EXPECT_EQ(&buf[sizeof(buf)], pos);
119}
120
121TEST(consumestr, trailing_nul) {
122 char buf[1024];
123 size_t len = sizeof(buf) - 1;
124 char *pos = &buf[0];
125 memset(buf, 0xff, sizeof(buf));
126 buf[sizeof(buf)-1] = '\0';
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400127 EXPECT_EQ(nullptr, consumestr(&pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -0400128 EXPECT_EQ(sizeof(buf) - 1, len);
129 EXPECT_EQ(&buf[0], pos);
130}
131
132class MarshalTest : public ::testing::Test {
133 protected:
134 virtual void SetUp() {
135 m_ = minijail_new();
136 j_ = minijail_new();
137 size_ = minijail_size(m_);
138 }
139 virtual void TearDown() {
140 minijail_destroy(m_);
141 minijail_destroy(j_);
142 }
143
144 char buf_[4096];
145 struct minijail *m_;
146 struct minijail *j_;
147 size_t size_;
148};
149
150TEST_F(MarshalTest, empty) {
151 ASSERT_EQ(0, minijail_marshal(m_, buf_, sizeof(buf_)));
152 EXPECT_EQ(0, minijail_unmarshal(j_, buf_, size_));
153}
154
155TEST_F(MarshalTest, 0xff) {
156 memset(buf_, 0xff, sizeof(buf_));
157 /* Should fail on the first consumestr since a NUL will never be found. */
158 EXPECT_EQ(-EINVAL, minijail_unmarshal(j_, buf_, sizeof(buf_)));
159}
160
161TEST(Test, minijail_run_pid_pipes_no_preload) {
162 pid_t pid;
163 int child_stdin, child_stdout, child_stderr;
164 int mj_run_ret;
165 ssize_t write_ret, read_ret;
166 const size_t buf_len = 128;
167 char buf[buf_len];
168 int status;
169#if defined(__ANDROID__)
170 char filename[] = "/system/bin/cat";
171#else
172 char filename[] = "/bin/cat";
173#endif
174 char teststr[] = "test\n";
175 size_t teststr_len = strlen(teststr);
176 char *argv[4];
177
178 struct minijail *j = minijail_new();
179
180 argv[0] = filename;
181 argv[1] = NULL;
182 mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv,
183 &pid,
184 &child_stdin, &child_stdout,
185 NULL);
186 EXPECT_EQ(mj_run_ret, 0);
187
188 write_ret = write(child_stdin, teststr, teststr_len);
189 EXPECT_EQ(write_ret, (int)teststr_len);
190
191 read_ret = read(child_stdout, buf, 8);
192 EXPECT_EQ(read_ret, (int)teststr_len);
193 buf[teststr_len] = 0;
194 EXPECT_EQ(strcmp(buf, teststr), 0);
195
196 EXPECT_EQ(kill(pid, SIGTERM), 0);
197 waitpid(pid, &status, 0);
198 ASSERT_TRUE(WIFSIGNALED(status));
199 EXPECT_EQ(WTERMSIG(status), SIGTERM);
200
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400201 argv[0] = (char*)kShellPath;
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -0400202 argv[1] = "-c";
203 argv[2] = "echo test >&2";
204 argv[3] = NULL;
205 mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv, &pid,
206 &child_stdin, &child_stdout,
207 &child_stderr);
208 EXPECT_EQ(mj_run_ret, 0);
209
210 read_ret = read(child_stderr, buf, buf_len);
211 EXPECT_GE(read_ret, (int)teststr_len);
212
213 waitpid(pid, &status, 0);
214 ASSERT_TRUE(WIFEXITED(status));
215 EXPECT_EQ(WEXITSTATUS(status), 0);
216
217 minijail_destroy(j);
218}
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400219
220TEST(Test, test_minijail_no_fd_leaks) {
221 pid_t pid;
222 int child_stdout;
223 int mj_run_ret;
224 ssize_t read_ret;
225 const size_t buf_len = 128;
226 char buf[buf_len];
227 char script[buf_len];
228 int status;
229 char *argv[4];
230
231 int dev_null = open("/dev/null", O_RDONLY);
232 ASSERT_NE(dev_null, -1);
233 snprintf(script,
234 sizeof(script),
235 "[ -e /proc/self/fd/%d ] && echo yes || echo no",
236 dev_null);
237
238 struct minijail *j = minijail_new();
239
240 argv[0] = (char*)kShellPath;
241 argv[1] = "-c";
242 argv[2] = script;
243 argv[3] = NULL;
244 mj_run_ret = minijail_run_pid_pipes_no_preload(
245 j, argv[0], argv, &pid, NULL, &child_stdout, NULL);
246 EXPECT_EQ(mj_run_ret, 0);
247
248 read_ret = read(child_stdout, buf, buf_len);
249 EXPECT_GE(read_ret, 0);
250 buf[read_ret] = '\0';
251 EXPECT_STREQ(buf, "yes\n");
252
253 waitpid(pid, &status, 0);
254 ASSERT_TRUE(WIFEXITED(status));
255 EXPECT_EQ(WEXITSTATUS(status), 0);
256
257 minijail_close_open_fds(j);
258 mj_run_ret = minijail_run_pid_pipes_no_preload(
259 j, argv[0], argv, &pid, NULL, &child_stdout, NULL);
260 EXPECT_EQ(mj_run_ret, 0);
261
262 read_ret = read(child_stdout, buf, buf_len);
263 EXPECT_GE(read_ret, 0);
264 buf[read_ret] = '\0';
265 EXPECT_STREQ(buf, "no\n");
266
267 waitpid(pid, &status, 0);
268 ASSERT_TRUE(WIFEXITED(status));
269 EXPECT_EQ(WEXITSTATUS(status), 0);
270
271 minijail_destroy(j);
272
273 close(dev_null);
274}
Martin Pelikánab9eb442017-01-25 11:53:58 +1100275
276TEST(Test, parse_size) {
277 size_t size;
278
279 ASSERT_EQ(0, parse_size(&size, "42"));
280 ASSERT_EQ(42U, size);
281
282 ASSERT_EQ(0, parse_size(&size, "16K"));
283 ASSERT_EQ(16384U, size);
284
285 ASSERT_EQ(0, parse_size(&size, "1M"));
286 ASSERT_EQ(1024U * 1024, size);
287
288 uint64_t gigabyte = 1024ULL * 1024 * 1024;
289 ASSERT_EQ(0, parse_size(&size, "3G"));
290 ASSERT_EQ(3U, size / gigabyte);
291 ASSERT_EQ(0U, size % gigabyte);
292
293 ASSERT_EQ(0, parse_size(&size, "4294967294"));
294 ASSERT_EQ(3U, size / gigabyte);
295 ASSERT_EQ(gigabyte - 2, size % gigabyte);
296
297#if __WORDSIZE == 64
298 uint64_t exabyte = gigabyte * 1024 * 1024 * 1024;
299 ASSERT_EQ(0, parse_size(&size, "9E"));
300 ASSERT_EQ(9U, size / exabyte);
301 ASSERT_EQ(0U, size % exabyte);
302
303 ASSERT_EQ(0, parse_size(&size, "15E"));
304 ASSERT_EQ(15U, size / exabyte);
305 ASSERT_EQ(0U, size % exabyte);
306
307 ASSERT_EQ(0, parse_size(&size, "18446744073709551614"));
308 ASSERT_EQ(15U, size / exabyte);
309 ASSERT_EQ(exabyte - 2, size % exabyte);
310
311 ASSERT_EQ(-ERANGE, parse_size(&size, "16E"));
312 ASSERT_EQ(-ERANGE, parse_size(&size, "19E"));
313#elif __WORDSIZE == 32
314 ASSERT_EQ(-ERANGE, parse_size(&size, "5G"));
315 ASSERT_EQ(-ERANGE, parse_size(&size, "9G"));
316 ASSERT_EQ(-ERANGE, parse_size(&size, "9E"));
317#endif
318
319 ASSERT_EQ(-EINVAL, parse_size(&size, ""));
320 ASSERT_EQ(-EINVAL, parse_size(&size, "14u"));
321 ASSERT_EQ(-EINVAL, parse_size(&size, "14.2G"));
322 ASSERT_EQ(-EINVAL, parse_size(&size, "7GTPE"));
323 ASSERT_EQ(-EINVAL, parse_size(&size, "-1G"));
324 ASSERT_EQ(-EINVAL, parse_size(&size, "; /bin/rm -- "));
325}