aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Konovalov <andreyknvl@google.com>2017-07-31 19:48:42 +0200
committerAndrey Konovalov <andreyknvl@google.com>2017-08-01 19:19:05 +0200
commit1517bd95488be386712ddab269ffd1dc1cf37f86 (patch)
treea8728b288db3d9511e248360d2252611ffce72d8
parent890882a0cf6eeecb32ec0d79cff56660f573b8c9 (diff)
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.
-rw-r--r--prog/encoding.go5
-rw-r--r--prog/prog.go31
-rw-r--r--prog/prog_test.go9
3 files changed, 45 insertions, 0 deletions
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++ {