aboutsummaryrefslogtreecommitdiffstats
path: root/prog
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-03-02 16:14:57 +0100
committerDmitry Vyukov <dvyukov@google.com>2018-03-05 12:10:27 +0100
commit002cecf2022de3ab01c87f905477aa3b063d73fc (patch)
tree674ee06d247de287e04017600f7fc52dc7ba58ec /prog
parent5ef8dbdf5a63ccf7e069527dbb2493dc2ef0c319 (diff)
pkg/compiler: allow specifying static size for filename's
Sometimes filenames are embed into structs and need to take fixed space.
Diffstat (limited to 'prog')
-rw-r--r--prog/analysis.go9
-rw-r--r--prog/mutation.go2
-rw-r--r--prog/rand.go24
-rw-r--r--prog/size_test.go4
-rw-r--r--prog/types.go2
5 files changed, 32 insertions, 9 deletions
diff --git a/prog/analysis.go b/prog/analysis.go
index 626af7446..7d5cc0099 100644
--- a/prog/analysis.go
+++ b/prog/analysis.go
@@ -73,11 +73,16 @@ func (s *state) analyzeImpl(c *Call, resources bool) {
case *BufferType:
a := arg.(*DataArg)
if typ.Dir() != DirOut && len(a.Data()) != 0 {
+ val := string(a.Data())
+ // Remove trailing zero padding.
+ for len(val) >= 2 && val[len(val)-1] == 0 && val[len(val)-2] == 0 {
+ val = val[:len(val)-1]
+ }
switch typ.Kind {
case BufferString:
- s.strings[string(a.Data())] = true
+ s.strings[val] = true
case BufferFilename:
- s.files[string(a.Data())] = true
+ s.files[val] = true
}
}
}
diff --git a/prog/mutation.go b/prog/mutation.go
index dd465cf3d..85a718a80 100644
--- a/prog/mutation.go
+++ b/prog/mutation.go
@@ -194,7 +194,7 @@ func (target *Target) mutateArg(r *randGen, s *state, arg Arg, ctx ArgCtx, updat
a.data = r.randString(s, t)
}
case BufferFilename:
- a.data = []byte(r.filename(s))
+ a.data = []byte(r.filename(s, t))
case BufferText:
data := append([]byte{}, a.Data()...)
a.data = r.mutateText(t.Text, data)
diff --git a/prog/rand.go b/prog/rand.go
index 97571b7ea..d8ba0f33d 100644
--- a/prog/rand.go
+++ b/prog/rand.go
@@ -150,7 +150,19 @@ func (r *randGen) flags(vv []uint64) (v uint64) {
return
}
-func (r *randGen) filename(s *state) string {
+func (r *randGen) filename(s *state, typ *BufferType) string {
+ fn := r.filenameImpl(s)
+ if !typ.Varlen() {
+ size := typ.Size()
+ if uint64(len(fn)) < size {
+ fn += string(make([]byte, size-uint64(len(fn))))
+ }
+ fn = fn[:size]
+ }
+ return fn
+}
+
+func (r *randGen) filenameImpl(s *state) string {
dir := "."
if r.oneOf(2) && len(s.files) != 0 {
files := make([]string, 0, len(s.files))
@@ -540,18 +552,20 @@ func (r *randGen) generateArgImpl(s *state, typ Type, ignoreSpecial bool) (arg A
return MakeDataArg(a, data), nil
case BufferFilename:
if a.Dir() == DirOut {
- sz := 0
+ var sz uint64
switch {
+ case !a.Varlen():
+ sz = a.Size()
case r.nOutOf(1, 3):
- sz = r.Intn(100)
+ sz = r.rand(100)
case r.nOutOf(1, 2):
sz = 108 // UNIX_PATH_MAX
default:
sz = 4096 // PATH_MAX
}
- return MakeOutDataArg(a, uint64(sz)), nil
+ return MakeOutDataArg(a, sz), nil
}
- return MakeDataArg(a, []byte(r.filename(s))), nil
+ return MakeDataArg(a, []byte(r.filename(s, a))), nil
case BufferText:
if a.Dir() == DirOut {
return MakeOutDataArg(a, uint64(r.Intn(100))), nil
diff --git a/prog/size_test.go b/prog/size_test.go
index 08b7cba92..8ce368d09 100644
--- a/prog/size_test.go
+++ b/prog/size_test.go
@@ -146,6 +146,10 @@ func TestAssignSize(t *testing.T) {
"syz_test$length28(&(0x7f0000000000), 0x0)",
"syz_test$length28(&(0x7f0000000000)=@f1, 0x2a)",
},
+ {
+ "syz_test$length29(&(0x7f0000000000)={'./a\\x00', './b/c\\x00', 0x0, 0x0, 0x0})",
+ "syz_test$length29(&(0x7f0000000000)={'./a\\x00', './b/c\\x00', 0xa, 0x14, 0x21})",
+ },
}
for i, test := range tests {
diff --git a/prog/types.go b/prog/types.go
index cdf1a0863..1dee2015b 100644
--- a/prog/types.go
+++ b/prog/types.go
@@ -259,7 +259,7 @@ const (
type BufferType struct {
TypeCommon
Kind BufferKind
- RangeBegin uint64 // for BufferBlobRange kind
+ RangeBegin uint64 // for BufferBlobRange kind, or static size for BufferFilename
RangeEnd uint64 // for BufferBlobRange kind
Text TextKind // for BufferText
SubKind string