aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/ipc
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-09-22 11:09:53 +0200
committerDmitry Vyukov <dvyukov@google.com>2017-09-22 13:10:55 +0200
commit913d592f973a0155647473eaa032711fe956f8a5 (patch)
tree29b1b2083c00d199cf4d9a30917411d923b49ef4 /pkg/ipc
parentc26ea367cfa790e86800ac025638ad50f95b8287 (diff)
all: more assorted fuchsia support
Diffstat (limited to 'pkg/ipc')
-rw-r--r--pkg/ipc/ipc.go8
-rw-r--r--pkg/ipc/ipc_fuchsia.go82
-rw-r--r--pkg/ipc/ipc_linux.go19
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
}