Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
Browse files Browse the repository at this point in the history
Test for the uv_spawn's setuid and setgid options
  • Loading branch information
piscisaureus committed Apr 28, 2012
1 parent 99a995a commit bfd6d46
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 1 deletion.
10 changes: 9 additions & 1 deletion test/test-list.h
Expand Up @@ -118,6 +118,8 @@ TEST_DECLARE (spawn_stdin)
TEST_DECLARE (spawn_and_kill)
TEST_DECLARE (spawn_and_kill_with_std)
TEST_DECLARE (spawn_and_ping)
TEST_DECLARE (spawn_setuid_fails)
TEST_DECLARE (spawn_setgid_fails)
TEST_DECLARE (kill)
TEST_DECLARE (fs_file_noent)
TEST_DECLARE (fs_file_nametoolong)
Expand All @@ -142,7 +144,7 @@ TEST_DECLARE (fs_event_watch_file_current_dir)
TEST_DECLARE (fs_event_no_callback_on_close)
TEST_DECLARE (fs_event_immediate_close)
TEST_DECLARE (fs_event_close_with_pending_event)
TEST_DECLARE (fs_event_close_in_callback);
TEST_DECLARE (fs_event_close_in_callback)
TEST_DECLARE (fs_readdir_empty_dir)
TEST_DECLARE (fs_readdir_file)
TEST_DECLARE (fs_open_dir)
Expand All @@ -164,6 +166,8 @@ TEST_DECLARE (environment_creation)
TEST_DECLARE (listen_with_simultaneous_accepts)
TEST_DECLARE (listen_no_simultaneous_accepts)
TEST_DECLARE (fs_stat_root)
#else
TEST_DECLARE (spawn_setuid_setgid)
#endif
HELPER_DECLARE (tcp4_echo_server)
HELPER_DECLARE (tcp6_echo_server)
Expand Down Expand Up @@ -316,6 +320,8 @@ TASK_LIST_START
TEST_ENTRY (spawn_and_kill)
TEST_ENTRY (spawn_and_kill_with_std)
TEST_ENTRY (spawn_and_ping)
TEST_ENTRY (spawn_setuid_fails)
TEST_ENTRY (spawn_setgid_fails)
TEST_ENTRY (kill)
#ifdef _WIN32
TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
Expand All @@ -324,6 +330,8 @@ TASK_LIST_START
TEST_ENTRY (listen_with_simultaneous_accepts)
TEST_ENTRY (listen_no_simultaneous_accepts)
TEST_ENTRY (fs_stat_root)
#else
TEST_ENTRY (spawn_setuid_setgid)
#endif

TEST_ENTRY (fs_file_noent)
Expand Down
159 changes: 159 additions & 0 deletions test/test-spawn.c
Expand Up @@ -55,6 +55,22 @@ static void exit_cb(uv_process_t* process, int exit_status, int term_signal) {
}


static void exit_cb_failure_expected(uv_process_t* process, int exit_status,
int term_signal) {
printf("exit_cb\n");
exit_cb_called++;
ASSERT(exit_status == 127);
ASSERT(term_signal == 0);
uv_close((uv_handle_t*)process, close_cb);
}


static void exit_cb_unexpected(uv_process_t* process, int exit_status,
int term_signal) {
ASSERT(0 && "should not have been called");
}


static void kill_cb(uv_process_t* process, int exit_status, int term_signal) {
uv_err_t err;

Expand Down Expand Up @@ -115,6 +131,7 @@ static void init_process_options(char* test, uv_exit_cb exit_cb) {
options.file = exepath;
options.args = args;
options.exit_cb = exit_cb;
options.flags = 0;
}


Expand Down Expand Up @@ -517,3 +534,145 @@ TEST_IMPL(environment_creation) {
return 0;
}
#endif

#ifndef _WIN32
TEST_IMPL(spawn_setuid_setgid) {
int r;

/* if not root, then this will fail. */
uv_uid_t uid = getuid();
if (uid != 0) {
fprintf(stderr, "spawn_setuid_setgid skipped: not root\n");
return 0;
}

init_process_options("spawn_helper1", exit_cb);

// become the "nobody" user.
struct passwd* pw;
pw = getpwnam("nobody");
ASSERT(pw != NULL);
options.uid = pw->pw_uid;
options.gid = pw->pw_gid;
options.flags = UV_PROCESS_SETUID | UV_PROCESS_SETGID;

r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == 0);

r = uv_run(uv_default_loop());
ASSERT(r == 0);

ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);

return 0;
}
#endif


#ifndef _WIN32
TEST_IMPL(spawn_setuid_fails) {
int r;

/* if root, become nobody. */
uv_uid_t uid = getuid();
if (uid == 0) {
struct passwd* pw;
pw = getpwnam("nobody");
ASSERT(pw != NULL);
r = setuid(pw->pw_uid);
ASSERT(r == 0);
}

init_process_options("spawn_helper1", exit_cb_failure_expected);

options.flags |= UV_PROCESS_SETUID;
options.uid = (uv_uid_t) -42424242;

r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == 0);

r = uv_run(uv_default_loop());
ASSERT(r == 0);

ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);

return 0;
}


TEST_IMPL(spawn_setgid_fails) {
int r;

/* if root, become nobody. */
uv_uid_t uid = getuid();
if (uid == 0) {
struct passwd* pw;
pw = getpwnam("nobody");
ASSERT(pw != NULL);
r = setuid(pw->pw_uid);
ASSERT(r == 0);
}

init_process_options("spawn_helper1", exit_cb_failure_expected);

options.flags |= UV_PROCESS_SETGID;
options.gid = (uv_gid_t) -42424242;

r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == 0);

r = uv_run(uv_default_loop());
ASSERT(r == 0);

ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);

return 0;
}
#endif


#ifdef _WIN32
TEST_IMPL(spawn_setuid_fails) {
int r;

init_process_options("spawn_helper1", exit_cb_unexpected);

options.flags |= UV_PROCESS_SETUID;
options.uid = (uv_uid_t) -42424242;

r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == -1);
ASSERT(uv_last_error(uv_default_loop()).code == UV_ENOTSUP);

r = uv_run(uv_default_loop());
ASSERT(r == 0);

ASSERT(close_cb_called == 0);

return 0;
}


TEST_IMPL(spawn_setgid_fails) {
int r;

init_process_options("spawn_helper1", exit_cb_unexpected);

options.flags |= UV_PROCESS_SETGID;
options.gid = (uv_gid_t) -42424242;

r = uv_spawn(uv_default_loop(), &process, options);
ASSERT(r == -1);
ASSERT(uv_last_error(uv_default_loop()).code == UV_ENOTSUP);

r = uv_run(uv_default_loop());
ASSERT(r == 0);

ASSERT(close_cb_called == 0);

return 0;
}
#endif

0 comments on commit bfd6d46

Please sign in to comment.