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. */ 43 TEST(silence, silence_unused) { 44 EXPECT_STREQ(kLdPreloadEnvVar, kLdPreloadEnvVar); 45 EXPECT_STREQ(kFdEnvVar, kFdEnvVar); 46 EXPECT_STRNE(kFdEnvVar, kLdPreloadEnvVar); 47 } 48 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 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 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 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 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 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 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 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: 134 virtual void SetUp() { 135 m_ = minijail_new(); 136 j_ = minijail_new(); 137 size_ = minijail_size(m_); 138 } 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 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 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 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 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