aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Konovalov <andreyknvl@google.com>2017-01-18 13:03:48 +0100
committerAndrey Konovalov <andreyknvl@google.com>2017-01-18 19:16:07 +0100
commit109c58ef682799fc7e92d7a74a9c3073f1ccd0ec (patch)
tree0afab56194498858fe743589da1466956abbff0b
parent11fa77cbbed73f018515d2ec5c6bff4123aa763a (diff)
prog: mutate sized strings with respect to size
-rw-r--r--prog/mutation.go11
-rw-r--r--prog/validation.go7
-rw-r--r--sys/decl.go1
-rw-r--r--sysgen/sysgen.go4
4 files changed, 19 insertions, 4 deletions
diff --git a/prog/mutation.go b/prog/mutation.go
index 9a48bcf98..eacce8033 100644
--- a/prog/mutation.go
+++ b/prog/mutation.go
@@ -5,6 +5,7 @@ package prog
import (
"fmt"
+ "math"
"math/rand"
"unsafe"
@@ -88,7 +89,7 @@ func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable, corpus []*Pro
panic(fmt.Sprintf("bad arg kind for BufferType: %v", arg.Kind))
}
minLen := int(0)
- maxLen := ^int(0)
+ maxLen := math.MaxInt32
if a.Kind == sys.BufferBlobRange {
minLen = int(a.RangeBegin)
maxLen = int(a.RangeEnd)
@@ -96,7 +97,13 @@ func (p *Prog) Mutate(rs rand.Source, ncalls int, ct *ChoiceTable, corpus []*Pro
arg.Data = mutateData(r, data, minLen, maxLen)
case sys.BufferString:
if r.bin() {
- arg.Data = mutateData(r, append([]byte{}, arg.Data...), int(0), ^int(0))
+ minLen := int(0)
+ maxLen := math.MaxInt32
+ if a.Length != 0 {
+ minLen = int(a.Length)
+ maxLen = int(a.Length)
+ }
+ arg.Data = mutateData(r, append([]byte{}, arg.Data...), minLen, maxLen)
} else {
arg.Data = r.randString(s, a.Values, a.Dir())
}
diff --git a/prog/validation.go b/prog/validation.go
index b2d539282..75d8e95a4 100644
--- a/prog/validation.go
+++ b/prog/validation.go
@@ -97,6 +97,13 @@ func (c *Call) validate(ctx *validCtx) error {
if arg.Val >= uintptr(typ1.ValuesPerProc) {
return fmt.Errorf("syscall %v: per proc arg '%v' has bad value '%v'", c.Meta.Name, typ.Name(), arg.Val)
}
+ case *sys.BufferType:
+ switch typ1.Kind {
+ case sys.BufferString:
+ if typ1.Length != 0 && len(arg.Data) != int(typ1.Length) {
+ return fmt.Errorf("syscall %v: string arg '%v' has size %v, which should be %v", c.Meta.Name, len(arg.Data), typ1.Length)
+ }
+ }
}
switch arg.Kind {
case ArgConst:
diff --git a/sys/decl.go b/sys/decl.go
index d16534a7f..94d05e0c3 100644
--- a/sys/decl.go
+++ b/sys/decl.go
@@ -222,6 +222,7 @@ type BufferType struct {
Text TextKind // for BufferText
SubKind string
Values []string // possible values for BufferString kind
+ Length uintptr // max string length for BufferString kind
}
func (t *BufferType) Size() uintptr {
diff --git a/sysgen/sysgen.go b/sysgen/sysgen.go
index ecc237118..c71936c01 100644
--- a/sysgen/sysgen.go
+++ b/sysgen/sysgen.go
@@ -433,8 +433,8 @@ func generateArg(
for i, s := range vals {
vals[i] = s + "\x00"
}
+ var size uint64
if len(a) >= 2 {
- var size uint64
if v, ok := consts[a[1]]; ok {
size = v
} else {
@@ -454,7 +454,7 @@ func generateArg(
vals[i] = s
}
}
- fmt.Fprintf(out, "&BufferType{%v, Kind: BufferString, SubKind: %q, Values: %#v}", common(), subkind, vals)
+ fmt.Fprintf(out, "&BufferType{%v, Kind: BufferString, SubKind: %q, Values: %#v, Length: %v}", common(), subkind, vals, size)
case "salg_type":
if want := 0; len(a) != want {
failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a))