From bb146866c04bc942242a53d110716f161519a721 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 17 Oct 2017 10:57:38 +0200 Subject: executor: improvements for akaros 1. remove workaround for pthread attrs (was fixed in akaros) 2. remove workaround for dup2 (was fixed in akaros) 3. check that we receive a program 4. implement timeout for test processes --- executor/executor.h | 25 +++++++++++-------------- executor/executor_akaros.cc | 25 +++++++++++++++++++------ executor/executor_freebsd.cc | 2 +- executor/executor_fuchsia.cc | 2 +- executor/executor_linux.cc | 2 +- executor/executor_posix.h | 11 ++--------- executor/executor_windows.cc | 2 +- executor/syscalls_akaros.h | 5 ++--- 8 files changed, 38 insertions(+), 36 deletions(-) (limited to 'executor') diff --git a/executor/executor.h b/executor/executor.h index 9e56f45e2..1933c6cef 100644 --- a/executor/executor.h +++ b/executor/executor.h @@ -21,13 +21,8 @@ #endif // Note: zircon max fd is 256. -#ifndef DUP2_BROKEN const int kInPipeFd = 250; // remapped from stdin const int kOutPipeFd = 251; // remapped from stdout -#else -const int kInPipeFd = 0; -const int kOutPipeFd = 1; -#endif const int kMaxInput = 2 << 20; const int kMaxOutput = 16 << 20; @@ -197,7 +192,6 @@ static bool dedup(uint32_t sig); void setup_control_pipes() { -#ifndef DUP2_BROKEN if (dup2(0, kInPipeFd) < 0) fail("dup2(0, kInPipeFd) failed"); if (dup2(1, kOutPipeFd) < 0) @@ -206,7 +200,6 @@ void setup_control_pipes() fail("dup2(2, 1) failed"); if (close(0)) fail("close(0) failed"); -#endif } void parse_env_flags(uint64_t flags) @@ -246,7 +239,7 @@ void reply_handshake() fail("control pipe write failed"); } -void receive_execute() +void receive_execute(bool need_prog) { execute_req req; if (read(kInPipeFd, &req, sizeof(req)) != (ssize_t)sizeof(req)) @@ -263,11 +256,15 @@ void receive_execute() flag_collect_comps = req.exec_flags & (1 << 3); flag_fault_call = req.fault_call; flag_fault_nth = req.fault_nth; - debug("exec opts: cover=%d comps=%d dedup=%d fault=%d/%d/%d\n", - flag_collect_cover, flag_collect_comps, flag_dedup_cover, - flag_inject_fault, flag_fault_call, flag_fault_nth); - if (req.prog_size == 0) + debug("exec opts: pid=%d threaded=%d collide=%d cover=%d comps=%d dedup=%d fault=%d/%d/%d prog=%llu\n", + flag_pid, flag_threaded, flag_collide, flag_collect_cover, flag_collect_comps, + flag_dedup_cover, flag_inject_fault, flag_fault_call, flag_fault_nth, + req.prog_size); + if (req.prog_size == 0) { + if (need_prog) + fail("need_prog: no program"); return; + } uint64_t pos = 0; for (;;) { ssize_t rv = read(kInPipeFd, input_data + pos, sizeof(input_data) - pos); @@ -512,7 +509,7 @@ void handle_completion(thread_t* th) if (!collide) { write_output(th->call_index); write_output(th->call_num); - uint32_t reserrno = th->res != (uint32_t)-1 ? 0 : th->reserrno; + uint32_t reserrno = th->res != -1 ? 0 : th->reserrno; write_output(reserrno); write_output(th->fault_injected); uint32_t* signal_count_pos = write_output(0); // filled in later @@ -631,7 +628,7 @@ void execute_call(thread_t* th) debug("fault injected: %d\n", th->fault_injected); } - if (th->res == (uint32_t)-1) + if (th->res == -1) debug("#%d: %s = errno(%d)\n", th->id, call->name, th->reserrno); else debug("#%d: %s = 0x%lx\n", th->id, call->name, th->res); diff --git a/executor/executor_akaros.cc b/executor/executor_akaros.cc index e7d828a40..f70e83807 100644 --- a/executor/executor_akaros.cc +++ b/executor/executor_akaros.cc @@ -3,9 +3,6 @@ // +build -// https://github.com/brho/akaros/issues/41 -#define DUP2_BROKEN - #define SYZ_EXECUTOR #include "common_akaros.h" @@ -31,7 +28,7 @@ int main(int argc, char** argv) reply_handshake(); for (;;) { - receive_execute(); + receive_execute(true); char cwdbuf[128] = "/syz-tmpXXXXXX"; mkdtemp(cwdbuf); int pid = fork(); @@ -45,10 +42,26 @@ int main(int argc, char** argv) execute_one(); doexit(0); } - // TODO: timeout. int status = 0; - while (waitpid(pid, &status, 0) != pid) { + uint64_t start = current_time_ms(); + for (;;) { + int res = waitpid(pid, &status, WNOHANG); + if (res == pid) + break; + sleep_ms(10); + uint64_t now = current_time_ms(); + if (now - start < 3 * 1000) + continue; + kill(pid, SIGKILL); + while (waitpid(pid, &status, 0) != pid) { + } + break; } + status = WEXITSTATUS(status); + if (status == kFailStatus) + fail("child failed"); + if (status == kErrorStatus) + error("child errored"); remove_dir(cwdbuf); reply_execute(0); } diff --git a/executor/executor_freebsd.cc b/executor/executor_freebsd.cc index abfb4139b..78c48b693 100644 --- a/executor/executor_freebsd.cc +++ b/executor/executor_freebsd.cc @@ -40,7 +40,7 @@ int main(int argc, char** argv) install_segv_handler(); setup_control_pipes(); - receive_execute(); + receive_execute(true); execute_one(); return 0; } diff --git a/executor/executor_fuchsia.cc b/executor/executor_fuchsia.cc index 490ec551c..a93811928 100644 --- a/executor/executor_fuchsia.cc +++ b/executor/executor_fuchsia.cc @@ -23,7 +23,7 @@ int main(int argc, char** argv) install_segv_handler(); setup_control_pipes(); - receive_execute(); + receive_execute(true); execute_one(); return 0; } diff --git a/executor/executor_linux.cc b/executor/executor_linux.cc index 72bd91aa8..d49e7e22b 100644 --- a/executor/executor_linux.cc +++ b/executor/executor_linux.cc @@ -138,7 +138,7 @@ void loop() // TODO: consider moving the read into the child. // Potentially it can speed up things a bit -- when the read finishes // we already have a forked worker process. - receive_execute(); + receive_execute(false); int pid = fork(); if (pid < 0) fail("clone failed"); diff --git a/executor/executor_posix.h b/executor/executor_posix.h index e75bfb3a7..e9b06b807 100644 --- a/executor/executor_posix.h +++ b/executor/executor_posix.h @@ -23,17 +23,10 @@ struct event_t { void event_init(event_t* ev) { - // Akaros crashes on NULL attr. - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - if (pthread_mutex_init(&ev->mu, &attr)) + if (pthread_mutex_init(&ev->mu, 0)) fail("pthread_mutex_init failed"); - pthread_mutexattr_destroy(&attr); - pthread_condattr_t cvattr; - pthread_condattr_init(&cvattr); - if (pthread_cond_init(&ev->cv, &cvattr)) + if (pthread_cond_init(&ev->cv, 0)) fail("pthread_cond_init failed"); - pthread_condattr_destroy(&cvattr); ev->state = false; } diff --git a/executor/executor_windows.cc b/executor/executor_windows.cc index 0124aa0d9..04f6fe6aa 100644 --- a/executor/executor_windows.cc +++ b/executor/executor_windows.cc @@ -24,7 +24,7 @@ int main(int argc, char** argv) } setup_control_pipes(); - receive_execute(); + receive_execute(true); execute_one(); return 0; } diff --git a/executor/syscalls_akaros.h b/executor/syscalls_akaros.h index 3cdd883a2..db066273a 100644 --- a/executor/syscalls_akaros.h +++ b/executor/syscalls_akaros.h @@ -2,9 +2,9 @@ #if defined(__x86_64__) || 0 #define GOARCH "amd64" -#define SYZ_REVISION "77727415c41fde64d42084c526dfb8bf1f1abf05" +#define SYZ_REVISION "1caab53009bda97952c0c670cb9fc3e335e1d49d" -unsigned syscall_count = 36; +unsigned syscall_count = 35; call_t syscalls[] = { {"abort_sysc_fd", 33}, {"chdir", 116}, @@ -21,7 +21,6 @@ call_t syscalls[] = { {"fcntl$F_SETLK", 107}, {"fcntl$F_SETLKW", 107}, {"fcntl$F_SETOWN", 107}, - {"fork", 15}, {"fstat", 104}, {"getcwd", 117}, {"link", 112}, -- cgit mrf-deployment