blob: 4e75bdc27aa5fcb6cadf0777267f4f52dfe1b7b3 [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
20#include <sys/types.h>
21#include <sys/wait.h>
22
23#include <gtest/gtest.h>
24
25#include "libminijail.h"
26#include "libminijail-private.h"
27#include "util.h"
28
29/* Prototypes needed only by test. */
30void *consumebytes(size_t length, char **buf, size_t *buflength);
31char *consumestr(char **buf, size_t *buflength);
32
33/* Silence unused variable warnings. */
34TEST(silence, silence_unused) {
35 EXPECT_STREQ(kLdPreloadEnvVar, kLdPreloadEnvVar);
36 EXPECT_STREQ(kFdEnvVar, kFdEnvVar);
37 EXPECT_STRNE(kFdEnvVar, kLdPreloadEnvVar);
38}
39
40TEST(consumebytes, zero) {
41 char buf[1024];
42 size_t len = sizeof(buf);
43 char *pos = &buf[0];
44 EXPECT_TRUE(NULL != consumebytes(0, &pos, &len));
45 EXPECT_EQ(&buf[0], pos);
46 EXPECT_EQ(sizeof(buf), len);
47}
48
49TEST(consumebytes, exact) {
50 char buf[1024];
51 size_t len = sizeof(buf);
52 char *pos = &buf[0];
53 /* One past the end since it consumes the whole buffer. */
54 char *end = &buf[sizeof(buf)];
55 EXPECT_TRUE(NULL != consumebytes(len, &pos, &len));
56 EXPECT_EQ((size_t)0, len);
57 EXPECT_EQ(end, pos);
58}
59
60TEST(consumebytes, half) {
61 char buf[1024];
62 size_t len = sizeof(buf);
63 char *pos = &buf[0];
64 /* One past the end since it consumes the whole buffer. */
65 char *end = &buf[sizeof(buf) / 2];
66 EXPECT_TRUE(NULL != consumebytes(len / 2, &pos, &len));
67 EXPECT_EQ(sizeof(buf) / 2, len);
68 EXPECT_EQ(end, pos);
69}
70
71TEST(consumebytes, toolong) {
72 char buf[1024];
73 size_t len = sizeof(buf);
74 char *pos = &buf[0];
75 /* One past the end since it consumes the whole buffer. */
76 EXPECT_TRUE(NULL == consumebytes(len + 1, &pos, &len));
77 EXPECT_EQ(sizeof(buf), len);
78 EXPECT_EQ(&buf[0], pos);
79}
80
81TEST(consumestr, zero) {
82 char buf[1024];
83 size_t len = 0;
84 char *pos = &buf[0];
85 memset(buf, 0xff, sizeof(buf));
86 EXPECT_EQ(NULL, consumestr(&pos, &len));
87 EXPECT_EQ((size_t)0, len);
88 EXPECT_EQ(&buf[0], pos);
89}
90
91TEST(consumestr, nonul) {
92 char buf[1024];
93 size_t len = sizeof(buf);
94 char *pos = &buf[0];
95 memset(buf, 0xff, sizeof(buf));
96 EXPECT_EQ(NULL, consumestr(&pos, &len));
97 EXPECT_EQ(sizeof(buf), len);
98 EXPECT_EQ(&buf[0], pos);
99}
100
101TEST(consumestr, full) {
102 char buf[1024];
103 size_t len = sizeof(buf);
104 char *pos = &buf[0];
105 memset(buf, 0xff, sizeof(buf));
106 buf[sizeof(buf)-1] = '\0';
107 EXPECT_EQ((void *)buf, consumestr(&pos, &len));
108 EXPECT_EQ((size_t)0, len);
109 EXPECT_EQ(&buf[sizeof(buf)], pos);
110}
111
112TEST(consumestr, trailing_nul) {
113 char buf[1024];
114 size_t len = sizeof(buf) - 1;
115 char *pos = &buf[0];
116 memset(buf, 0xff, sizeof(buf));
117 buf[sizeof(buf)-1] = '\0';
118 EXPECT_EQ(NULL, consumestr(&pos, &len));
119 EXPECT_EQ(sizeof(buf) - 1, len);
120 EXPECT_EQ(&buf[0], pos);
121}
122
123class MarshalTest : public ::testing::Test {
124 protected:
125 virtual void SetUp() {
126 m_ = minijail_new();
127 j_ = minijail_new();
128 size_ = minijail_size(m_);
129 }
130 virtual void TearDown() {
131 minijail_destroy(m_);
132 minijail_destroy(j_);
133 }
134
135 char buf_[4096];
136 struct minijail *m_;
137 struct minijail *j_;
138 size_t size_;
139};
140
141TEST_F(MarshalTest, empty) {
142 ASSERT_EQ(0, minijail_marshal(m_, buf_, sizeof(buf_)));
143 EXPECT_EQ(0, minijail_unmarshal(j_, buf_, size_));
144}
145
146TEST_F(MarshalTest, 0xff) {
147 memset(buf_, 0xff, sizeof(buf_));
148 /* Should fail on the first consumestr since a NUL will never be found. */
149 EXPECT_EQ(-EINVAL, minijail_unmarshal(j_, buf_, sizeof(buf_)));
150}
151
152TEST(Test, minijail_run_pid_pipes_no_preload) {
153 pid_t pid;
154 int child_stdin, child_stdout, child_stderr;
155 int mj_run_ret;
156 ssize_t write_ret, read_ret;
157 const size_t buf_len = 128;
158 char buf[buf_len];
159 int status;
160#if defined(__ANDROID__)
161 char filename[] = "/system/bin/cat";
162#else
163 char filename[] = "/bin/cat";
164#endif
165 char teststr[] = "test\n";
166 size_t teststr_len = strlen(teststr);
167 char *argv[4];
168
169 struct minijail *j = minijail_new();
170
171 argv[0] = filename;
172 argv[1] = NULL;
173 mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv,
174 &pid,
175 &child_stdin, &child_stdout,
176 NULL);
177 EXPECT_EQ(mj_run_ret, 0);
178
179 write_ret = write(child_stdin, teststr, teststr_len);
180 EXPECT_EQ(write_ret, (int)teststr_len);
181
182 read_ret = read(child_stdout, buf, 8);
183 EXPECT_EQ(read_ret, (int)teststr_len);
184 buf[teststr_len] = 0;
185 EXPECT_EQ(strcmp(buf, teststr), 0);
186
187 EXPECT_EQ(kill(pid, SIGTERM), 0);
188 waitpid(pid, &status, 0);
189 ASSERT_TRUE(WIFSIGNALED(status));
190 EXPECT_EQ(WTERMSIG(status), SIGTERM);
191
192#if defined(__ANDROID__)
193 argv[0] = "/system/bin/sh";
194#else
195 argv[0] = "/bin/sh";
196#endif
197 argv[1] = "-c";
198 argv[2] = "echo test >&2";
199 argv[3] = NULL;
200 mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv, &pid,
201 &child_stdin, &child_stdout,
202 &child_stderr);
203 EXPECT_EQ(mj_run_ret, 0);
204
205 read_ret = read(child_stderr, buf, buf_len);
206 EXPECT_GE(read_ret, (int)teststr_len);
207
208 waitpid(pid, &status, 0);
209 ASSERT_TRUE(WIFEXITED(status));
210 EXPECT_EQ(WEXITSTATUS(status), 0);
211
212 minijail_destroy(j);
213}