diff options
Diffstat (limited to 'libminijail_unittest.cc')
-rw-r--r-- | libminijail_unittest.cc | 262 |
1 files changed, 25 insertions, 237 deletions
diff --git a/libminijail_unittest.cc b/libminijail_unittest.cc index d8ffc381..25aa76e5 100644 --- a/libminijail_unittest.cc +++ b/libminijail_unittest.cc @@ -217,189 +217,19 @@ TEST_F(MarshalTest, 0xff) { EXPECT_EQ(-EINVAL, minijail_unmarshal(j_, buf_, sizeof(buf_))); } -TEST(KillTest, running_process) { - const ScopedMinijail j(minijail_new()); - char* const argv[] = {"sh", "-c", "sleep 1000", nullptr}; - EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0); - EXPECT_EQ(minijail_kill(j.get()), 128 + SIGTERM); - EXPECT_EQ(minijail_kill(j.get()), -ESRCH); -} - -TEST(KillTest, process_already_awaited) { - const ScopedMinijail j(minijail_new()); - char* const argv[] = {"sh", "-c", "sleep 1; exit 42", nullptr}; - EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0); - EXPECT_EQ(minijail_wait(j.get()), 42); - EXPECT_EQ(minijail_kill(j.get()), -ESRCH); -} - -TEST(KillTest, process_already_finished_but_not_awaited) { - int fds[2]; - const ScopedMinijail j(minijail_new()); - char* const argv[] = {"sh", "-c", "exit 42", nullptr}; - ASSERT_EQ(pipe(fds), 0); - EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0); - ASSERT_EQ(close(fds[1]), 0); - // Wait for process to finish. - char buf[PIPE_BUF]; - EXPECT_EQ(read(fds[0], buf, PIPE_BUF), 0); - EXPECT_EQ(minijail_kill(j.get()), 42); - EXPECT_EQ(minijail_wait(j.get()), -ECHILD); -} - -TEST(KillTest, process_not_started) { - const ScopedMinijail j(minijail_new()); - EXPECT_EQ(minijail_kill(j.get()), -ECHILD); -} - -TEST(WaitTest, return_zero) { - const ScopedMinijail j(minijail_new()); - char* const argv[] = {"sh", "-c", "exit 0", nullptr}; - EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0); - EXPECT_EQ(minijail_wait(j.get()), 0); -} - -TEST(WaitTest, return_max) { - const ScopedMinijail j(minijail_new()); - char* const argv[] = {"sh", "-c", "exit 255", nullptr}; - EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0); - EXPECT_EQ(minijail_wait(j.get()), 255); -} - -TEST(WaitTest, return_modulo) { - const ScopedMinijail j(minijail_new()); - char* const argv[] = {"sh", "-c", "exit 256", nullptr}; - EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0); - EXPECT_EQ(minijail_wait(j.get()), 0); -} - -TEST(WaitTest, killed_by_sigkill) { - const ScopedMinijail j(minijail_new()); - char* const argv[] = {"sh", "-c", "kill -KILL $$; sleep 1000", nullptr}; - EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0); - EXPECT_EQ(minijail_wait(j.get()), MINIJAIL_ERR_SIG_BASE + SIGKILL); -} - -TEST(WaitTest, killed_by_sigsys) { - const ScopedMinijail j(minijail_new()); - char* const argv[] = {"sh", "-c", "kill -SYS $$; sleep 1000", nullptr}; - EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0); - EXPECT_EQ(minijail_wait(j.get()), MINIJAIL_ERR_JAIL); -} - -TEST(WaitTest, command_not_found) { - const ScopedMinijail j(minijail_new()); - char* const argv[] = {"whatever", nullptr}; - EXPECT_EQ(minijail_run(j.get(), "command that cannot be found", argv), 0); - EXPECT_EQ(minijail_wait(j.get()), MINIJAIL_ERR_NO_COMMAND); -} - -TEST(WaitTest, command_not_run) { - const ScopedMinijail j(minijail_new()); - char* const argv[] = {"whatever", nullptr}; - EXPECT_EQ(minijail_run(j.get(), "/dev/null", argv), 0); - EXPECT_EQ(minijail_wait(j.get()), MINIJAIL_ERR_NO_ACCESS); -} - -TEST(WaitTest, no_process) { - const ScopedMinijail j(minijail_new()); - EXPECT_EQ(minijail_wait(j.get()), -ECHILD); -} - -TEST(WaitTest, can_wait_only_once) { - const ScopedMinijail j(minijail_new()); - char* const argv[] = {"sh", "-c", "exit 0", nullptr}; - EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0); - EXPECT_EQ(minijail_wait(j.get()), 0); - EXPECT_EQ(minijail_wait(j.get()), -ECHILD); -} - -TEST(Test, close_original_pipes_after_dup2) { - // Pipe used by child process to signal that it continued after reading from - // stdin. - int to_wait[2]; - ASSERT_EQ(pipe(to_wait), 0); - - const ScopedMinijail j(minijail_new()); - char* program; - ASSERT_GT(asprintf(&program, R"( - echo Hi >&1; - echo There >&2; - exec 1>&-; - exec 2>&-; - read line1; - read line2; - echo "$line1$line2 and Goodbye" >&%d; - exit 42; - )", to_wait[1]), 0); - char* const argv[] = {"sh", "-c", program, nullptr}; - - int in = -1; - int out = -1; - int err = -1; - EXPECT_EQ(minijail_run_pid_pipes_no_preload(j.get(), kShellPath, argv, - nullptr, &in, &out, &err), - 0); - free(program); - - EXPECT_GT(in, 0); - EXPECT_GT(out, 0); - EXPECT_GT(err, 0); - - char buf[PIPE_BUF]; - ssize_t n; - - // Check that stdout and stderr pipes work. - n = read(out, buf, PIPE_BUF); - ASSERT_GT(n, 0); - EXPECT_EQ(std::string(buf, n), "Hi\n"); - - n = read(err, buf, PIPE_BUF); - ASSERT_GT(n, 0); - EXPECT_EQ(std::string(buf, n), "There\n"); - - // Check that the write ends of stdout and stderr pipes got closed by the - // child process. If the child process kept other file descriptors connected - // to stdout and stderr, then the parent process wouldn't be able to detect - // that all write ends of these pipes are closed and it would block here. - EXPECT_EQ(read(out, buf, PIPE_BUF), 0); - EXPECT_EQ(read(err, buf, PIPE_BUF), 0); - - // Check that stdin pipe works. - const std::string s = "Greetings\n"; - EXPECT_EQ(write(in, s.data(), s.size()), s.size()); - - // Close write end of pipe connected to child's stdin. If there was another - // file descriptor connected to this write end, then the child wouldn't be - // able to detect that this write end is closed and it would block. - ASSERT_EQ(close(in), 0); - - // Check that child process continued and ended. - n = read(to_wait[0], buf, PIPE_BUF); - ASSERT_GT(n, 0); - EXPECT_EQ(std::string(buf, n), "Greetings and Goodbye\n"); - EXPECT_EQ(minijail_wait(j.get()), 42); -} - TEST(Test, minijail_run_pid_pipes) { - // TODO(crbug.com/895875): The preload library interferes with ASan since they - // both need to use LD_PRELOAD. - if (running_with_asan()) { - SUCCEED(); - return; - } constexpr char teststr[] = "test\n"; - ScopedMinijail j(minijail_new()); - minijail_set_preload_path(j.get(), kPreloadPath); + struct minijail* j = minijail_new(); + minijail_set_preload_path(j, kPreloadPath); char* argv[4]; argv[0] = const_cast<char*>(kCatPath); argv[1] = nullptr; pid_t pid; int child_stdin, child_stdout; - int mj_run_ret = minijail_run_pid_pipes(j.get(), argv[0], argv, &pid, - &child_stdin, &child_stdout, nullptr); + int mj_run_ret = minijail_run_pid_pipes(j, argv[0], argv, &pid, &child_stdin, + &child_stdout, nullptr); EXPECT_EQ(mj_run_ret, 0); const size_t teststr_len = strlen(teststr); @@ -423,9 +253,8 @@ TEST(Test, minijail_run_pid_pipes) { argv[2] = "echo test >&2"; argv[3] = nullptr; int child_stderr; - mj_run_ret = minijail_run_pid_pipes(j.get(), argv[0], argv, &pid, - &child_stdin, &child_stdout, - &child_stderr); + 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, sizeof(buf)); @@ -434,6 +263,8 @@ TEST(Test, minijail_run_pid_pipes) { waitpid(pid, &status, 0); ASSERT_TRUE(WIFEXITED(status)); EXPECT_EQ(WEXITSTATUS(status), 0); + + minijail_destroy(j); } TEST(Test, minijail_run_pid_pipes_no_preload) { @@ -449,7 +280,7 @@ TEST(Test, minijail_run_pid_pipes_no_preload) { struct minijail *j = minijail_new(); - argv[0] = const_cast<char*>(kCatPath); + argv[0] = (char*)kCatPath; argv[1] = NULL; mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv, &pid, @@ -470,7 +301,7 @@ TEST(Test, minijail_run_pid_pipes_no_preload) { ASSERT_TRUE(WIFSIGNALED(status)); EXPECT_EQ(WTERMSIG(status), SIGTERM); - argv[0] = const_cast<char*>(kShellPath); + argv[0] = (char*)kShellPath; argv[1] = "-c"; argv[2] = "echo test >&2"; argv[3] = NULL; @@ -503,7 +334,7 @@ TEST(Test, minijail_run_env_pid_pipes_no_preload) { struct minijail *j = minijail_new(); - argv[0] = const_cast<char*>(kShellPath); + argv[0] = (char*)kShellPath; argv[1] = "-c"; argv[2] = "echo \"${TEST_PARENT+set}|${TEST_VAR}\""; argv[3] = NULL; @@ -519,9 +350,9 @@ TEST(Test, minijail_run_env_pid_pipes_no_preload) { EXPECT_EQ(mj_run_ret, 0); read_ret = read(child_stdout, buf, sizeof(buf)); - EXPECT_EQ(read_ret, (int)testvar_len + 2); + EXPECT_GE(read_ret, (int)testvar_len); - EXPECT_EQ("|test\n", std::string(buf, 0, testvar_len + 2)); + EXPECT_EQ("|test\n", std::string(buf)); EXPECT_EQ(waitpid(pid, &status, 0), pid); ASSERT_TRUE(WIFEXITED(status)); @@ -549,7 +380,7 @@ TEST(Test, test_minijail_no_fd_leaks) { struct minijail *j = minijail_new(); - argv[0] = const_cast<char*>(kShellPath); + argv[0] = (char*)kShellPath; argv[1] = "-c"; argv[2] = script; argv[3] = NULL; @@ -591,17 +422,18 @@ TEST(Test, test_minijail_fork) { int pipe_fds[2]; ssize_t pid_size = sizeof(mj_fork_ret); - ScopedMinijail j(minijail_new()); + struct minijail *j = minijail_new(); ASSERT_EQ(pipe(pipe_fds), 0); - mj_fork_ret = minijail_fork(j.get()); + mj_fork_ret = minijail_fork(j); ASSERT_GE(mj_fork_ret, 0); if (mj_fork_ret == 0) { pid_t pid_in_parent; // Wait for the parent to tell us the pid in the parent namespace. ASSERT_EQ(read(pipe_fds[0], &pid_in_parent, pid_size), pid_size); ASSERT_EQ(pid_in_parent, getpid()); + minijail_destroy(j); exit(0); } @@ -609,6 +441,8 @@ TEST(Test, test_minijail_fork) { waitpid(mj_fork_ret, &status, 0); ASSERT_TRUE(WIFEXITED(status)); EXPECT_EQ(WEXITSTATUS(status), 0); + + minijail_destroy(j); } static int early_exit(void* payload) { @@ -629,7 +463,7 @@ TEST(Test, test_minijail_callback) { MINIJAIL_HOOK_EVENT_PRE_DROP_CAPS); EXPECT_EQ(status, 0); - argv[0] = const_cast<char*>(kCatPath); + argv[0] = (char*)kCatPath; argv[1] = NULL; mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv, &pid, NULL, NULL, NULL); @@ -664,7 +498,7 @@ TEST(Test, test_minijail_preserve_fd) { ASSERT_EQ(status, 0); minijail_close_open_fds(j); - argv[0] = const_cast<char*>(kCatPath); + argv[0] = (char*)kCatPath; argv[1] = NULL; mj_run_ret = minijail_run_no_preload(j, argv[0], argv); EXPECT_EQ(mj_run_ret, 0); @@ -818,7 +652,7 @@ TEST_F(NamespaceTest, test_tmpfs_userns) { minijail_gidmap(j, gidmap); minijail_namespace_user_disable_setgroups(j); - argv[0] = const_cast<char*>(kShellPath); + argv[0] = (char*)kShellPath; argv[1] = "-c"; argv[2] = "exec touch /tmp/foo"; argv[3] = NULL; @@ -834,9 +668,7 @@ TEST_F(NamespaceTest, test_tmpfs_userns) { TEST_F(NamespaceTest, test_namespaces) { constexpr char teststr[] = "test\n"; - // TODO(crbug.com/895875): The preload library interferes with ASan since they - // both need to use LD_PRELOAD. - if (!userns_supported_ || running_with_asan()) { + if (!userns_supported_) { SUCCEED(); return; } @@ -881,11 +713,11 @@ TEST_F(NamespaceTest, test_namespaces) { minijail_close_open_fds(j.get()); test_function(j.get()); - char* const argv[] = {const_cast<char*>(kCatPath), nullptr}; + const char* argv[] = {kCatPath, nullptr}; pid_t container_pid; int child_stdin, child_stdout; int mj_run_ret = - run_function(j.get(), argv[0], argv, + run_function(j.get(), argv[0], const_cast<char* const*>(argv), &container_pid, &child_stdin, &child_stdout, nullptr); EXPECT_EQ(mj_run_ret, 0); @@ -1041,47 +873,3 @@ TEST(Test, parse_size) { ASSERT_EQ(-EINVAL, parse_size(&size, "-1G")); ASSERT_EQ(-EINVAL, parse_size(&size, "; /bin/rm -- ")); } - -void TestCreateSession(bool create_session) { - int status; - int pipe_fds[2]; - pid_t child_pid; - pid_t parent_sid = getsid(0); - ssize_t pid_size = sizeof(pid_t); - - ScopedMinijail j(minijail_new()); - // stdin/stdout/stderr might be attached to TTYs. Close them to avoid creating - // a new session because of that. - minijail_close_open_fds(j.get()); - - if (create_session) - minijail_create_session(j.get()); - - ASSERT_EQ(pipe(pipe_fds), 0); - minijail_preserve_fd(j.get(), pipe_fds[0], pipe_fds[0]); - - child_pid = minijail_fork(j.get()); - ASSERT_GE(child_pid, 0); - if (child_pid == 0) { - pid_t sid_in_parent; - ASSERT_EQ(read(pipe_fds[0], &sid_in_parent, pid_size), pid_size); - if (create_session) - ASSERT_NE(sid_in_parent, getsid(0)); - else - ASSERT_EQ(sid_in_parent, getsid(0)); - exit(0); - } - - EXPECT_EQ(write(pipe_fds[1], &parent_sid, pid_size), pid_size); - waitpid(child_pid, &status, 0); - ASSERT_TRUE(WIFEXITED(status)); - EXPECT_EQ(WEXITSTATUS(status), 0); -} - -TEST(Test, default_no_new_session) { - TestCreateSession(/*create_session=*/false); -} - -TEST(Test, create_new_session) { - TestCreateSession(/*create_session=*/true); -} |