make ipc.Env.Exec accept the program to execute

This commit is contained in:
Dmitry Vyukov 2015-10-13 11:34:13 +02:00
parent a79bd395ce
commit 9145be6961
6 changed files with 28 additions and 40 deletions

View File

@ -342,17 +342,7 @@ func execute1(env *ipc.Env, p *prog.Prog, workerId int) []cover.Cover {
try := 0 try := 0
retry: retry:
exec := p.SerializeForExec() output, strace, failed, hanged, err := env.Exec(p)
if len(exec) > len(env.In) {
panic("program is too long")
}
copy(env.In, exec)
// Zero out the first word (ncmd), so that we don't have garbage there
// if executor crashes before writing non-garbage there.
for i := 0; i < 4; i++ {
env.Out[i] = 0
}
output, strace, failed, hanged, err := env.Exec()
if err != nil { if err != nil {
if try > 10 { if try > 10 {
panic(err) panic(err)

View File

@ -12,6 +12,8 @@ import (
"strings" "strings"
"syscall" "syscall"
"time" "time"
"github.com/google/syzkaller/prog"
) )
type Env struct { type Env struct {
@ -74,7 +76,19 @@ func (env *Env) Close() error {
} }
} }
func (env *Env) Exec() (output, strace []byte, failed, hanged bool, err0 error) { func (env *Env) Exec(p *prog.Prog) (output, strace []byte, failed, hanged bool, err0 error) {
if p != nil {
progData := p.SerializeForExec()
if len(progData) > len(env.In) {
panic("program is too long")
}
copy(env.In, progData)
}
// Zero out the first word (ncmd), so that we don't have garbage there
// if executor crashes before writing non-garbage there.
for i := 0; i < 4; i++ {
env.Out[i] = 0
}
dir, err := ioutil.TempDir("./", "syzkaller-testdir") dir, err := ioutil.TempDir("./", "syzkaller-testdir")
if err != nil { if err != nil {
err0 = fmt.Errorf("failed to create temp dir: %v", err) err0 = fmt.Errorf("failed to create temp dir: %v", err)
@ -184,8 +198,7 @@ func createMapping(size int) (f *os.File, mem []byte, err error) {
if err != nil { if err != nil {
return return
} }
if _, err = f.Write(make([]byte, size)); err != nil { if err = f.Truncate(int64(size)); err != nil {
// if err = f.Truncate(int64(size)); err != nil {
f.Close() f.Close()
os.Remove(f.Name()) os.Remove(f.Name())
return return

View File

@ -73,10 +73,7 @@ func TestEmptyProg(t *testing.T) {
defer env.Close() defer env.Close()
p := new(prog.Prog) p := new(prog.Prog)
data := p.SerializeForExec() output, strace, failed, hanged, err := env.Exec(p)
copy(env.In, data)
output, strace, failed, hanged, err := env.Exec()
if err != nil { if err != nil {
t.Fatalf("failed to run executor: %v", err) t.Fatalf("failed to run executor: %v", err)
} }
@ -102,10 +99,7 @@ func TestStrace(t *testing.T) {
defer env.Close() defer env.Close()
p := new(prog.Prog) p := new(prog.Prog)
data := p.SerializeForExec() _, strace, failed, hanged, err := env.Exec(p)
copy(env.In, data)
_, strace, failed, hanged, err := env.Exec()
if err != nil { if err != nil {
t.Fatalf("failed to run executor: %v", err) t.Fatalf("failed to run executor: %v", err)
} }
@ -132,10 +126,7 @@ func TestExecute(t *testing.T) {
for i := 0; i < iters/len(flags); i++ { for i := 0; i < iters/len(flags); i++ {
p := prog.Generate(rs, 10, nil) p := prog.Generate(rs, 10, nil)
data := p.SerializeForExec() _, _, _, _, err := env.Exec(p)
copy(env.In, data)
_, _, _, _, err := env.Exec()
if err != nil { if err != nil {
t.Fatalf("failed to run executor: %v", err) t.Fatalf("failed to run executor: %v", err)
} }
@ -169,10 +160,7 @@ func TestCompare(t *testing.T) {
rs, iters := initTest(t) rs, iters := initTest(t)
for i := 0; i < iters; i++ { for i := 0; i < iters; i++ {
p := prog.Generate(rs, 10, nil) p := prog.Generate(rs, 10, nil)
data := p.SerializeForExec() _, strace1, _, _, err := env1.Exec(p)
copy(env1.In, data)
_, strace1, _, _, err := env1.Exec()
if err != nil { if err != nil {
t.Fatalf("failed to run executor: %v", err) t.Fatalf("failed to run executor: %v", err)
} }
@ -187,7 +175,7 @@ func TestCompare(t *testing.T) {
} }
defer env2.Close() // yes, that's defer in a loop defer env2.Close() // yes, that's defer in a loop
_, strace2, _, _, err := env2.Exec() _, strace2, _, _, err := env2.Exec(nil)
if err != nil { if err != nil {
t.Fatalf("failed to run c binary: %v", err) t.Fatalf("failed to run c binary: %v", err)
} }

View File

@ -24,7 +24,7 @@ var (
func main() { func main() {
flag.Parse() flag.Parse()
var progs [][]byte var progs []*prog.Prog
for _, fn := range strings.Split(*flagLog, ",") { for _, fn := range strings.Split(*flagLog, ",") {
logf, err := os.Open(fn) logf, err := os.Open(fn)
if err != nil { if err != nil {
@ -45,13 +45,13 @@ func main() {
continue continue
} }
if last != nil { if last != nil {
progs = append(progs, last.SerializeForExec()) progs = append(progs, last)
last = nil last = nil
cur = cur[:0] cur = cur[:0]
} }
} }
if last != nil { if last != nil {
progs = append(progs, last.SerializeForExec()) progs = append(progs, last)
} }
} }
log.Printf("parsed %v programs", len(progs)) log.Printf("parsed %v programs", len(progs))
@ -71,8 +71,7 @@ func main() {
if idx%1000 == 0 { if idx%1000 == 0 {
log.Printf("executing %v\n", idx) log.Printf("executing %v\n", idx)
} }
copy(env.In, progs[idx%len(progs)]) _, _, _, _, err := env.Exec(progs[idx%len(progs)])
_, _, _, _, err := env.Exec()
if err != nil { if err != nil {
log.Printf("failed to execute program: %v", err) log.Printf("failed to execute program: %v", err)
} }

View File

@ -53,8 +53,7 @@ func main() {
fmt.Fprintf(os.Stderr, "failed to create execution environment: %v\n", err) fmt.Fprintf(os.Stderr, "failed to create execution environment: %v\n", err)
os.Exit(1) os.Exit(1)
} }
copy(env.In, p.SerializeForExec()) output, strace, failed, hanged, err := env.Exec(p)
output, strace, failed, hanged, err := env.Exec()
fmt.Printf("result: failed=%v hanged=%v err=%v\n\n%s", failed, hanged, err, output) fmt.Printf("result: failed=%v hanged=%v err=%v\n\n%s", failed, hanged, err, output)
if *flagStrace { if *flagStrace {
fmt.Printf("strace output:\n%s", strace) fmt.Printf("strace output:\n%s", strace)

View File

@ -59,8 +59,7 @@ func execute(env *ipc.Env, p *prog.Prog) {
if *flagExecutor == "" { if *flagExecutor == "" {
return return
} }
copy(env.In, p.SerializeForExec()) output, _, _, _, err := env.Exec(p)
output, _, _, _, err := env.Exec()
if err != nil { if err != nil {
fmt.Printf("failed to execute executor: %v\n", err) fmt.Printf("failed to execute executor: %v\n", err)
} }