1 /* libminijail_unittest.c
2  * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  *
6  * Test platform independent logic of minijail.
7  */
8 
9 #include <errno.h>
10 
11 #include <sys/types.h>
12 #include <sys/wait.h>
13 
14 #include "test_harness.h"
15 
16 #include "libminijail.h"
17 #include "libminijail-private.h"
18 
19 /* Prototypes needed only by test. */
20 void *consumebytes(size_t length, char **buf, size_t *buflength);
21 char *consumestr(char **buf, size_t *buflength);
22 
23 /* Silence unused variable warnings. */
TEST(silence_unused)24 TEST(silence_unused) {
25   EXPECT_STREQ(kLdPreloadEnvVar, kLdPreloadEnvVar);
26   EXPECT_STREQ(kFdEnvVar, kFdEnvVar);
27   EXPECT_STRNE(kFdEnvVar, kLdPreloadEnvVar);
28 }
29 
TEST(consumebytes_zero)30 TEST(consumebytes_zero) {
31   char buf[1024];
32   size_t len = sizeof(buf);
33   char *pos = &buf[0];
34   EXPECT_NE(NULL, consumebytes(0, &pos, &len));
35   EXPECT_EQ(&buf[0], pos);
36   EXPECT_EQ(sizeof(buf), len);
37 }
38 
TEST(consumebytes_exact)39 TEST(consumebytes_exact) {
40   char buf[1024];
41   size_t len = sizeof(buf);
42   char *pos = &buf[0];
43   /* One past the end since it consumes the whole buffer. */
44   char *end = &buf[sizeof(buf)];
45   EXPECT_NE(NULL, consumebytes(len, &pos, &len));
46   EXPECT_EQ((size_t)0, len);
47   EXPECT_EQ(end, pos);
48 }
49 
TEST(consumebytes_half)50 TEST(consumebytes_half) {
51   char buf[1024];
52   size_t len = sizeof(buf);
53   char *pos = &buf[0];
54   /* One past the end since it consumes the whole buffer. */
55   char *end = &buf[sizeof(buf) / 2];
56   EXPECT_NE(NULL, consumebytes(len / 2, &pos, &len));
57   EXPECT_EQ(sizeof(buf) / 2, len);
58   EXPECT_EQ(end, pos);
59 }
60 
TEST(consumebytes_toolong)61 TEST(consumebytes_toolong) {
62   char buf[1024];
63   size_t len = sizeof(buf);
64   char *pos = &buf[0];
65   /* One past the end since it consumes the whole buffer. */
66   EXPECT_EQ(NULL, consumebytes(len + 1, &pos, &len));
67   EXPECT_EQ(sizeof(buf), len);
68   EXPECT_EQ(&buf[0], pos);
69 }
70 
TEST(consumestr_zero)71 TEST(consumestr_zero) {
72   char buf[1024];
73   size_t len = 0;
74   char *pos = &buf[0];
75   memset(buf, 0xff, sizeof(buf));
76   EXPECT_EQ(NULL, consumestr(&pos, &len));
77   EXPECT_EQ((size_t)0, len);
78   EXPECT_EQ(&buf[0], pos);
79 }
80 
TEST(consumestr_nonul)81 TEST(consumestr_nonul) {
82   char buf[1024];
83   size_t len = sizeof(buf);
84   char *pos = &buf[0];
85   memset(buf, 0xff, sizeof(buf));
86   EXPECT_EQ(NULL, consumestr(&pos, &len));
87   EXPECT_EQ(sizeof(buf), len);
88   EXPECT_EQ(&buf[0], pos);
89 }
90 
TEST(consumestr_full)91 TEST(consumestr_full) {
92   char buf[1024];
93   size_t len = sizeof(buf);
94   char *pos = &buf[0];
95   memset(buf, 0xff, sizeof(buf));
96   buf[sizeof(buf)-1] = '\0';
97   EXPECT_EQ((void *)buf, consumestr(&pos, &len));
98   EXPECT_EQ((size_t)0, len);
99   EXPECT_EQ(&buf[sizeof(buf)], pos);
100 }
101 
TEST(consumestr_trailing_nul)102 TEST(consumestr_trailing_nul) {
103   char buf[1024];
104   size_t len = sizeof(buf) - 1;
105   char *pos = &buf[0];
106   memset(buf, 0xff, sizeof(buf));
107   buf[sizeof(buf)-1] = '\0';
108   EXPECT_EQ(NULL, consumestr(&pos, &len));
109   EXPECT_EQ(sizeof(buf) - 1, len);
110   EXPECT_EQ(&buf[0], pos);
111 }
112 
FIXTURE(marshal)113 FIXTURE(marshal) {
114   char buf[4096];
115   struct minijail *m;
116   struct minijail *j;
117   size_t size;
118 };
119 
FIXTURE_SETUP(marshal)120 FIXTURE_SETUP(marshal) {
121   self->m = minijail_new();
122   self->j = minijail_new();
123   ASSERT_TRUE(self->m && self->j) TH_LOG("allocation failed");
124   self->size = minijail_size(self->m);
125   ASSERT_GT(sizeof(self->buf), self->size) {
126     TH_LOG("static buffer too small for test");
127   }
128 }
129 
FIXTURE_TEARDOWN(marshal)130 FIXTURE_TEARDOWN(marshal) {
131   minijail_destroy(self->m);
132   minijail_destroy(self->j);
133 }
134 
TEST_F(marshal,empty)135 TEST_F(marshal, empty) {
136   ASSERT_EQ(0, minijail_marshal(self->m, self->buf, sizeof(self->buf)));
137   EXPECT_EQ(0, minijail_unmarshal(self->j, self->buf, self->size));
138 }
139 
140 TEST_F(marshal, 0xff) {
141   memset(self->buf, 0xff, sizeof(self->buf));
142   /* Should fail on the first consumestr since a NUL will never be found. */
143   EXPECT_EQ(-EINVAL, minijail_unmarshal(self->j, self->buf, sizeof(self->buf)));
144 }
145 
TEST(test_minijail_run_pid_pipes_no_preload)146 TEST(test_minijail_run_pid_pipes_no_preload) {
147   pid_t pid;
148   int child_stdin, child_stdout, child_stderr;
149   int mj_run_ret;
150   ssize_t write_ret, read_ret;
151   const size_t buf_len = 128;
152   char buf[buf_len];
153   int status;
154 #if defined(__ANDROID__)
155   char filename[] = "/system/bin/cat";
156 #else
157   char filename[] = "/bin/cat";
158 #endif
159   char teststr[] = "test\n";
160   size_t teststr_len = strlen(teststr);
161   char *argv[4];
162 
163   struct minijail *j = minijail_new();
164 
165   argv[0] = filename;
166   argv[1] = NULL;
167   mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv,
168                                                  &pid,
169                                                  &child_stdin, &child_stdout,
170                                                  NULL);
171   EXPECT_EQ(mj_run_ret, 0);
172 
173   write_ret = write(child_stdin, teststr, teststr_len);
174   EXPECT_EQ(write_ret, (int)teststr_len);
175 
176   read_ret = read(child_stdout, buf, 8);
177   EXPECT_EQ(read_ret, (int)teststr_len);
178   buf[teststr_len] = 0;
179   EXPECT_EQ(strcmp(buf, teststr), 0);
180 
181   EXPECT_EQ(kill(pid, SIGTERM), 0);
182   waitpid(pid, &status, 0);
183   ASSERT_TRUE(WIFSIGNALED(status));
184   EXPECT_EQ(WTERMSIG(status), SIGTERM);
185 
186 #if defined(__ANDROID__)
187   argv[0] = "/system/bin/sh";
188 #else
189   argv[0] = "/bin/sh";
190 #endif
191   argv[1] = "-c";
192   argv[2] = "echo test >&2";
193   argv[3] = NULL;
194   mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv, &pid,
195                                                  &child_stdin, &child_stdout,
196                                                  &child_stderr);
197   EXPECT_EQ(mj_run_ret, 0);
198 
199   read_ret = read(child_stderr, buf, buf_len);
200   EXPECT_GE(read_ret, (int)teststr_len);
201 
202   waitpid(pid, &status, 0);
203   ASSERT_TRUE(WIFEXITED(status));
204   EXPECT_EQ(WEXITSTATUS(status), 0);
205 
206   minijail_destroy(j);
207 }
208 
209 TEST_HARNESS_MAIN
210