1
0
mirror of https://github.com/libuv/libuv synced 2025-03-28 21:13:16 +00:00

Test for setuid/setgid

This commit is contained in:
Bert Belder 2012-04-27 21:05:15 +02:00
parent c42ba103b7
commit 66647bf934
2 changed files with 182 additions and 1 deletions

View File

@ -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)
@ -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)
@ -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)
@ -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)
@ -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)

View File

@ -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];
@ -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;
@ -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;
}
@ -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