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. */ 24 TEST(silence_unused) { 25 EXPECT_STREQ(kLdPreloadEnvVar, kLdPreloadEnvVar); 26 EXPECT_STREQ(kFdEnvVar, kFdEnvVar); 27 EXPECT_STRNE(kFdEnvVar, kLdPreloadEnvVar); 28 } 29 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 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 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 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 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 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 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 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 113 FIXTURE(marshal) { 114 char buf[4096]; 115 struct minijail *m; 116 struct minijail *j; 117 size_t size; 118 }; 119 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 130 FIXTURE_TEARDOWN(marshal) { 131 minijail_destroy(self->m); 132 minijail_destroy(self->j); 133 } 134 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 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