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 setuid/setgid
  • Loading branch information
piscisaureus committed Apr 27, 2012
1 parent c42ba10 commit 66647bf
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 1 deletion.
10 changes: 9 additions & 1 deletion test/test-list.h
Expand Up @@ -110,6 +110,8 @@ TEST_DECLARE (spawn_stdout)
TEST_DECLARE (spawn_stdin)
TEST_DECLARE (spawn_and_kill)
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 @@ -133,7 +135,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 @@ -147,6 +149,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 @@ -289,6 +293,8 @@ TASK_LIST_START
TEST_ENTRY (spawn_stdin)
TEST_ENTRY (spawn_and_kill)
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 @@ -297,6 +303,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
173 changes: 173 additions & 0 deletions test/test-spawn.c
Expand Up @@ -30,6 +30,7 @@ static int exit_cb_called;
static uv_process_t process;
static uv_timer_t timer;
static uv_process_options_t options;
static uv_process_options2_t options2;
static char exepath[1024];
static size_t exepath_size = 1024;
static char* args[3];
Expand All @@ -55,6 +56,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 @@ -116,6 +133,22 @@ static void init_process_options(char* test, uv_exit_cb exit_cb) {
options.file = exepath;
options.args = args;
options.exit_cb = exit_cb;
options.windows_verbatim_arguments = 0;
}


static void init_process_options2(char* test, uv_exit_cb exit_cb) {
/* Note spawn_helper1 defined in test/run-tests.c */
int r = uv_exepath(exepath, &exepath_size);
ASSERT(r == 0);
exepath[exepath_size] = '\0';
args[0] = exepath;
args[1] = test;
args[2] = NULL;
options2.file = exepath;
options2.args = args;
options2.exit_cb = exit_cb;
options2.flags = 0;
}


Expand Down Expand Up @@ -466,3 +499,143 @@ 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_options2("spawn_helper1", exit_cb);

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

r = uv_spawn2(uv_default_loop(), &process, options2);
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_options2("spawn_helper1", exit_cb_failure_expected);

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

r = uv_spawn2(uv_default_loop(), &process, options2);
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_options2("spawn_helper1", exit_cb_failure_expected);

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

r = uv_spawn2(uv_default_loop(), &process, options2);
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_options2("spawn_helper1", exit_cb_unexpected);

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

r = uv_spawn2(uv_default_loop(), &process, options2);
ASSERT(r == -1);

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_options2("spawn_helper1", exit_cb_unexpected);

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

r = uv_spawn2(uv_default_loop(), &process, options2);
ASSERT(r == -1);

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

ASSERT(close_cb_called == 0);

return 0;
}
#endif

0 comments on commit 66647bf

Please sign in to comment.