executor: restore nodropprivs mode

This commit is contained in:
Dmitry Vyukov 2016-01-23 00:04:34 +01:00
parent 81438c4ddd
commit 0a98e8c14a

View File

@ -109,13 +109,14 @@ struct thread_t {
}; };
thread_t threads[kMaxThreads]; thread_t threads[kMaxThreads];
char loop_stack[1 << 20]; char sandbox_stack[1 << 20];
__attribute__((noreturn)) void fail(const char* msg, ...); __attribute__((noreturn)) void fail(const char* msg, ...);
__attribute__((noreturn)) void error(const char* msg, ...); __attribute__((noreturn)) void error(const char* msg, ...);
__attribute__((noreturn)) void exitf(const char* msg, ...); __attribute__((noreturn)) void exitf(const char* msg, ...);
void debug(const char* msg, ...); void debug(const char* msg, ...);
int loop(void* arg); int sandbox(void* arg);
void loop();
void execute_one(); void execute_one();
uint64_t read_input(uint64_t** input_posp, bool peek = false); uint64_t read_input(uint64_t** input_posp, bool peek = false);
uint64_t read_arg(uint64_t** input_posp); uint64_t read_arg(uint64_t** input_posp);
@ -128,7 +129,6 @@ void execute_call(thread_t* th);
void handle_completion(thread_t* th); void handle_completion(thread_t* th);
void thread_create(thread_t* th, int id); void thread_create(thread_t* th, int id);
void* worker_thread(void* arg); void* worker_thread(void* arg);
void sandbox();
bool write_file(const char* file, const char* what, ...); bool write_file(const char* file, const char* what, ...);
void remove_dir(const char* dir); void remove_dir(const char* dir);
uint64_t current_time_ms(); uint64_t current_time_ms();
@ -178,11 +178,19 @@ int main(int argc, char** argv)
syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8); syscall(SYS_rt_sigaction, 0x20, &sa, NULL, 8);
syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8); syscall(SYS_rt_sigaction, 0x21, &sa, NULL, 8);
real_uid = getuid(); int pid = -1;
real_gid = getgid(); if (flag_drop_privs) {
real_uid = getuid();
int pid = clone(loop, &loop_stack[sizeof(loop_stack) - 8], real_gid = getgid();
CLONE_NEWUSER | CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWUTS | CLONE_NEWNET, NULL); pid = clone(sandbox, &sandbox_stack[sizeof(sandbox_stack) - 8],
CLONE_NEWUSER | CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWUTS | CLONE_NEWNET, NULL);
} else {
pid = fork();
if (pid == 0) {
loop();
exit(1);
}
}
if (pid < 0) if (pid < 0)
fail("clone failed"); fail("clone failed");
debug("spawned loop pid %d\n", pid); debug("spawned loop pid %d\n", pid);
@ -198,18 +206,14 @@ int main(int argc, char** argv)
return 0; return 0;
} }
int loop(void* arg) void loop()
{ {
sandbox();
for (int iter = 0;; iter++) { for (int iter = 0;; iter++) {
// Create a new private work dir for this test (removed at the end of the loop). // Create a new private work dir for this test (removed at the end of the loop).
char cwdbuf[256]; char cwdbuf[256];
sprintf(cwdbuf, "/%d", iter); sprintf(cwdbuf, "./%d", iter);
if (mkdir(cwdbuf, 0777)) if (mkdir(cwdbuf, 0777))
fail("failed to mkdir"); fail("failed to mkdir");
if (chdir(cwdbuf))
fail("failed to chdir");
char tmp; char tmp;
if (read(kInPipeFd, &tmp, 1) != 1) if (read(kInPipeFd, &tmp, 1) != 1)
@ -221,6 +225,8 @@ int loop(void* arg)
if (pid == 0) { if (pid == 0) {
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
setpgrp(); setpgrp();
if (chdir(cwdbuf))
fail("failed to chdir");
close(kInPipeFd); close(kInPipeFd);
close(kOutPipeFd); close(kOutPipeFd);
execute_one(); execute_one();
@ -267,7 +273,7 @@ int loop(void* arg)
} }
} }
void sandbox() int sandbox(void* arg)
{ {
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
setpgrp(); setpgrp();
@ -320,6 +326,9 @@ void sandbox()
fail("chroot failed"); fail("chroot failed");
if (chdir("/")) if (chdir("/"))
fail("chdir failed"); fail("chdir failed");
loop();
exit(1);
} }
void execute_one() void execute_one()