• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
20 #include <fcntl.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #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 
31 #if defined(__ANDROID__)
32 const char *kShellPath = "/system/bin/sh";
33 #else
34 const char *kShellPath = "/bin/sh";
35 #endif
36 
37 /* Prototypes needed only by test. */
38 void *consumebytes(size_t length, char **buf, size_t *buflength);
39 char *consumestr(char **buf, size_t *buflength);
40 size_t minijail_get_tmpfs_size(const struct minijail *);
41 
42 /* Silence unused variable warnings. */
TEST(silence,silence_unused)43 TEST(silence, silence_unused) {
44   EXPECT_STREQ(kLdPreloadEnvVar, kLdPreloadEnvVar);
45   EXPECT_STREQ(kFdEnvVar, kFdEnvVar);
46   EXPECT_STRNE(kFdEnvVar, kLdPreloadEnvVar);
47 }
48 
TEST(consumebytes,zero)49 TEST(consumebytes, zero) {
50   char buf[1024];
51   size_t len = sizeof(buf);
52   char *pos = &buf[0];
53   EXPECT_NE(nullptr, consumebytes(0, &pos, &len));
54   EXPECT_EQ(&buf[0], pos);
55   EXPECT_EQ(sizeof(buf), len);
56 }
57 
TEST(consumebytes,exact)58 TEST(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)];
64   EXPECT_NE(nullptr, consumebytes(len, &pos, &len));
65   EXPECT_EQ((size_t)0, len);
66   EXPECT_EQ(end, pos);
67 }
68 
TEST(consumebytes,half)69 TEST(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];
75   EXPECT_NE(nullptr, consumebytes(len / 2, &pos, &len));
76   EXPECT_EQ(sizeof(buf) / 2, len);
77   EXPECT_EQ(end, pos);
78 }
79 
TEST(consumebytes,toolong)80 TEST(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. */
85   EXPECT_EQ(nullptr, consumebytes(len + 1, &pos, &len));
86   EXPECT_EQ(sizeof(buf), len);
87   EXPECT_EQ(&buf[0], pos);
88 }
89 
TEST(consumestr,zero)90 TEST(consumestr, zero) {
91   char buf[1024];
92   size_t len = 0;
93   char *pos = &buf[0];
94   memset(buf, 0xff, sizeof(buf));
95   EXPECT_EQ(nullptr, consumestr(&pos, &len));
96   EXPECT_EQ((size_t)0, len);
97   EXPECT_EQ(&buf[0], pos);
98 }
99 
TEST(consumestr,nonul)100 TEST(consumestr, nonul) {
101   char buf[1024];
102   size_t len = sizeof(buf);
103   char *pos = &buf[0];
104   memset(buf, 0xff, sizeof(buf));
105   EXPECT_EQ(nullptr, consumestr(&pos, &len));
106   EXPECT_EQ(sizeof(buf), len);
107   EXPECT_EQ(&buf[0], pos);
108 }
109 
TEST(consumestr,full)110 TEST(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 
TEST(consumestr,trailing_nul)121 TEST(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';
127   EXPECT_EQ(nullptr, consumestr(&pos, &len));
128   EXPECT_EQ(sizeof(buf) - 1, len);
129   EXPECT_EQ(&buf[0], pos);
130 }
131 
132 class MarshalTest : public ::testing::Test {
133  protected:
SetUp()134   virtual void SetUp() {
135     m_ = minijail_new();
136     j_ = minijail_new();
137     size_ = minijail_size(m_);
138   }
TearDown()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 
TEST_F(MarshalTest,empty)150 TEST_F(MarshalTest, empty) {
151   ASSERT_EQ(0, minijail_marshal(m_, buf_, sizeof(buf_)));
152   EXPECT_EQ(0, minijail_unmarshal(j_, buf_, size_));
153 }
154 
155 TEST_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 
TEST(Test,minijail_run_pid_pipes_no_preload)161 TEST(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 
201   argv[0] = (char*)kShellPath;
202   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 }
219 
TEST(Test,test_minijail_no_fd_leaks)220 TEST(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 }
275 
TEST(Test,parse_size)276 TEST(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   ASSERT_EQ(-EINVAL, parse_size(&size, "7GTPE"));
314 #elif __WORDSIZE == 32
315   ASSERT_EQ(-ERANGE, parse_size(&size, "5G"));
316   ASSERT_EQ(-ERANGE, parse_size(&size, "9G"));
317   ASSERT_EQ(-ERANGE, parse_size(&size, "9E"));
318   ASSERT_EQ(-ERANGE, parse_size(&size, "7GTPE"));
319 #endif
320 
321   ASSERT_EQ(-EINVAL, parse_size(&size, ""));
322   ASSERT_EQ(-EINVAL, parse_size(&size, "14u"));
323   ASSERT_EQ(-EINVAL, parse_size(&size, "14.2G"));
324   ASSERT_EQ(-EINVAL, parse_size(&size, "-1G"));
325   ASSERT_EQ(-EINVAL, parse_size(&size, "; /bin/rm -- "));
326 }
327