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
This commit is contained in:
Dmitry Vyukov 2017-10-17 10:57:38 +02:00
parent a8a0b01a8b
commit bb146866c0
10 changed files with 61 additions and 59 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -24,7 +24,7 @@ int main(int argc, char** argv)
}
setup_control_pipes();
receive_execute();
receive_execute(true);
execute_one();
return 0;
}

View File

@ -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},

View File

@ -97,35 +97,34 @@ var syscalls_amd64 = []*Syscall{
&ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "const", FldName: "cmd", TypeSize: 8}}, Val: 8},
&ResourceType{TypeCommon: TypeCommon{TypeName: "pid", FldName: "pid", TypeSize: 4}},
}},
{ID: 15, NR: 15, Name: "fork", CallName: "fork"},
{ID: 16, NR: 104, Name: "fstat", CallName: "fstat", Args: []Type{
{ID: 15, NR: 104, Name: "fstat", CallName: "fstat", Args: []Type{
&ResourceType{TypeCommon: TypeCommon{TypeName: "fd", FldName: "fd", TypeSize: 4}},
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "statbuf", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "array", ArgDir: 1}}},
}},
{ID: 17, NR: 117, Name: "getcwd", CallName: "getcwd", Args: []Type{
{ID: 16, NR: 117, Name: "getcwd", CallName: "getcwd", Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "buffer", FldName: "buf", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{ArgDir: 1}}},
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "size", TypeSize: 8}}, Buf: "buf"},
}},
{ID: 18, NR: 112, Name: "link", CallName: "link", Args: []Type{
{ID: 17, NR: 112, Name: "link", CallName: "link", Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "old", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "new", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
}},
{ID: 19, NR: 111, Name: "llseek", CallName: "llseek", Args: []Type{
{ID: 18, NR: 111, Name: "llseek", CallName: "llseek", Args: []Type{
&ResourceType{TypeCommon: TypeCommon{TypeName: "fd", FldName: "fd", TypeSize: 4}},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "intptr", FldName: "offset_hi", TypeSize: 8}}},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "intptr", FldName: "offset_lo", TypeSize: 8}}},
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "result", TypeSize: 8}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", TypeSize: 8, ArgDir: 1}}}},
&FlagsType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "seek_whence", FldName: "whence", TypeSize: 8}}, Vals: []uint64{0, 1, 2}},
}},
{ID: 20, NR: 106, Name: "lstat", CallName: "lstat", Args: []Type{
{ID: 19, NR: 106, Name: "lstat", CallName: "lstat", Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "file", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "statbuf", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "array", ArgDir: 1}}},
}},
{ID: 21, NR: 118, Name: "mkdir", CallName: "mkdir", Args: []Type{
{ID: 20, NR: 118, Name: "mkdir", CallName: "mkdir", Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "path", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
&FlagsType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "open_mode", FldName: "mode", TypeSize: 8}}, Vals: []uint64{256, 128, 64, 32, 16, 8, 4, 2, 1}},
}},
{ID: 22, NR: 18, Name: "mmap", CallName: "mmap", Args: []Type{
{ID: 21, NR: 18, Name: "mmap", CallName: "mmap", Args: []Type{
&VmaType{TypeCommon: TypeCommon{TypeName: "vma", FldName: "addr", TypeSize: 8}},
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "len", TypeSize: 8}}, Buf: "addr"},
&FlagsType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "mmap_prot", FldName: "prot", TypeSize: 8}}, Vals: []uint64{4, 1, 2, 16777216, 33554432}},
@ -133,59 +132,59 @@ var syscalls_amd64 = []*Syscall{
&ResourceType{TypeCommon: TypeCommon{TypeName: "fd", FldName: "fd", TypeSize: 4, IsOptional: true}},
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "intptr", FldName: "offset", TypeSize: 8}}},
}},
{ID: 23, NR: 20, Name: "mprotect", CallName: "mprotect", Args: []Type{
{ID: 22, NR: 20, Name: "mprotect", CallName: "mprotect", Args: []Type{
&VmaType{TypeCommon: TypeCommon{TypeName: "vma", FldName: "addr", TypeSize: 8}},
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "len", TypeSize: 8}}, Buf: "addr"},
&FlagsType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "mmap_prot", FldName: "prot", TypeSize: 8}}, Vals: []uint64{4, 1, 2, 16777216, 33554432}},
}},
{ID: 24, NR: 19, Name: "munmap", CallName: "munmap", Args: []Type{
{ID: 23, NR: 19, Name: "munmap", CallName: "munmap", Args: []Type{
&VmaType{TypeCommon: TypeCommon{TypeName: "vma", FldName: "addr", TypeSize: 8}},
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "len", TypeSize: 8}}, Buf: "addr"},
}},
{ID: 25, NR: 36, Name: "nanosleep", CallName: "nanosleep", Args: []Type{
{ID: 24, NR: 36, Name: "nanosleep", CallName: "nanosleep", Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "req", TypeSize: 8}, Type: &StructType{Key: StructKey{Name: "timespec"}}},
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "rem", TypeSize: 8, IsOptional: true}, Type: &StructType{Key: StructKey{Name: "timespec", Dir: 1}}},
}},
{ID: 26, NR: 102, Name: "openat", CallName: "openat", Args: []Type{
{ID: 25, NR: 102, Name: "openat", CallName: "openat", Args: []Type{
&ResourceType{TypeCommon: TypeCommon{TypeName: "fd", FldName: "fd", TypeSize: 4}},
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "file", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
&FlagsType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "open_flags", FldName: "flags", TypeSize: 8}}, Vals: []uint64{0, 1, 2, 1024, 8192, 524288, 64, 65536, 128, 256, 131072, 2048, 1052672, 512, 4259840}},
&FlagsType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "open_mode", FldName: "mode", TypeSize: 8}}, Vals: []uint64{256, 128, 64, 32, 16, 8, 4, 2, 1}},
}, Ret: &ResourceType{TypeCommon: TypeCommon{TypeName: "fd", FldName: "ret", TypeSize: 4, ArgDir: 1}}},
{ID: 27, NR: 100, Name: "read", CallName: "read", Args: []Type{
{ID: 26, NR: 100, Name: "read", CallName: "read", Args: []Type{
&ResourceType{TypeCommon: TypeCommon{TypeName: "fd", FldName: "fd", TypeSize: 4}},
&PtrType{TypeCommon: TypeCommon{TypeName: "buffer", FldName: "buf", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{ArgDir: 1}}},
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "count", TypeSize: 8}}, Buf: "buf"},
}},
{ID: 28, NR: 115, Name: "readlink", CallName: "readlink", Args: []Type{
{ID: 27, NR: 115, Name: "readlink", CallName: "readlink", Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "path", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
&PtrType{TypeCommon: TypeCommon{TypeName: "buffer", FldName: "buf", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{ArgDir: 1}}},
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "siz", TypeSize: 8}}, Buf: "buf"},
}},
{ID: 29, NR: 123, Name: "rename", CallName: "rename", Args: []Type{
{ID: 28, NR: 123, Name: "rename", CallName: "rename", Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "old", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "new", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
}},
{ID: 30, NR: 119, Name: "rmdir", CallName: "rmdir", Args: []Type{
{ID: 29, NR: 119, Name: "rmdir", CallName: "rmdir", Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "path", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
}},
{ID: 31, NR: 105, Name: "stat", CallName: "stat", Args: []Type{
{ID: 30, NR: 105, Name: "stat", CallName: "stat", Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "file", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "statbuf", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "array", ArgDir: 1}}},
}},
{ID: 32, NR: 114, Name: "symlink", CallName: "symlink", Args: []Type{
{ID: 31, NR: 114, Name: "symlink", CallName: "symlink", Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "old", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "new", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
}},
{ID: 33, NR: 113, Name: "unlink", CallName: "unlink", Args: []Type{
{ID: 32, NR: 113, Name: "unlink", CallName: "unlink", Args: []Type{
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "path", TypeSize: 8}, Type: &BufferType{TypeCommon: TypeCommon{TypeName: "filename"}, Kind: 3}},
}},
{ID: 34, NR: 17, Name: "waitpid", CallName: "waitpid", Args: []Type{
{ID: 33, NR: 17, Name: "waitpid", CallName: "waitpid", Args: []Type{
&ResourceType{TypeCommon: TypeCommon{TypeName: "pid", FldName: "pid", TypeSize: 4}},
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "status", TypeSize: 8}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4, ArgDir: 1}}}},
&FlagsType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "wait_options", FldName: "options", TypeSize: 8}}, Vals: []uint64{1, 2}},
}},
{ID: 35, NR: 101, Name: "write", CallName: "write", Args: []Type{
{ID: 34, NR: 101, Name: "write", CallName: "write", Args: []Type{
&ResourceType{TypeCommon: TypeCommon{TypeName: "fd", FldName: "fd", TypeSize: 4}},
&PtrType{TypeCommon: TypeCommon{TypeName: "buffer", FldName: "buf", TypeSize: 8}, Type: &BufferType{}},
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "count", TypeSize: 8}}, Buf: "buf"},
@ -286,4 +285,4 @@ var consts_amd64 = []ConstValue{
{Name: "__O_TMPFILE", Value: 4259840},
}
const revision_amd64 = "77727415c41fde64d42084c526dfb8bf1f1abf05"
const revision_amd64 = "1caab53009bda97952c0c670cb9fc3e335e1d49d"

View File

@ -47,7 +47,8 @@ mmap(addr vma, len len[addr], prot flags[mmap_prot], flags flags[mmap_flags], fd
munmap(addr vma, len len[addr])
mprotect(addr vma, len len[addr], prot flags[mmap_prot])
fork()
# TODO: disabled because crashes kernel frequently.
# fork()
waitpid(pid pid, status ptr[out, int32], options flags[wait_options])
nanosleep(req ptr[in, timespec], rem ptr[out, timespec, opt])