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
retry:
exec := p.SerializeForExec()
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()
output, strace, failed, hanged, err := env.Exec(p)
if err != nil {
if try > 10 {
panic(err)

View File

@ -12,6 +12,8 @@ import (
"strings"
"syscall"
"time"
"github.com/google/syzkaller/prog"
)
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")
if err != nil {
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 {
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()
os.Remove(f.Name())
return

View File

@ -73,10 +73,7 @@ func TestEmptyProg(t *testing.T) {
defer env.Close()
p := new(prog.Prog)
data := p.SerializeForExec()
copy(env.In, data)
output, strace, failed, hanged, err := env.Exec()
output, strace, failed, hanged, err := env.Exec(p)
if err != nil {
t.Fatalf("failed to run executor: %v", err)
}
@ -102,10 +99,7 @@ func TestStrace(t *testing.T) {
defer env.Close()
p := new(prog.Prog)
data := p.SerializeForExec()
copy(env.In, data)
_, strace, failed, hanged, err := env.Exec()
_, strace, failed, hanged, err := env.Exec(p)
if err != nil {
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++ {
p := prog.Generate(rs, 10, nil)
data := p.SerializeForExec()
copy(env.In, data)
_, _, _, _, err := env.Exec()
_, _, _, _, err := env.Exec(p)
if err != nil {
t.Fatalf("failed to run executor: %v", err)
}
@ -169,10 +160,7 @@ func TestCompare(t *testing.T) {
rs, iters := initTest(t)
for i := 0; i < iters; i++ {
p := prog.Generate(rs, 10, nil)
data := p.SerializeForExec()
copy(env1.In, data)
_, strace1, _, _, err := env1.Exec()
_, strace1, _, _, err := env1.Exec(p)
if err != nil {
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
_, strace2, _, _, err := env2.Exec()
_, strace2, _, _, err := env2.Exec(nil)
if err != nil {
t.Fatalf("failed to run c binary: %v", err)
}

View File

@ -24,7 +24,7 @@ var (
func main() {
flag.Parse()
var progs [][]byte
var progs []*prog.Prog
for _, fn := range strings.Split(*flagLog, ",") {
logf, err := os.Open(fn)
if err != nil {
@ -45,13 +45,13 @@ func main() {
continue
}
if last != nil {
progs = append(progs, last.SerializeForExec())
progs = append(progs, last)
last = nil
cur = cur[:0]
}
}
if last != nil {
progs = append(progs, last.SerializeForExec())
progs = append(progs, last)
}
}
log.Printf("parsed %v programs", len(progs))
@ -71,8 +71,7 @@ func main() {
if idx%1000 == 0 {
log.Printf("executing %v\n", idx)
}
copy(env.In, progs[idx%len(progs)])
_, _, _, _, err := env.Exec()
_, _, _, _, err := env.Exec(progs[idx%len(progs)])
if err != nil {
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)
os.Exit(1)
}
copy(env.In, p.SerializeForExec())
output, strace, failed, hanged, err := env.Exec()
output, strace, failed, hanged, err := env.Exec(p)
fmt.Printf("result: failed=%v hanged=%v err=%v\n\n%s", failed, hanged, err, output)
if *flagStrace {
fmt.Printf("strace output:\n%s", strace)

View File

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