diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-03-02 16:14:57 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-03-05 12:10:27 +0100 |
| commit | 002cecf2022de3ab01c87f905477aa3b063d73fc (patch) | |
| tree | 674ee06d247de287e04017600f7fc52dc7ba58ec /prog | |
| parent | 5ef8dbdf5a63ccf7e069527dbb2493dc2ef0c319 (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.go | 9 | ||||
| -rw-r--r-- | prog/mutation.go | 2 | ||||
| -rw-r--r-- | prog/rand.go | 24 | ||||
| -rw-r--r-- | prog/size_test.go | 4 | ||||
| -rw-r--r-- | prog/types.go | 2 |
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 |
