blob: cdaba0b23e95b4f8e2e0fce5c6788834107e8c9f [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);
40
41/* Silence unused variable warnings. */
42TEST(silence, silence_unused) {
43 EXPECT_STREQ(kLdPreloadEnvVar, kLdPreloadEnvVar);
44 EXPECT_STREQ(kFdEnvVar, kFdEnvVar);
45 EXPECT_STRNE(kFdEnvVar, kLdPreloadEnvVar);
46}
47
48TEST(consumebytes, zero) {
49 char buf[1024];
50 size_t len = sizeof(buf);
51 char *pos = &buf[0];
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040052 EXPECT_NE(nullptr, consumebytes(0, &pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040053 EXPECT_EQ(&buf[0], pos);
54 EXPECT_EQ(sizeof(buf), len);
55}
56
57TEST(consumebytes, exact) {
58 char buf[1024];
59 size_t len = sizeof(buf);
60 char *pos = &buf[0];
61 /* One past the end since it consumes the whole buffer. */
62 char *end = &buf[sizeof(buf)];
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040063 EXPECT_NE(nullptr, consumebytes(len, &pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040064 EXPECT_EQ((size_t)0, len);
65 EXPECT_EQ(end, pos);
66}
67
68TEST(consumebytes, half) {
69 char buf[1024];
70 size_t len = sizeof(buf);
71 char *pos = &buf[0];
72 /* One past the end since it consumes the whole buffer. */
73 char *end = &buf[sizeof(buf) / 2];
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040074 EXPECT_NE(nullptr, consumebytes(len / 2, &pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040075 EXPECT_EQ(sizeof(buf) / 2, len);
76 EXPECT_EQ(end, pos);
77}
78
79TEST(consumebytes, toolong) {
80 char buf[1024];
81 size_t len = sizeof(buf);
82 char *pos = &buf[0];
83 /* One past the end since it consumes the whole buffer. */
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040084 EXPECT_EQ(nullptr, consumebytes(len + 1, &pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040085 EXPECT_EQ(sizeof(buf), len);
86 EXPECT_EQ(&buf[0], pos);
87}
88
89TEST(consumestr, zero) {
90 char buf[1024];
91 size_t len = 0;
92 char *pos = &buf[0];
93 memset(buf, 0xff, sizeof(buf));
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -040094 EXPECT_EQ(nullptr, consumestr(&pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -040095 EXPECT_EQ((size_t)0, len);
96 EXPECT_EQ(&buf[0], pos);
97}
98
99TEST(consumestr, nonul) {
100 char buf[1024];
101 size_t len = sizeof(buf);
102 char *pos = &buf[0];
103 memset(buf, 0xff, sizeof(buf));
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400104 EXPECT_EQ(nullptr, consumestr(&pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -0400105 EXPECT_EQ(sizeof(buf), len);
106 EXPECT_EQ(&buf[0], pos);
107}
108
109TEST(consumestr, full) {
110 char buf[1024];
111 size_t len = sizeof(buf);
112 char *pos = &buf[0];
113 memset(buf, 0xff, sizeof(buf));
114 buf[sizeof(buf)-1] = '\0';
115 EXPECT_EQ((void *)buf, consumestr(&pos, &len));
116 EXPECT_EQ((size_t)0, len);
117 EXPECT_EQ(&buf[sizeof(buf)], pos);
118}
119
120TEST(consumestr, trailing_nul) {
121 char buf[1024];
122 size_t len = sizeof(buf) - 1;
123 char *pos = &buf[0];
124 memset(buf, 0xff, sizeof(buf));
125 buf[sizeof(buf)-1] = '\0';
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400126 EXPECT_EQ(nullptr, consumestr(&pos, &len));
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -0400127 EXPECT_EQ(sizeof(buf) - 1, len);
128 EXPECT_EQ(&buf[0], pos);
129}
130
131class MarshalTest : public ::testing::Test {
132 protected:
133 virtual void SetUp() {
134 m_ = minijail_new();
135 j_ = minijail_new();
136 size_ = minijail_size(m_);
137 }
138 virtual void TearDown() {
139 minijail_destroy(m_);
140 minijail_destroy(j_);
141 }
142
143 char buf_[4096];
144 struct minijail *m_;
145 struct minijail *j_;
146 size_t size_;
147};
148
149TEST_F(MarshalTest, empty) {
150 ASSERT_EQ(0, minijail_marshal(m_, buf_, sizeof(buf_)));
151 EXPECT_EQ(0, minijail_unmarshal(j_, buf_, size_));
152}
153
154TEST_F(MarshalTest, 0xff) {
155 memset(buf_, 0xff, sizeof(buf_));
156 /* Should fail on the first consumestr since a NUL will never be found. */
157 EXPECT_EQ(-EINVAL, minijail_unmarshal(j_, buf_, sizeof(buf_)));
158}
159
160TEST(Test, minijail_run_pid_pipes_no_preload) {
161 pid_t pid;
162 int child_stdin, child_stdout, child_stderr;
163 int mj_run_ret;
164 ssize_t write_ret, read_ret;
165 const size_t buf_len = 128;
166 char buf[buf_len];
167 int status;
168#if defined(__ANDROID__)
169 char filename[] = "/system/bin/cat";
170#else
171 char filename[] = "/bin/cat";
172#endif
173 char teststr[] = "test\n";
174 size_t teststr_len = strlen(teststr);
175 char *argv[4];
176
177 struct minijail *j = minijail_new();
178
179 argv[0] = filename;
180 argv[1] = NULL;
181 mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv,
182 &pid,
183 &child_stdin, &child_stdout,
184 NULL);
185 EXPECT_EQ(mj_run_ret, 0);
186
187 write_ret = write(child_stdin, teststr, teststr_len);
188 EXPECT_EQ(write_ret, (int)teststr_len);
189
190 read_ret = read(child_stdout, buf, 8);
191 EXPECT_EQ(read_ret, (int)teststr_len);
192 buf[teststr_len] = 0;
193 EXPECT_EQ(strcmp(buf, teststr), 0);
194
195 EXPECT_EQ(kill(pid, SIGTERM), 0);
196 waitpid(pid, &status, 0);
197 ASSERT_TRUE(WIFSIGNALED(status));
198 EXPECT_EQ(WTERMSIG(status), SIGTERM);
199
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400200 argv[0] = (char*)kShellPath;
Jorge Lucangeli Obesa67bd6a2016-08-19 15:33:48 -0400201 argv[1] = "-c";
202 argv[2] = "echo test >&2";
203 argv[3] = NULL;
204 mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv, &pid,
205 &child_stdin, &child_stdout,
206 &child_stderr);
207 EXPECT_EQ(mj_run_ret, 0);
208
209 read_ret = read(child_stderr, buf, buf_len);
210 EXPECT_GE(read_ret, (int)teststr_len);
211
212 waitpid(pid, &status, 0);
213 ASSERT_TRUE(WIFEXITED(status));
214 EXPECT_EQ(WEXITSTATUS(status), 0);
215
216 minijail_destroy(j);
217}
Jorge Lucangeli Obese9740af2016-11-02 13:39:24 -0400218
219TEST(Test, test_minijail_no_fd_leaks) {
220 pid_t pid;
221 int child_stdout;
222 int mj_run_ret;
223 ssize_t read_ret;
224 const size_t buf_len = 128;
225 char buf[buf_len];
226 char script[buf_len];
227 int status;
228 char *argv[4];
229
230 int dev_null = open("/dev/null", O_RDONLY);
231 ASSERT_NE(dev_null, -1);
232 snprintf(script,
233 sizeof(script),
234 "[ -e /proc/self/fd/%d ] && echo yes || echo no",
235 dev_null);
236
237 struct minijail *j = minijail_new();
238
239 argv[0] = (char*)kShellPath;
240 argv[1] = "-c";
241 argv[2] = script;
242 argv[3] = NULL;
243 mj_run_ret = minijail_run_pid_pipes_no_preload(
244 j, argv[0], argv, &pid, NULL, &child_stdout, NULL);
245 EXPECT_EQ(mj_run_ret, 0);
246
247 read_ret = read(child_stdout, buf, buf_len);
248 EXPECT_GE(read_ret, 0);
249 buf[read_ret] = '\0';
250 EXPECT_STREQ(buf, "yes\n");
251
252 waitpid(pid, &status, 0);
253 ASSERT_TRUE(WIFEXITED(status));
254 EXPECT_EQ(WEXITSTATUS(status), 0);
255
256 minijail_close_open_fds(j);
257 mj_run_ret = minijail_run_pid_pipes_no_preload(
258 j, argv[0], argv, &pid, NULL, &child_stdout, NULL);
259 EXPECT_EQ(mj_run_ret, 0);
260
261 read_ret = read(child_stdout, buf, buf_len);
262 EXPECT_GE(read_ret, 0);
263 buf[read_ret] = '\0';
264 EXPECT_STREQ(buf, "no\n");
265
266 waitpid(pid, &status, 0);
267 ASSERT_TRUE(WIFEXITED(status));
268 EXPECT_EQ(WEXITSTATUS(status), 0);
269
270 minijail_destroy(j);
271
272 close(dev_null);
273}