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 | |
| parent | 5ef8dbdf5a63ccf7e069527dbb2493dc2ef0c319 (diff) | |
pkg/compiler: allow specifying static size for filename's
Sometimes filenames are embed into structs and need to take fixed space.
| -rw-r--r-- | docs/syscall_descriptions_syntax.md | 4 | ||||
| -rw-r--r-- | executor/syscalls_test.h | 10 | ||||
| -rw-r--r-- | pkg/compiler/types.go | 8 | ||||
| -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 | ||||
| -rw-r--r-- | sys/test/32.go | 12 | ||||
| -rw-r--r-- | sys/test/64.go | 12 | ||||
| -rw-r--r-- | sys/test/test.txt | 9 |
11 files changed, 80 insertions, 16 deletions
diff --git a/docs/syscall_descriptions_syntax.md b/docs/syscall_descriptions_syntax.md index 42a6439dd..6d3306232 100644 --- a/docs/syscall_descriptions_syntax.md +++ b/docs/syscall_descriptions_syntax.md @@ -42,7 +42,9 @@ rest of the type-options are type-specific: "stringnoz": a non-zero-terminated memory buffer (no pointer indirection implied), type-options: either a string value in quotes for constant strings (e.g. "foo"), or a reference to string flags, -"filename": a file/link/dir name, no pointer indirection implied, in most cases you want `ptr[in, filename]` +"filename": a file/link/dir name, no pointer indirection implied, + in most cases you want `ptr[in, filename]`, type-options: + static size (optional) "fileoff": offset within a file "len": length of another field (for array it is number of elements), type-options: argname of the object diff --git a/executor/syscalls_test.h b/executor/syscalls_test.h index d5be16213..bea4a537d 100644 --- a/executor/syscalls_test.h +++ b/executor/syscalls_test.h @@ -2,11 +2,11 @@ #if 0 #define GOARCH "32" -#define SYZ_REVISION "d4cbc2aec52e291fefa8155c6c6ca397ba3c9e49" +#define SYZ_REVISION "154a7d4ae122c9736177396c2a2e6c0b506b77d2" #define SYZ_PAGE_SIZE 8192 #define SYZ_NUM_PAGES 2048 #define SYZ_DATA_OFFSET 536870912 -unsigned syscall_count = 92; +unsigned syscall_count = 93; call_t syscalls[] = { {"foo$any0", 0, (syscall_t)foo}, {"foo$anyres", 0, (syscall_t)foo}, @@ -69,6 +69,7 @@ call_t syscalls[] = { {"syz_test$length26", 0, (syscall_t)syz_test}, {"syz_test$length27", 0, (syscall_t)syz_test}, {"syz_test$length28", 0, (syscall_t)syz_test}, + {"syz_test$length29", 0, (syscall_t)syz_test}, {"syz_test$length3", 0, (syscall_t)syz_test}, {"syz_test$length4", 0, (syscall_t)syz_test}, {"syz_test$length5", 0, (syscall_t)syz_test}, @@ -106,11 +107,11 @@ call_t syscalls[] = { #if 0 #define GOARCH "64" -#define SYZ_REVISION "cabe73c3b49273a8b0cd13bff35d40897dd88138" +#define SYZ_REVISION "07f96db2fe414280f7b2c908e79f44d3d134b8f8" #define SYZ_PAGE_SIZE 4096 #define SYZ_NUM_PAGES 4096 #define SYZ_DATA_OFFSET 536870912 -unsigned syscall_count = 92; +unsigned syscall_count = 93; call_t syscalls[] = { {"foo$any0", 0, (syscall_t)foo}, {"foo$anyres", 0, (syscall_t)foo}, @@ -173,6 +174,7 @@ call_t syscalls[] = { {"syz_test$length26", 0, (syscall_t)syz_test}, {"syz_test$length27", 0, (syscall_t)syz_test}, {"syz_test$length28", 0, (syscall_t)syz_test}, + {"syz_test$length29", 0, (syscall_t)syz_test}, {"syz_test$length3", 0, (syscall_t)syz_test}, {"syz_test$length4", 0, (syscall_t)syz_test}, {"syz_test$length5", 0, (syscall_t)syz_test}, diff --git a/pkg/compiler/types.go b/pkg/compiler/types.go index a7734262a..f5ec1221e 100644 --- a/pkg/compiler/types.go +++ b/pkg/compiler/types.go @@ -264,11 +264,19 @@ var typeArgFlags = &typeArg{ var typeFilename = &typeDesc{ Names: []string{"filename"}, CantBeOpt: true, + OptArgs: 1, + Args: []namedArg{{"size", typeArgInt}}, Varlen: func(comp *compiler, t *ast.Type, args []*ast.Type) bool { + if len(args) >= 1 { + return false + } return true }, Gen: func(comp *compiler, t *ast.Type, args []*ast.Type, base prog.IntTypeCommon) prog.Type { base.TypeSize = 0 + if len(args) >= 1 { + base.TypeSize = args[0].Value + } return &prog.BufferType{ TypeCommon: base.TypeCommon, Kind: prog.BufferFilename, 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 diff --git a/sys/test/32.go b/sys/test/32.go index 7425c8bd9..50611b0dd 100644 --- a/sys/test/32.go +++ b/sys/test/32.go @@ -93,6 +93,13 @@ var structDescs_32 = []*KeyedStruct{ &BufferType{TypeCommon: TypeCommon{TypeName: "string", FldName: "a", TypeSize: 10}, Kind: 2, SubKind: "serialize_strings", Values: []string{"aaa\x00\x00\x00\x00\x00\x00\x00", "bbb\x00\x00\x00\x00\x00\x00\x00"}}, &BufferType{TypeCommon: TypeCommon{TypeName: "string", FldName: "b", TypeSize: 5}, Kind: 2, SubKind: "serialize_strings", Values: []string{"aaa\x00\x00", "bbb\x00\x00"}}, }}}, + {Key: StructKey{Name: "static_filename"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "static_filename", TypeSize: 33}, Fields: []Type{ + &BufferType{TypeCommon: TypeCommon{TypeName: "filename", FldName: "f1", TypeSize: 10}, Kind: 3}, + &BufferType{TypeCommon: TypeCommon{TypeName: "filename", FldName: "f2", TypeSize: 20}, Kind: 3}, + &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "bytesize", FldName: "f3", TypeSize: 1}}, BitSize: 8, Buf: "f1"}, + &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "bytesize", FldName: "f4", TypeSize: 1}}, BitSize: 8, Buf: "f2"}, + &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "bytesize", FldName: "f5", TypeSize: 1}}, BitSize: 8, Buf: "parent"}, + }}}, {Key: StructKey{Name: "syz_align0"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "syz_align0", TypeSize: 24}, Fields: []Type{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "f0", TypeSize: 2}}}, &ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "pad", TypeSize: 2}}, IsPad: true}, @@ -690,6 +697,9 @@ var syscalls_32 = []*Syscall{ &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "a0", TypeSize: 4}, Type: &UnionType{Key: StructKey{Name: "explicitly_sized_union"}}}, &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "a1", TypeSize: 4}}, Buf: "a0"}, }}, + {Name: "syz_test$length29", CallName: "syz_test", Args: []Type{ + &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "a", TypeSize: 4}, Type: &StructType{Key: StructKey{Name: "static_filename"}}}, + }}, {Name: "syz_test$length3", CallName: "syz_test", Args: []Type{ &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "a0", TypeSize: 4}, Type: &StructType{Key: StructKey{Name: "syz_length_len_struct"}}}, }}, @@ -797,4 +807,4 @@ var consts_32 = []ConstValue{ {Name: "ONLY_32BITS_CONST", Value: 1}, } -const revision_32 = "d4cbc2aec52e291fefa8155c6c6ca397ba3c9e49" +const revision_32 = "154a7d4ae122c9736177396c2a2e6c0b506b77d2" diff --git a/sys/test/64.go b/sys/test/64.go index 4b48d9b05..3c4cf8281 100644 --- a/sys/test/64.go +++ b/sys/test/64.go @@ -93,6 +93,13 @@ var structDescs_64 = []*KeyedStruct{ &BufferType{TypeCommon: TypeCommon{TypeName: "string", FldName: "a", TypeSize: 10}, Kind: 2, SubKind: "serialize_strings", Values: []string{"aaa\x00\x00\x00\x00\x00\x00\x00", "bbb\x00\x00\x00\x00\x00\x00\x00"}}, &BufferType{TypeCommon: TypeCommon{TypeName: "string", FldName: "b", TypeSize: 5}, Kind: 2, SubKind: "serialize_strings", Values: []string{"aaa\x00\x00", "bbb\x00\x00"}}, }}}, + {Key: StructKey{Name: "static_filename"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "static_filename", TypeSize: 33}, Fields: []Type{ + &BufferType{TypeCommon: TypeCommon{TypeName: "filename", FldName: "f1", TypeSize: 10}, Kind: 3}, + &BufferType{TypeCommon: TypeCommon{TypeName: "filename", FldName: "f2", TypeSize: 20}, Kind: 3}, + &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "bytesize", FldName: "f3", TypeSize: 1}}, BitSize: 8, Buf: "f1"}, + &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "bytesize", FldName: "f4", TypeSize: 1}}, BitSize: 8, Buf: "f2"}, + &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "bytesize", FldName: "f5", TypeSize: 1}}, BitSize: 8, Buf: "parent"}, + }}}, {Key: StructKey{Name: "syz_align0"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "syz_align0", TypeSize: 24}, Fields: []Type{ &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "f0", TypeSize: 2}}}, &ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "pad", TypeSize: 2}}, IsPad: true}, @@ -689,6 +696,9 @@ var syscalls_64 = []*Syscall{ &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "a0", TypeSize: 8}, Type: &UnionType{Key: StructKey{Name: "explicitly_sized_union"}}}, &LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "a1", TypeSize: 8}}, Buf: "a0"}, }}, + {Name: "syz_test$length29", CallName: "syz_test", Args: []Type{ + &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "a", TypeSize: 8}, Type: &StructType{Key: StructKey{Name: "static_filename"}}}, + }}, {Name: "syz_test$length3", CallName: "syz_test", Args: []Type{ &PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "a0", TypeSize: 8}, Type: &StructType{Key: StructKey{Name: "syz_length_len_struct"}}}, }}, @@ -795,4 +805,4 @@ var consts_64 = []ConstValue{ {Name: "IPPROTO_UDP", Value: 17}, } -const revision_64 = "cabe73c3b49273a8b0cd13bff35d40897dd88138" +const revision_64 = "07f96db2fe414280f7b2c908e79f44d3d134b8f8" diff --git a/sys/test/test.txt b/sys/test/test.txt index ca548d073..9c074d217 100644 --- a/sys/test/test.txt +++ b/sys/test/test.txt @@ -409,11 +409,20 @@ explicitly_sized_union [ f1 int8 ] [size[42]] +static_filename { + f1 filename[10] + f2 filename[20] + f3 bytesize[f1, int8] + f4 bytesize[f2, int8] + f5 bytesize[parent, int8] +} + syz_test$length24(a ptr[in, len_nontemp5]) syz_test$length25(a0 ptr[in, array[array[int8]]], a1 len[a0]) syz_test$length26(a ptr[in, len_unaligned], b bytesize[a]) syz_test$length27(a0 ptr[in, explicitly_sized], a1 len[a0]) syz_test$length28(a0 ptr[in, explicitly_sized_union], a1 len[a0]) +syz_test$length29(a ptr[in, static_filename]) # Big endian |
