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