blob: 011ce85e2bfa66dea094a5ff13f3d1ce1588f041 [file] [log] [blame]
/* libminijail_unittest.c
* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* Test platform independent logic of minijail.
*/
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "test_harness.h"
#include "libminijail.h"
#include "libminijail-private.h"
/* Prototypes needed only by test. */
void *consumebytes(size_t length, char **buf, size_t *buflength);
char *consumestr(char **buf, size_t *buflength);
/* Silence unused variable warnings. */
TEST(silence_unused) {
EXPECT_STREQ(kLdPreloadEnvVar, kLdPreloadEnvVar);
EXPECT_STREQ(kFdEnvVar, kFdEnvVar);
EXPECT_STRNE(kFdEnvVar, kLdPreloadEnvVar);
}
TEST(consumebytes_zero) {
char buf[1024];
size_t len = sizeof(buf);
char *pos = &buf[0];
EXPECT_NE(NULL, consumebytes(0, &pos, &len));
EXPECT_EQ(&buf[0], pos);
EXPECT_EQ(sizeof(buf), len);
}
TEST(consumebytes_exact) {
char buf[1024];
size_t len = sizeof(buf);
char *pos = &buf[0];
/* One past the end since it consumes the whole buffer. */
char *end = &buf[sizeof(buf)];
EXPECT_NE(NULL, consumebytes(len, &pos, &len));
EXPECT_EQ((size_t)0, len);
EXPECT_EQ(end, pos);
}
TEST(consumebytes_half) {
char buf[1024];
size_t len = sizeof(buf);
char *pos = &buf[0];
/* One past the end since it consumes the whole buffer. */
char *end = &buf[sizeof(buf) / 2];
EXPECT_NE(NULL, consumebytes(len / 2, &pos, &len));
EXPECT_EQ(sizeof(buf) / 2, len);
EXPECT_EQ(end, pos);
}
TEST(consumebytes_toolong) {
char buf[1024];
size_t len = sizeof(buf);
char *pos = &buf[0];
/* One past the end since it consumes the whole buffer. */
EXPECT_EQ(NULL, consumebytes(len + 1, &pos, &len));
EXPECT_EQ(sizeof(buf), len);
EXPECT_EQ(&buf[0], pos);
}
TEST(consumestr_zero) {
char buf[1024];
size_t len = 0;
char *pos = &buf[0];
memset(buf, 0xff, sizeof(buf));
EXPECT_EQ(NULL, consumestr(&pos, &len));
EXPECT_EQ((size_t)0, len);
EXPECT_EQ(&buf[0], pos);
}
TEST(consumestr_nonul) {
char buf[1024];
size_t len = sizeof(buf);
char *pos = &buf[0];
memset(buf, 0xff, sizeof(buf));
EXPECT_EQ(NULL, consumestr(&pos, &len));
EXPECT_EQ(sizeof(buf), len);
EXPECT_EQ(&buf[0], pos);
}
TEST(consumestr_full) {
char buf[1024];
size_t len = sizeof(buf);
char *pos = &buf[0];
memset(buf, 0xff, sizeof(buf));
buf[sizeof(buf)-1] = '\0';
EXPECT_EQ((void *)buf, consumestr(&pos, &len));
EXPECT_EQ((size_t)0, len);
EXPECT_EQ(&buf[sizeof(buf)], pos);
}
TEST(consumestr_trailing_nul) {
char buf[1024];
size_t len = sizeof(buf) - 1;
char *pos = &buf[0];
memset(buf, 0xff, sizeof(buf));
buf[sizeof(buf)-1] = '\0';
EXPECT_EQ(NULL, consumestr(&pos, &len));
EXPECT_EQ(sizeof(buf) - 1, len);
EXPECT_EQ(&buf[0], pos);
}
FIXTURE(marshal) {
char buf[4096];
struct minijail *m;
struct minijail *j;
size_t size;
};
FIXTURE_SETUP(marshal) {
self->m = minijail_new();
self->j = minijail_new();
ASSERT_TRUE(self->m && self->j) TH_LOG("allocation failed");
self->size = minijail_size(self->m);
ASSERT_GT(sizeof(self->buf), self->size) {
TH_LOG("static buffer too small for test");
}
}
FIXTURE_TEARDOWN(marshal) {
minijail_destroy(self->m);
minijail_destroy(self->j);
}
TEST_F(marshal, empty) {
ASSERT_EQ(0, minijail_marshal(self->m, self->buf, sizeof(self->buf)));
EXPECT_EQ(0, minijail_unmarshal(self->j, self->buf, self->size));
}
TEST_F(marshal, 0xff) {
memset(self->buf, 0xff, sizeof(self->buf));
/* Should fail on the first consumestr since a NUL will never be found. */
EXPECT_EQ(-EINVAL, minijail_unmarshal(self->j, self->buf, sizeof(self->buf)));
}
/*
* TODO(jorgelo): rewrite these tests to not depend on libminijailpreload.so.
TEST(test_minijail_run_pid_pipe) {
pid_t pid;
int child_stdin;
int mj_run_ret;
ssize_t write_ret;
int status;
char filename[] = "test/read_stdin";
char *argv[2];
argv[0] = filename;
argv[1] = NULL;
struct minijail *j = minijail_new();
mj_run_ret = minijail_run_pid_pipe(j, argv[0], argv, &pid, &child_stdin);
EXPECT_EQ(mj_run_ret, 0);
write_ret = write(child_stdin, "test\n", strlen("test\n"));
EXPECT_GT(write_ret, -1);
waitpid(pid, &status, 0);
ASSERT_TRUE(WIFEXITED(status));
EXPECT_EQ(WEXITSTATUS(status), 0);
minijail_destroy(j);
}
TEST(test_minijail_run_pid_pipes) {
pid_t pid;
int child_stdin, child_stdout, child_stderr;
int mj_run_ret;
ssize_t write_ret, read_ret;
const size_t buf_len = 128;
char buf[buf_len];
int status;
char filename[] = "/bin/cat";
char teststr[] = "test\n";
size_t teststr_len = strlen(teststr);
char *argv[4];
struct minijail *j = minijail_new();
argv[0] = filename;
argv[1] = NULL;
mj_run_ret = minijail_run_pid_pipes(j, argv[0], argv,
&pid, &child_stdin, &child_stdout, NULL);
EXPECT_EQ(mj_run_ret, 0);
write_ret = write(child_stdin, teststr, teststr_len);
EXPECT_EQ(write_ret, (int)teststr_len);
read_ret = read(child_stdout, buf, 8);
EXPECT_EQ(read_ret, (int)teststr_len);
buf[teststr_len] = 0;
EXPECT_EQ(strcmp(buf, teststr), 0);
EXPECT_EQ(kill(pid, SIGTERM), 0);
waitpid(pid, &status, 0);
ASSERT_TRUE(WIFSIGNALED(status));
EXPECT_EQ(WTERMSIG(status), SIGTERM);
argv[0] = "/bin/sh";
argv[1] = "-c";
argv[2] = "echo test >&2";
argv[3] = NULL;
mj_run_ret = minijail_run_pid_pipes(j, argv[0], argv, &pid, &child_stdin,
&child_stdout, &child_stderr);
EXPECT_EQ(mj_run_ret, 0);
read_ret = read(child_stderr, buf, buf_len);
EXPECT_GE(read_ret, (int)teststr_len);
waitpid(pid, &status, 0);
ASSERT_TRUE(WIFEXITED(status));
EXPECT_EQ(WEXITSTATUS(status), 0);
minijail_destroy(j);
}
*/
TEST_HARNESS_MAIN