diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-09-22 11:09:53 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-09-22 13:10:55 +0200 |
| commit | 913d592f973a0155647473eaa032711fe956f8a5 (patch) | |
| tree | 29b1b2083c00d199cf4d9a30917411d923b49ef4 /pkg/ipc | |
| parent | c26ea367cfa790e86800ac025638ad50f95b8287 (diff) | |
all: more assorted fuchsia support
Diffstat (limited to 'pkg/ipc')
| -rw-r--r-- | pkg/ipc/ipc.go | 8 | ||||
| -rw-r--r-- | pkg/ipc/ipc_fuchsia.go | 82 | ||||
| -rw-r--r-- | pkg/ipc/ipc_linux.go | 19 |
3 files changed, 93 insertions, 16 deletions
diff --git a/pkg/ipc/ipc.go b/pkg/ipc/ipc.go index a7e79b033..bae83806c 100644 --- a/pkg/ipc/ipc.go +++ b/pkg/ipc/ipc.go @@ -31,6 +31,14 @@ const ( FlagCollectComps // collect KCOV comparisons ) +const ( + outputSize = 16 << 20 + + statusFail = 67 + statusError = 68 + statusRetry = 69 +) + var ( flagThreaded = flag.Bool("threaded", true, "use threaded mode in executor") flagCollide = flag.Bool("collide", true, "collide syscalls to provoke data races") diff --git a/pkg/ipc/ipc_fuchsia.go b/pkg/ipc/ipc_fuchsia.go index a95a47f85..7f576b1c2 100644 --- a/pkg/ipc/ipc_fuchsia.go +++ b/pkg/ipc/ipc_fuchsia.go @@ -6,18 +6,54 @@ package ipc import ( + "bytes" + "encoding/binary" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strings" + "time" + + "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/prog" ) type Env struct { - In []byte + bin []string + pid int + config Config StatExecs uint64 StatRestarts uint64 } func MakeEnv(bin string, pid int, config Config) (*Env, error) { - env := &Env{} + if config.Timeout < 7*time.Second { + config.Timeout = 7 * time.Second + } + env := &Env{ + bin: strings.Split(bin, " "), + pid: pid, + config: config, + } + if len(env.bin) == 0 { + return nil, fmt.Errorf("binary is empty string") + } + if false { + env.bin[0] = osutil.Abs(env.bin[0]) + base := filepath.Base(env.bin[0]) + pidStr := fmt.Sprint(pid) + if len(base)+len(pidStr) >= 16 { + // TASK_COMM_LEN is currently set to 16 + base = base[:15-len(pidStr)] + } + binCopy := filepath.Join(filepath.Dir(env.bin[0]), base+pidStr) + if err := os.Link(env.bin[0], binCopy); err == nil { + env.bin[0] = binCopy + } + } return env, nil } @@ -26,5 +62,47 @@ func (env *Env) Close() error { } func (env *Env) Exec(opts *ExecOpts, p *prog.Prog) (output []byte, info []CallInfo, failed, hanged bool, err0 error) { + dir, err := ioutil.TempDir("./", "syzkaller-testdir") + if err != nil { + err0 = fmt.Errorf("failed to create temp dir: %v", err) + return + } + defer os.RemoveAll(dir) + + data := make([]byte, prog.ExecBufferSize) + if err := p.SerializeForExec(data, env.pid); err != nil { + err0 = err + return + } + inbuf := new(bytes.Buffer) + binary.Write(inbuf, binary.LittleEndian, uint64(env.config.Flags)) + binary.Write(inbuf, binary.LittleEndian, uint64(opts.Flags)) + binary.Write(inbuf, binary.LittleEndian, uint64(env.pid)) + inbuf.Write(data) + + cmd := exec.Command(env.bin[0], env.bin[1:]...) + cmd.Env = []string{} + cmd.Dir = dir + cmd.Stdin = inbuf + if env.config.Flags&FlagDebug != 0 { + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stdout + } + if err := cmd.Start(); err != nil { + err0 = err + return + } + done := make(chan error) + go func() { + done <- cmd.Wait() + }() + t := time.NewTimer(env.config.Timeout) + select { + case <-done: + t.Stop() + case <-t.C: + cmd.Process.Kill() + <-done + } return } diff --git a/pkg/ipc/ipc_linux.go b/pkg/ipc/ipc_linux.go index 3023ac0a6..793611b91 100644 --- a/pkg/ipc/ipc_linux.go +++ b/pkg/ipc/ipc_linux.go @@ -22,7 +22,7 @@ import ( ) type Env struct { - In []byte + in []byte out []byte cmd *command @@ -37,12 +37,6 @@ type Env struct { } const ( - outputSize = 16 << 20 - - statusFail = 67 - statusError = 68 - statusRetry = 69 - // Comparison types masks taken from KCOV headers. compSizeMask = 6 compSize8 = 6 @@ -77,7 +71,7 @@ func MakeEnv(bin string, pid int, config Config) (*Env, error) { serializeUint64(inmem[8:], uint64(pid)) inmem = inmem[16:] env := &Env{ - In: inmem, + in: inmem, out: outmem, inFile: inf, outFile: outf, @@ -88,10 +82,7 @@ func MakeEnv(bin string, pid int, config Config) (*Env, error) { if len(env.bin) == 0 { return nil, fmt.Errorf("binary is empty string") } - env.bin[0], err = filepath.Abs(env.bin[0]) // we are going to chdir - if err != nil { - return nil, fmt.Errorf("filepath.Abs failed: %v", err) - } + env.bin[0] = osutil.Abs(env.bin[0]) // we are going to chdir // Append pid to binary name. // E.g. if binary is 'syz-executor' and pid=15, // we create a link from 'syz-executor15' to 'syz-executor' and use 'syz-executor15' as binary. @@ -116,7 +107,7 @@ func (env *Env) Close() error { if env.cmd != nil { env.cmd.close() } - err1 := closeMapping(env.inFile, env.In) + err1 := closeMapping(env.inFile, env.in) err2 := closeMapping(env.outFile, env.out) switch { case err1 != nil: @@ -137,7 +128,7 @@ func (env *Env) Close() error { func (env *Env) Exec(opts *ExecOpts, p *prog.Prog) (output []byte, info []CallInfo, failed, hanged bool, err0 error) { if p != nil { // Copy-in serialized program. - if err := p.SerializeForExec(env.In, env.pid); err != nil { + if err := p.SerializeForExec(env.in, env.pid); err != nil { err0 = fmt.Errorf("executor %v: failed to serialize: %v", env.pid, err) return } |
