From 1517bd95488be386712ddab269ffd1dc1cf37f86 Mon Sep 17 00:00:00 2001 From: Andrey Konovalov Date: Mon, 31 Jul 2017 19:48:42 +0200 Subject: prog: generate missing syscall args when decoding After a change in syscall description the number of syscall arguments might change and some of the programs in corpus get invalidated. This change makes syzkaller to generate missing arguments when decoding a program as an attempt to fix and keep more programs from corpus. --- prog/encoding.go | 5 +++++ prog/prog.go | 31 +++++++++++++++++++++++++++++++ prog/prog_test.go | 9 +++++++++ 3 files changed, 45 insertions(+) diff --git a/prog/encoding.go b/prog/encoding.go index c9d5d40c5..69fcdc6cb 100644 --- a/prog/encoding.go +++ b/prog/encoding.go @@ -171,6 +171,11 @@ func Deserialize(data []byte) (prog *Prog, err error) { if !p.EOF() { return nil, fmt.Errorf("tailing data (line #%v)", p.l) } + if len(c.Args) < len(meta.Args) { + for i := len(c.Args); i < len(meta.Args); i++ { + c.Args = append(c.Args, defaultArg(meta.Args[i])) + } + } if len(c.Args) != len(meta.Args) { return nil, fmt.Errorf("wrong call arg count: %v, want %v", len(c.Args), len(meta.Args)) } diff --git a/prog/prog.go b/prog/prog.go index 98121e781..a6dc0e40d 100644 --- a/prog/prog.go +++ b/prog/prog.go @@ -266,6 +266,37 @@ func returnArg(t sys.Type) Arg { return &ReturnArg{ArgCommon: ArgCommon{typ: t}} } +func defaultArg(t sys.Type) Arg { + switch typ := t.(type) { + case *sys.IntType, *sys.ConstType, *sys.FlagsType, *sys.LenType, *sys.ProcType, *sys.CsumType: + return constArg(t, t.Default()) + case *sys.ResourceType: + return resultArg(t, nil, typ.Desc.Type.Default()) + case *sys.BufferType: + return dataArg(t, nil) + case *sys.ArrayType: + return groupArg(t, nil) + case *sys.StructType: + var inner []Arg + for _, field := range typ.Fields { + inner = append(inner, defaultArg(field)) + } + return groupArg(t, nil) + case *sys.UnionType: + return unionArg(t, defaultArg(typ.Options[0]), typ.Options[0]) + case *sys.VmaType: + return pointerArg(t, 0, 0, 0, nil) + case *sys.PtrType: + var res Arg + if !t.Optional() { + res = defaultArg(typ.Type) + } + return pointerArg(t, 0, 0, 1, res) + default: + panic("unknown arg type") + } +} + func (p *Prog) insertBefore(c *Call, calls []*Call) { idx := 0 for ; idx < len(p.Calls); idx++ { diff --git a/prog/prog_test.go b/prog/prog_test.go index 707c7133a..2d05058ea 100644 --- a/prog/prog_test.go +++ b/prog/prog_test.go @@ -35,6 +35,15 @@ func TestGeneration(t *testing.T) { } } +func TestDefault(t *testing.T) { + initTest(t) + for _, meta := range sys.CallMap { + for _, t := range meta.Args { + defaultArg(t) + } + } +} + func TestSerialize(t *testing.T) { rs, iters := initTest(t) for i := 0; i < iters; i++ { -- cgit mrf-deployment