diff options
| -rw-r--r-- | prog/analysis.go | 4 | ||||
| -rw-r--r-- | prog/size_test.go | 4 | ||||
| -rw-r--r-- | sys/decl.go | 2 | ||||
| -rw-r--r-- | sys/test.txt | 11 | ||||
| -rw-r--r-- | sysgen/sysgen.go | 21 |
5 files changed, 37 insertions, 5 deletions
diff --git a/prog/analysis.go b/prog/analysis.go index ad962f3f2..6348a48c6 100644 --- a/prog/analysis.go +++ b/prog/analysis.go @@ -160,8 +160,8 @@ func generateSize(arg *Arg, lenType *sys.LenType) *Arg { case *sys.VmaType: return pageSizeArg(lenType, arg.AddrPagesNum, 0) case *sys.ArrayType: - if lenType.ByteSize { - return constArg(lenType, arg.Size()) + if lenType.ByteSize != 0 { + return constArg(lenType, arg.Size() / lenType.ByteSize) } else { return constArg(lenType, uintptr(len(arg.Inner))) } diff --git a/prog/size_test.go b/prog/size_test.go index 9faa27546..c257eae31 100644 --- a/prog/size_test.go +++ b/prog/size_test.go @@ -102,6 +102,10 @@ func TestAssignSize(t *testing.T) { "syz_test$length15(0xff, 0x0)", "syz_test$length15(0xff, 0x2)", }, + { + "syz_test$length16(&(0x7f0000000000)={[0x42, 0x42], 0xff, 0xff, 0xff, 0xff, 0xff})", + "syz_test$length16(&(0x7f0000000000)={[0x42, 0x42], 0x2, 0x10, 0x8, 0x4, 0x2})", + }, } for i, test := range tests { diff --git a/sys/decl.go b/sys/decl.go index bb82cfa18..63fca61b7 100644 --- a/sys/decl.go +++ b/sys/decl.go @@ -157,7 +157,7 @@ type LenType struct { TypeCommon TypeSize uintptr BigEndian bool - ByteSize bool // want size in bytes instead of array size + ByteSize uintptr // want size in multiple of bytes instead of array size Buf string } diff --git a/sys/test.txt b/sys/test.txt index e6865b467..2c0c489a1 100644 --- a/sys/test.txt +++ b/sys/test.txt @@ -97,6 +97,8 @@ syz_test$length13(a0 ptr[inout, syz_length_large_struct], a1 ptr[inout, len[a0, syz_test$length14(a0 ptr[inout, syz_length_large_struct], a1 ptr[inout, len[a0, int64], opt]) syz_test$length15(a0 int16, a1 len[a0]) +syz_test$length16(a0 ptr[in, syz_length_bytesize_struct]) + syz_length_flags = 0, 1 syz_length_int_struct { @@ -167,6 +169,15 @@ syz_length_large_struct { f2 array[int32, 8] } +syz_length_bytesize_struct { + f0 array[int64, 2] + f1 len[f0, int8] + f2 bytesize[f0, int8] + f3 bytesize2[f0, int8] + f4 bytesize4[f0, int8] + f5 bytesize8[f0, int8] +} + # Big endian. syz_test$end0(a0 ptr[in, syz_end_int_struct]) diff --git a/sysgen/sysgen.go b/sysgen/sysgen.go index 5bda2ed2b..92258150d 100644 --- a/sysgen/sysgen.go +++ b/sysgen/sysgen.go @@ -465,7 +465,7 @@ func generateArg( failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) } fmt.Fprintf(out, "&VmaType{%v}", common()) - case "len", "bytesize": + case "len", "bytesize", "bytesize2", "bytesize4", "bytesize8": canBeArg = true size := uint64(ptrSize) bigEndian := false @@ -479,7 +479,11 @@ func generateArg( failf("wrong number of arguments for %v arg %v, want %v, got %v", typ, name, want, len(a)) } } - fmt.Fprintf(out, "&LenType{%v, Buf: \"%v\", TypeSize: %v, BigEndian: %v, ByteSize: %v}", common(), a[0], size, bigEndian, typ == "bytesize") + byteSize := uint8(0) + if typ != "len" { + byteSize = decodeByteSizeType(typ) + } + fmt.Fprintf(out, "&LenType{%v, Buf: \"%v\", TypeSize: %v, BigEndian: %v, ByteSize: %v}", common(), a[0], size, bigEndian, byteSize) case "flags": canBeArg = true size := uint64(ptrSize) @@ -683,6 +687,19 @@ func decodeIntType(typ string) (uint64, bool) { return uint64(sz / 8), bigEndian } +func decodeByteSizeType(typ string) uint8 { + switch typ { + case "bytesize", "bytesize2", "bytesize4", "bytesize8": + default: + failf("unknown type %v", typ) + } + sz := int64(1) + if typ != "bytesize" { + sz, _ = strconv.ParseInt(typ[8:], 10, 8) + } + return uint8(sz) +} + func isIdentifier(s string) bool { for i, c := range s { if c == '_' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || i > 0 && (c >= '0' && c <= '9') { |
