diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2017-01-05 14:16:07 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2017-01-09 20:20:48 +0100 |
| commit | 94b38efc1d80ae2854d29af44c6d5918a2cb40cd (patch) | |
| tree | 401943d29621eeb485b016e74e3062178091e12a | |
| parent | b5aa8b45061e01c79cf78fe3a634abf5dc6d3f46 (diff) | |
sys: allow to specify number of pages for vma type
Allows to write vma[4] or vma[5-10] to specify desired number of pages.
| -rw-r--r-- | prog/prog_test.go | 37 | ||||
| -rw-r--r-- | prog/rand.go | 3 | ||||
| -rw-r--r-- | sys/README.md | 3 | ||||
| -rw-r--r-- | sys/decl.go | 2 | ||||
| -rw-r--r-- | sys/test.txt | 4 | ||||
| -rw-r--r-- | sysgen/sysgen.go | 11 |
6 files changed, 56 insertions, 4 deletions
diff --git a/prog/prog_test.go b/prog/prog_test.go index 72e8868e7..218a76821 100644 --- a/prog/prog_test.go +++ b/prog/prog_test.go @@ -8,9 +8,12 @@ import ( "math/rand" "testing" "time" + + "github.com/google/syzkaller/sys" ) func initTest(t *testing.T) (rand.Source, int) { + t.Parallel() iters := 10000 if testing.Short() { iters = 100 @@ -49,3 +52,37 @@ func TestSerialize(t *testing.T) { } } } + +func TestVmaType(t *testing.T) { + rs, iters := initTest(t) + meta := sys.CallMap["syz_test$vma0"] + r := newRand(rs) + for i := 0; i < iters; i++ { + s := newState(nil) + calls := r.generateParticularCall(s, meta) + c := calls[len(calls)-1] + if c.Meta.Name != "syz_test$vma0" { + t.Fatalf("generated wrong call %v", c.Meta.Name) + } + if len(c.Args) != 6 { + t.Fatalf("generated wrong number of args %v", len(c.Args)) + } + check := func(v, l *Arg, min, max uintptr) { + if v.Kind != ArgPointer { + t.Fatalf("vma has bad type: %v, want %v", v.Kind, ArgPointer) + } + if l.Kind != ArgPageSize { + t.Fatalf("len has bad type: %v, want %v", l.Kind, ArgPageSize) + } + if v.AddrPagesNum < min || v.AddrPagesNum > max { + t.Fatalf("vma has bad number of pages: %v, want [%v-%v]", v.AddrPagesNum, min, max) + } + if l.AddrPage < min || l.AddrPage > max { + t.Fatalf("len has bad number of pages: %v, want [%v-%v]", l.AddrPage, min, max) + } + } + check(c.Args[0], c.Args[1], 1, 1e5) + check(c.Args[2], c.Args[3], 5, 5) + check(c.Args[4], c.Args[5], 7, 9) + } +} diff --git a/prog/rand.go b/prog/rand.go index e56893b66..a8b33ea08 100644 --- a/prog/rand.go +++ b/prog/rand.go @@ -596,6 +596,9 @@ func (r *randGen) generateArg(s *state, typ sys.Type) (arg *Arg, calls []*Call) } case *sys.VmaType: npages := r.randPageCount() + if a.RangeBegin != 0 || a.RangeEnd != 0 { + npages = uintptr(int(a.RangeBegin) + r.Intn(int(a.RangeEnd-a.RangeBegin+1))) + } arg := r.randPageAddr(s, a, npages, nil, true) return arg, nil case *sys.FlagsType: diff --git a/sys/README.md b/sys/README.md index 259a1c1f5..6e2ecb75c 100644 --- a/sys/README.md +++ b/sys/README.md @@ -54,7 +54,8 @@ rest of the type-options are type-specific: argname of the object "bytesize": similar to "len", but always denotes the size in bytes, type-options: argname of the object - "vma": a pointer to a set of pages (used as input for mmap/munmap/mremap/madvise) + "vma": a pointer to a set of pages (used as input for mmap/munmap/mremap/madvise), type-options: + optional number of pages (e.g. vma[7]), or a range of pages (e.g. vma[2-4]) "proc": per process int (see description below), type-options: underlying type, value range start, how many values per process ``` diff --git a/sys/decl.go b/sys/decl.go index 63fca61b7..322158b92 100644 --- a/sys/decl.go +++ b/sys/decl.go @@ -143,6 +143,8 @@ func (t *BufferType) Align() uintptr { type VmaType struct { TypeCommon + RangeBegin int64 // in pages + RangeEnd int64 } func (t *VmaType) Size() uintptr { diff --git a/sys/test.txt b/sys/test.txt index 2c0c489a1..b48ca8f5f 100644 --- a/sys/test.txt +++ b/sys/test.txt @@ -199,6 +199,10 @@ syz_end_var_struct { f2 flags[syz_end_flags, int64be] } [packed] +# Vma type. + +syz_test$vma0(v0 vma, l0 len[v0], v1 vma[5], l1 len[v1], v2 vma[7:9], l2 len[v2]) + # Regression tests. syz_test$regression0(a0 ptr[inout, syz_regression0_struct]) diff --git a/sysgen/sysgen.go b/sysgen/sysgen.go index 92258150d..d16841577 100644 --- a/sysgen/sysgen.go +++ b/sysgen/sysgen.go @@ -461,10 +461,15 @@ func generateArg( fmt.Fprintf(out, "&BufferType{%v, Kind: BufferAlgName}", common()) case "vma": canBeArg = true - if want := 0; len(a) != want { - failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) + begin, end := "0", "0" + switch len(a) { + case 0: + case 1: + begin, end = parseRange(a[0], consts) + default: + failf("wrong number of arguments for %v arg %v, want 0 or 1, got %v", typ, name, len(a)) } - fmt.Fprintf(out, "&VmaType{%v}", common()) + fmt.Fprintf(out, "&VmaType{%v, RangeBegin: %v, RangeEnd: %v}", common(), begin, end) case "len", "bytesize", "bytesize2", "bytesize4", "bytesize8": canBeArg = true size := uint64(ptrSize) |
