mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-26 21:00:30 +00:00
prog: add arbitrary mutation of complex structs
Squash complex structs into flat byte array and mutate this array with generic blob mutations. This allows to mutate what we currently consider as paddings and add/remove paddings from structs, etc.
This commit is contained in:
parent
2145057cb8
commit
9fe8aa42c5
@ -452,8 +452,8 @@ static uintptr_t syz_emit_ethernet(uintptr_t a0, uintptr_t a1, uintptr_t a2)
|
||||
// syz_emit_ethernet(len len[packet], packet ptr[in, eth_packet], frags ptr[in, vnet_fragmentation, opt])
|
||||
// vnet_fragmentation {
|
||||
// full int32[0:1]
|
||||
// count len[frags, int32]
|
||||
// frags array[int32[0:4096], 1:4]
|
||||
// count int32[1:4]
|
||||
// frags array[int32[0:4096], 4]
|
||||
// }
|
||||
if (tunfd < 0)
|
||||
return (uintptr_t)-1;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#if defined(__i386__) || 0
|
||||
#define GOARCH "386"
|
||||
#define SYZ_REVISION "7fa1dc861170866b93bcdf1919d822e8d0a07cec"
|
||||
#define SYZ_REVISION "9ec0173f31cb1936a6a5913dd48542851e4e86c9"
|
||||
#define SYZ_PAGE_SIZE 4096
|
||||
#define SYZ_NUM_PAGES 4096
|
||||
#define SYZ_DATA_OFFSET 536870912
|
||||
@ -1599,7 +1599,7 @@ call_t syscalls[] = {
|
||||
|
||||
#if defined(__x86_64__) || 0
|
||||
#define GOARCH "amd64"
|
||||
#define SYZ_REVISION "f5d957ae165e714c54b67d39db5982187b5393ec"
|
||||
#define SYZ_REVISION "3aed60c42df2cc7ef2ac7f3e16d21628ec0649c9"
|
||||
#define SYZ_PAGE_SIZE 4096
|
||||
#define SYZ_NUM_PAGES 4096
|
||||
#define SYZ_DATA_OFFSET 536870912
|
||||
@ -3249,7 +3249,7 @@ call_t syscalls[] = {
|
||||
|
||||
#if defined(__arm__) || 0
|
||||
#define GOARCH "arm"
|
||||
#define SYZ_REVISION "4b33f66a0aeae24040db5b4a35e18e6ff2977b10"
|
||||
#define SYZ_REVISION "c4a0e4b5eaf2ba6525f3c7ccd07e35532c7cc41e"
|
||||
#define SYZ_PAGE_SIZE 4096
|
||||
#define SYZ_NUM_PAGES 4096
|
||||
#define SYZ_DATA_OFFSET 536870912
|
||||
@ -4854,7 +4854,7 @@ call_t syscalls[] = {
|
||||
|
||||
#if defined(__aarch64__) || 0
|
||||
#define GOARCH "arm64"
|
||||
#define SYZ_REVISION "95e5f9d1ee68c969b1db26d8fd6ef0fb8b329019"
|
||||
#define SYZ_REVISION "757e10e8ba130d265ef537544c5defb8dc52c0b6"
|
||||
#define SYZ_PAGE_SIZE 4096
|
||||
#define SYZ_NUM_PAGES 4096
|
||||
#define SYZ_DATA_OFFSET 536870912
|
||||
@ -6433,7 +6433,7 @@ call_t syscalls[] = {
|
||||
|
||||
#if defined(__ppc64__) || defined(__PPC64__) || defined(__powerpc64__) || 0
|
||||
#define GOARCH "ppc64le"
|
||||
#define SYZ_REVISION "067ce945ca9c59814a9ba64002ae646a553e757c"
|
||||
#define SYZ_REVISION "a6de45082b1273527d9bb9832f7f0abc2820c50a"
|
||||
#define SYZ_PAGE_SIZE 4096
|
||||
#define SYZ_NUM_PAGES 4096
|
||||
#define SYZ_DATA_OFFSET 536870912
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
#if 0
|
||||
#define GOARCH "32"
|
||||
#define SYZ_REVISION "8e3bfbc4dd1f6619b4895bcb80e0004ef4c96928"
|
||||
#define SYZ_REVISION "0d78e9b1f441c9ae33361f9778195af0a245ffdd"
|
||||
#define SYZ_PAGE_SIZE 8192
|
||||
#define SYZ_NUM_PAGES 2048
|
||||
#define SYZ_DATA_OFFSET 536870912
|
||||
unsigned syscall_count = 88;
|
||||
unsigned syscall_count = 90;
|
||||
call_t syscalls[] = {
|
||||
{"foo$any0", 0, (syscall_t)foo},
|
||||
{"foo$anyres", 0, (syscall_t)foo},
|
||||
{"mmap", 0, (syscall_t)mmap},
|
||||
{"mutate0", 0, (syscall_t)mutate0},
|
||||
{"mutate1", 0, (syscall_t)mutate1},
|
||||
@ -102,12 +104,14 @@ call_t syscalls[] = {
|
||||
|
||||
#if 0
|
||||
#define GOARCH "64"
|
||||
#define SYZ_REVISION "4a4abb9774bf056d0952d60f2fffdfdc392353a2"
|
||||
#define SYZ_REVISION "e361957ea430829459298bc20840e4edbd324930"
|
||||
#define SYZ_PAGE_SIZE 4096
|
||||
#define SYZ_NUM_PAGES 4096
|
||||
#define SYZ_DATA_OFFSET 536870912
|
||||
unsigned syscall_count = 88;
|
||||
unsigned syscall_count = 90;
|
||||
call_t syscalls[] = {
|
||||
{"foo$any0", 0, (syscall_t)foo},
|
||||
{"foo$anyres", 0, (syscall_t)foo},
|
||||
{"mmap", 0, (syscall_t)mmap},
|
||||
{"mutate0", 0, (syscall_t)mutate0},
|
||||
{"mutate1", 0, (syscall_t)mutate1},
|
||||
|
@ -123,8 +123,8 @@ func foreachArgImpl(arg Arg, ctx ArgCtx, f func(Arg, *ArgCtx)) {
|
||||
claimedSize := a.Size()
|
||||
varlen := a.Type().Varlen()
|
||||
if varlen && totalSize > claimedSize || !varlen && totalSize != claimedSize {
|
||||
panic(fmt.Sprintf("bad group arg size %v, should be <= %v for %+v",
|
||||
totalSize, claimedSize, a))
|
||||
panic(fmt.Sprintf("bad group arg size %v, should be <= %v for %#v type %#v",
|
||||
totalSize, claimedSize, a, a.Type()))
|
||||
}
|
||||
case *PointerArg:
|
||||
if a.Res != nil {
|
||||
|
303
prog/any.go
Normal file
303
prog/any.go
Normal file
@ -0,0 +1,303 @@
|
||||
package prog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type anyTypes struct {
|
||||
anyUnion *UnionType
|
||||
anyArray *ArrayType
|
||||
anyBlob *BufferType
|
||||
anyPtrPtr *PtrType
|
||||
anyPtr64 *PtrType
|
||||
anyRes32 *ResourceType
|
||||
anyRes64 *ResourceType
|
||||
}
|
||||
|
||||
// This generates type descriptions for:
|
||||
//
|
||||
// resource ANYRES32[int32]: 0xffffffffffffffff, 0
|
||||
// resource ANYRES64[int64]: 0xffffffffffffffff, 0
|
||||
// ANY [
|
||||
// bin array[int8]
|
||||
// ptr ptr[in, array[ANY], opt]
|
||||
// ptr64 ptr64[in, array[ANY], opt]
|
||||
// res32 ANYRES32
|
||||
// res64 ANYRES64
|
||||
// ] [varlen]
|
||||
func initAnyTypes(target *Target) {
|
||||
target.anyUnion = &UnionType{
|
||||
FldName: "ANYUNION",
|
||||
}
|
||||
target.anyArray = &ArrayType{
|
||||
TypeCommon: TypeCommon{
|
||||
TypeName: "ANYARRAY",
|
||||
FldName: "ANYARRAY",
|
||||
IsVarlen: true,
|
||||
},
|
||||
Type: target.anyUnion,
|
||||
}
|
||||
target.anyPtrPtr = &PtrType{
|
||||
TypeCommon: TypeCommon{
|
||||
TypeName: "ptr",
|
||||
FldName: "ANYPTR",
|
||||
TypeSize: target.PtrSize,
|
||||
IsOptional: true,
|
||||
},
|
||||
Type: target.anyArray,
|
||||
}
|
||||
target.anyPtr64 = &PtrType{
|
||||
TypeCommon: TypeCommon{
|
||||
TypeName: "ptr64",
|
||||
FldName: "ANYPTR64",
|
||||
TypeSize: 8,
|
||||
IsOptional: true,
|
||||
},
|
||||
Type: target.anyArray,
|
||||
}
|
||||
target.anyBlob = &BufferType{
|
||||
TypeCommon: TypeCommon{
|
||||
TypeName: "ANYBLOB",
|
||||
FldName: "ANYBLOB",
|
||||
IsVarlen: true,
|
||||
},
|
||||
}
|
||||
createResource := func(name, base string, size uint64) *ResourceType {
|
||||
return &ResourceType{
|
||||
TypeCommon: TypeCommon{
|
||||
TypeName: name,
|
||||
FldName: name,
|
||||
ArgDir: DirIn,
|
||||
TypeSize: size,
|
||||
IsOptional: true,
|
||||
},
|
||||
Desc: &ResourceDesc{
|
||||
Name: name,
|
||||
Kind: []string{name},
|
||||
Values: []uint64{^uint64(0), 0},
|
||||
Type: &IntType{
|
||||
IntTypeCommon: IntTypeCommon{
|
||||
TypeCommon: TypeCommon{
|
||||
TypeName: base,
|
||||
TypeSize: size,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
target.anyRes32 = createResource("ANYRES32", "int32", 4)
|
||||
target.anyRes64 = createResource("ANYRES64", "int64", 8)
|
||||
target.anyUnion.StructDesc = &StructDesc{
|
||||
TypeCommon: TypeCommon{
|
||||
TypeName: "ANYUNION",
|
||||
FldName: "ANYUNION",
|
||||
IsVarlen: true,
|
||||
ArgDir: DirIn,
|
||||
},
|
||||
Fields: []Type{
|
||||
target.anyBlob,
|
||||
target.anyPtrPtr,
|
||||
target.anyPtr64,
|
||||
target.anyRes32,
|
||||
target.anyRes64,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (target *Target) makeAnyPtrType(size uint64, field string) *PtrType {
|
||||
// We need to make a copy because type holds field name,
|
||||
// and field names are used as len target.
|
||||
var typ PtrType
|
||||
if size == target.PtrSize {
|
||||
typ = *target.anyPtrPtr
|
||||
} else if size == 8 {
|
||||
typ = *target.anyPtr64
|
||||
} else {
|
||||
panic(fmt.Sprintf("bad pointer size %v", size))
|
||||
}
|
||||
typ.TypeSize = size
|
||||
if field != "" {
|
||||
typ.FldName = field
|
||||
}
|
||||
return &typ
|
||||
}
|
||||
|
||||
func (target *Target) isAnyPtr(typ Type) bool {
|
||||
ptr, ok := typ.(*PtrType)
|
||||
return ok && ptr.Type == target.anyArray
|
||||
}
|
||||
|
||||
func (p *Prog) complexPtrs() (res []*PointerArg) {
|
||||
for _, c := range p.Calls {
|
||||
ForeachArg(c, func(arg Arg, ctx *ArgCtx) {
|
||||
if ptrArg, ok := arg.(*PointerArg); ok && p.Target.isComplexPtr(ptrArg) {
|
||||
res = append(res, ptrArg)
|
||||
ctx.Stop = true
|
||||
}
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (target *Target) isComplexPtr(arg *PointerArg) bool {
|
||||
if arg.Res == nil || arg.Type().Dir() != DirIn {
|
||||
return false
|
||||
}
|
||||
if target.isAnyPtr(arg.Type()) {
|
||||
return true
|
||||
}
|
||||
res := false
|
||||
ForeachSubArg(arg.Res, func(a1 Arg, ctx *ArgCtx) {
|
||||
switch typ := a1.Type().(type) {
|
||||
case *StructType:
|
||||
if typ.Varlen() {
|
||||
res = true
|
||||
ctx.Stop = true
|
||||
}
|
||||
case *UnionType:
|
||||
if typ.Varlen() && len(typ.Fields) > 5 {
|
||||
res = true
|
||||
ctx.Stop = true
|
||||
}
|
||||
case *PtrType:
|
||||
if a1 != arg {
|
||||
ctx.Stop = true
|
||||
}
|
||||
}
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
func (target *Target) CallContainsAny(c *Call) (res bool) {
|
||||
ForeachArg(c, func(arg Arg, ctx *ArgCtx) {
|
||||
if target.isAnyPtr(arg.Type()) {
|
||||
res = true
|
||||
ctx.Stop = true
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (target *Target) ArgContainsAny(arg0 Arg) (res bool) {
|
||||
ForeachSubArg(arg0, func(arg Arg, ctx *ArgCtx) {
|
||||
if target.isAnyPtr(arg.Type()) {
|
||||
res = true
|
||||
ctx.Stop = true
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (target *Target) squashPtr(arg *PointerArg, preserveField bool) {
|
||||
if arg.Res == nil || arg.VmaSize != 0 {
|
||||
panic("bad ptr arg")
|
||||
}
|
||||
res0 := arg.Res
|
||||
size0 := res0.Size()
|
||||
var elems []Arg
|
||||
target.squashPtrImpl(arg.Res, &elems)
|
||||
field := ""
|
||||
if preserveField {
|
||||
field = arg.Type().FieldName()
|
||||
}
|
||||
arg.typ = target.makeAnyPtrType(arg.Type().Size(), field)
|
||||
arg.Res = MakeGroupArg(arg.typ.(*PtrType).Type, elems)
|
||||
if size := arg.Res.Size(); size != size0 {
|
||||
panic(fmt.Sprintf("squash changed size %v->%v for %v", size0, size, res0.Type()))
|
||||
}
|
||||
}
|
||||
|
||||
func (target *Target) squashPtrImpl(a Arg, elems *[]Arg) {
|
||||
if a.Type().BitfieldMiddle() {
|
||||
panic("bitfield in squash")
|
||||
}
|
||||
var pad uint64
|
||||
switch arg := a.(type) {
|
||||
case *ConstArg:
|
||||
if IsPad(arg.Type()) {
|
||||
pad = arg.Size()
|
||||
} else {
|
||||
// Note: we need a constant value, but it depends on pid for proc.
|
||||
v := arg.ValueForProc(0)
|
||||
elem := target.ensureDataElem(elems)
|
||||
for i := uint64(0); i < arg.Size(); i++ {
|
||||
elem.data = append(elem.Data(), byte(v))
|
||||
v >>= 8
|
||||
}
|
||||
}
|
||||
case *ResultArg:
|
||||
switch arg.Size() {
|
||||
case 4:
|
||||
arg.typ = target.anyRes32
|
||||
case 8:
|
||||
arg.typ = target.anyRes64
|
||||
default:
|
||||
panic("bad size")
|
||||
}
|
||||
*elems = append(*elems, MakeUnionArg(target.anyUnion, arg))
|
||||
case *PointerArg:
|
||||
if arg.Res != nil {
|
||||
target.squashPtr(arg, false)
|
||||
*elems = append(*elems, MakeUnionArg(target.anyUnion, arg))
|
||||
} else {
|
||||
elem := target.ensureDataElem(elems)
|
||||
addr := target.PhysicalAddr(arg)
|
||||
for i := uint64(0); i < arg.Size(); i++ {
|
||||
elem.data = append(elem.Data(), byte(addr))
|
||||
addr >>= 8
|
||||
}
|
||||
}
|
||||
case *UnionArg:
|
||||
if !arg.Type().Varlen() {
|
||||
pad = arg.Size() - arg.Option.Size()
|
||||
}
|
||||
target.squashPtrImpl(arg.Option, elems)
|
||||
case *DataArg:
|
||||
if arg.Type().Dir() == DirOut {
|
||||
pad = arg.Size()
|
||||
} else {
|
||||
elem := target.ensureDataElem(elems)
|
||||
elem.data = append(elem.Data(), arg.Data()...)
|
||||
}
|
||||
case *GroupArg:
|
||||
if typ, ok := arg.Type().(*StructType); ok && typ.Varlen() && typ.AlignAttr != 0 {
|
||||
var fieldsSize uint64
|
||||
for _, fld := range arg.Inner {
|
||||
if !fld.Type().BitfieldMiddle() {
|
||||
fieldsSize += fld.Size()
|
||||
}
|
||||
}
|
||||
if fieldsSize%typ.AlignAttr != 0 {
|
||||
pad = typ.AlignAttr - fieldsSize%typ.AlignAttr
|
||||
}
|
||||
}
|
||||
for _, fld := range arg.Inner {
|
||||
if fld.Type().BitfieldMiddle() {
|
||||
// TODO(dvyukov): handle bitfields
|
||||
continue
|
||||
}
|
||||
target.squashPtrImpl(fld, elems)
|
||||
}
|
||||
default:
|
||||
panic("bad arg kind")
|
||||
}
|
||||
if pad != 0 {
|
||||
elem := target.ensureDataElem(elems)
|
||||
elem.data = append(elem.Data(), make([]byte, pad)...)
|
||||
}
|
||||
}
|
||||
|
||||
func (target *Target) ensureDataElem(elems *[]Arg) *DataArg {
|
||||
if len(*elems) == 0 {
|
||||
res := MakeDataArg(target.anyBlob, nil)
|
||||
*elems = append(*elems, MakeUnionArg(target.anyUnion, res))
|
||||
return res
|
||||
}
|
||||
res, ok := (*elems)[len(*elems)-1].(*UnionArg).Option.(*DataArg)
|
||||
if !ok {
|
||||
res = MakeDataArg(target.anyBlob, nil)
|
||||
*elems = append(*elems, MakeUnionArg(target.anyUnion, res))
|
||||
}
|
||||
return res
|
||||
}
|
74
prog/any_test.go
Normal file
74
prog/any_test.go
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright 2018 syzkaller project authors. All rights reserved.
|
||||
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
package prog
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestIsComplexPtr(t *testing.T) {
|
||||
target, rs, _ := initRandomTargetTest(t, "linux", "amd64")
|
||||
r := newRand(target, rs)
|
||||
compl := make(map[string]bool)
|
||||
for _, meta := range target.Syscalls {
|
||||
for i := 0; i < 10; i++ {
|
||||
s := newState(target, nil)
|
||||
calls := r.generateParticularCall(s, meta)
|
||||
p := &Prog{Target: target, Calls: calls}
|
||||
for _, arg := range p.complexPtrs() {
|
||||
compl[arg.Res.Type().String()] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
var arr []string
|
||||
for id := range compl {
|
||||
arr = append(arr, id)
|
||||
}
|
||||
sort.Strings(arr)
|
||||
t.Log("complex types:\n" + strings.Join(arr, "\n"))
|
||||
}
|
||||
|
||||
func TestSquash(t *testing.T) {
|
||||
target := initTargetTest(t, "test", "64")
|
||||
tests := []struct {
|
||||
prog string
|
||||
squashed string
|
||||
}{
|
||||
{
|
||||
`foo$any0(&(0x7f0000000000)={0x11, 0x11223344, 0x2233, 0x1122334455667788, [{0x0, @res32=0x0, 0x0, @i8=0x44, "aabb"}, {0x0, @res64=0x1, 0x0, @i32=0x11223344, "1122334455667788"}]})`,
|
||||
`foo$any0(&(0x7f0000000000)=ANY=[@ANYBLOB="1100000044332211223300000000000088776655443322110000000000000000", @ANYRES32, @ANYBLOB="00000000000000000000000044aabb000000000000000000", @ANYRES64=0x1, @ANYBLOB="0000000000000000443322111122334455667788"])`,
|
||||
},
|
||||
}
|
||||
for i, test := range tests {
|
||||
t.Run(fmt.Sprint(i), func(t *testing.T) {
|
||||
p, err := target.Deserialize([]byte(test.prog))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to deserialize prog: %v", err)
|
||||
}
|
||||
ptrArg := p.Calls[0].Args[0].(*PointerArg)
|
||||
if !target.isComplexPtr(ptrArg) {
|
||||
t.Fatalf("arg is not complex")
|
||||
}
|
||||
if target.ArgContainsAny(ptrArg) {
|
||||
t.Fatalf("arg is already squashed")
|
||||
}
|
||||
target.squashPtr(ptrArg, true)
|
||||
if !target.ArgContainsAny(ptrArg) {
|
||||
t.Fatalf("arg is not squashed")
|
||||
}
|
||||
p1 := strings.TrimSpace(string(p.Serialize()))
|
||||
target.squashPtr(ptrArg, true)
|
||||
p2 := strings.TrimSpace(string(p.Serialize()))
|
||||
if p1 != p2 {
|
||||
t.Fatalf("double squash changed program:\n%v\nvs:\n%v", p1, p2)
|
||||
}
|
||||
if p1 != test.squashed {
|
||||
t.Fatalf("bad squash result:\n%v\nwant:\n%v", p1, test.squashed)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -72,8 +72,11 @@ func (target *Target) serialize(arg Arg, buf *bytes.Buffer, vars map[Arg]int, va
|
||||
break
|
||||
}
|
||||
fmt.Fprintf(buf, "&%v", target.serializeAddr(a))
|
||||
if a.Res == nil || !target.isDefaultArg(a.Res) {
|
||||
if a.Res == nil || !target.isDefaultArg(a.Res) || target.isAnyPtr(a.Type()) {
|
||||
fmt.Fprintf(buf, "=")
|
||||
if target.isAnyPtr(a.Type()) {
|
||||
fmt.Fprintf(buf, "ANY=")
|
||||
}
|
||||
target.serialize(a.Res, buf, vars, varSeq)
|
||||
}
|
||||
case *DataArg:
|
||||
@ -296,6 +299,17 @@ func (target *Target) parseArg(typ Type, p *parser, vars map[string]Arg) (Arg, e
|
||||
var inner Arg
|
||||
if p.Char() == '=' {
|
||||
p.Parse('=')
|
||||
if p.Char() == 'A' {
|
||||
p.Parse('A')
|
||||
p.Parse('N')
|
||||
p.Parse('Y')
|
||||
p.Parse('=')
|
||||
if typ.Size() == 0 {
|
||||
panic(fmt.Sprintf("TYPESIZE=0: %#v", typ))
|
||||
}
|
||||
typ = target.makeAnyPtrType(typ.Size(), typ.FieldName())
|
||||
typ1 = target.anyArray
|
||||
}
|
||||
inner, err = target.parseArg(typ1, p, vars)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -112,6 +112,7 @@ func checkConstArg(arg *ConstArg, compMap CompMap, exec func()) {
|
||||
}
|
||||
|
||||
func checkDataArg(arg *DataArg, compMap CompMap, exec func()) {
|
||||
// TODO(dvyukov): we need big-endian match for ANYBLOBs.
|
||||
bytes := make([]byte, 8)
|
||||
data := arg.Data()
|
||||
size := len(data)
|
||||
|
325
prog/mutation.go
325
prog/mutation.go
@ -19,6 +19,34 @@ outer:
|
||||
for stop := false; !stop || retry; stop = r.oneOf(3) {
|
||||
retry = false
|
||||
switch {
|
||||
case r.oneOf(5):
|
||||
// Not all calls have anything squashable,
|
||||
// so this has lower priority in reality.
|
||||
complexPtrs := p.complexPtrs()
|
||||
if len(complexPtrs) == 0 {
|
||||
retry = true
|
||||
continue
|
||||
}
|
||||
ptr := complexPtrs[r.Intn(len(complexPtrs))]
|
||||
if !p.Target.isAnyPtr(ptr.Type()) {
|
||||
p.Target.squashPtr(ptr, true)
|
||||
}
|
||||
var blobs []*DataArg
|
||||
ForeachSubArg(ptr, func(arg Arg, _ *ArgCtx) {
|
||||
if data, ok := arg.(*DataArg); ok && arg.Type().Dir() != DirOut {
|
||||
blobs = append(blobs, data)
|
||||
}
|
||||
})
|
||||
if len(blobs) == 0 {
|
||||
retry = true
|
||||
continue
|
||||
}
|
||||
// TODO(dvyukov): we probably want special mutation for ANY.
|
||||
// E.g. merging adjacent ANYBLOBs (we don't create them,
|
||||
// but they can appear in future); or replacing ANYRES
|
||||
// with a blob (and merging it with adjacent blobs).
|
||||
arg := blobs[r.Intn(len(blobs))]
|
||||
arg.data = mutateData(r, arg.Data(), 0, maxBlobLen)
|
||||
case r.nOutOf(1, 100):
|
||||
// Splice with another prog from corpus.
|
||||
if len(corpus) == 0 || len(p.Calls) == 0 {
|
||||
@ -311,31 +339,9 @@ func mutateData(r *randGen, data []byte, minLen, maxLen uint64) []byte {
|
||||
loop:
|
||||
for stop := false; !stop || retry; stop = r.oneOf(3) {
|
||||
retry = false
|
||||
switch r.Intn(14) {
|
||||
// TODO(dvyukov): duplicate part of data.
|
||||
switch r.Intn(7) {
|
||||
case 0:
|
||||
// Append byte.
|
||||
if uint64(len(data)) >= maxLen {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
data = append(data, byte(r.rand(256)))
|
||||
case 1:
|
||||
// Remove byte.
|
||||
if len(data) == 0 || uint64(len(data)) <= minLen {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data))
|
||||
copy(data[i:], data[i+1:])
|
||||
data = data[:len(data)-1]
|
||||
case 2:
|
||||
// Replace byte with random value.
|
||||
if len(data) == 0 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
data[r.Intn(len(data))] = byte(r.rand(256))
|
||||
case 3:
|
||||
// Flip bit in byte.
|
||||
if len(data) == 0 {
|
||||
retry = true
|
||||
@ -344,122 +350,49 @@ loop:
|
||||
byt := r.Intn(len(data))
|
||||
bit := r.Intn(8)
|
||||
data[byt] ^= 1 << uint(bit)
|
||||
case 4:
|
||||
// Swap two bytes.
|
||||
if len(data) < 2 {
|
||||
case 1:
|
||||
// Insert random bytes.
|
||||
if len(data) == 0 || uint64(len(data)) >= maxLen {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i1 := r.Intn(len(data))
|
||||
i2 := r.Intn(len(data))
|
||||
data[i1], data[i2] = data[i2], data[i1]
|
||||
case 5:
|
||||
// Add / subtract from a byte.
|
||||
if len(data) == 0 {
|
||||
retry = true
|
||||
continue loop
|
||||
n := r.Intn(16) + 1
|
||||
if r := int(maxLen) - len(data); n > r {
|
||||
n = r
|
||||
}
|
||||
i := r.Intn(len(data))
|
||||
delta := byte(r.rand(2*maxInc+1) - maxInc)
|
||||
if delta == 0 {
|
||||
delta = 1
|
||||
pos := r.Intn(len(data))
|
||||
for i := 0; i < n; i++ {
|
||||
data = append(data, 0)
|
||||
}
|
||||
data[i] += delta
|
||||
case 6:
|
||||
// Add / subtract from a uint16.
|
||||
if len(data) < 2 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 1)
|
||||
p := (*uint16)(unsafe.Pointer(&data[i]))
|
||||
delta := uint16(r.rand(2*maxInc+1) - maxInc)
|
||||
if delta == 0 {
|
||||
delta = 1
|
||||
copy(data[pos+n:], data[pos:])
|
||||
for i := 0; i < n; i++ {
|
||||
data[pos+i] = byte(r.Int31())
|
||||
}
|
||||
if r.bin() {
|
||||
*p += delta
|
||||
} else {
|
||||
*p = swap16(swap16(*p) + delta)
|
||||
data = data[:len(data)-n] // preserve original length
|
||||
}
|
||||
case 7:
|
||||
// Add / subtract from a uint32.
|
||||
if len(data) < 4 {
|
||||
case 2:
|
||||
// Remove bytes.
|
||||
if uint64(len(data)) <= minLen {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 3)
|
||||
p := (*uint32)(unsafe.Pointer(&data[i]))
|
||||
delta := uint32(r.rand(2*maxInc+1) - maxInc)
|
||||
if delta == 0 {
|
||||
delta = 1
|
||||
n := r.Intn(16) + 1
|
||||
if n > len(data) {
|
||||
n = len(data)
|
||||
}
|
||||
pos := 0
|
||||
if n < len(data) {
|
||||
pos = r.Intn(len(data) - n)
|
||||
}
|
||||
copy(data[pos:], data[pos+n:])
|
||||
data = data[:len(data)-n]
|
||||
if r.bin() {
|
||||
*p += delta
|
||||
} else {
|
||||
*p = swap32(swap32(*p) + delta)
|
||||
for i := 0; i < n; i++ {
|
||||
data = append(data, 0) // preserve original length
|
||||
}
|
||||
}
|
||||
case 8:
|
||||
// Add / subtract from a uint64.
|
||||
if len(data) < 8 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 7)
|
||||
p := (*uint64)(unsafe.Pointer(&data[i]))
|
||||
delta := r.rand(2*maxInc+1) - maxInc
|
||||
if delta == 0 {
|
||||
delta = 1
|
||||
}
|
||||
if r.bin() {
|
||||
*p += delta
|
||||
} else {
|
||||
*p = swap64(swap64(*p) + delta)
|
||||
}
|
||||
case 9:
|
||||
// Set byte to an interesting value.
|
||||
if len(data) == 0 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
data[r.Intn(len(data))] = byte(r.randInt())
|
||||
case 10:
|
||||
// Set uint16 to an interesting value.
|
||||
if len(data) < 2 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 1)
|
||||
value := uint16(r.randInt())
|
||||
if r.bin() {
|
||||
value = swap16(value)
|
||||
}
|
||||
*(*uint16)(unsafe.Pointer(&data[i])) = value
|
||||
case 11:
|
||||
// Set uint32 to an interesting value.
|
||||
if len(data) < 4 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 3)
|
||||
value := uint32(r.randInt())
|
||||
if r.bin() {
|
||||
value = swap32(value)
|
||||
}
|
||||
*(*uint32)(unsafe.Pointer(&data[i])) = value
|
||||
case 12:
|
||||
// Set uint64 to an interesting value.
|
||||
if len(data) < 8 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 7)
|
||||
value := r.randInt()
|
||||
if r.bin() {
|
||||
value = swap64(value)
|
||||
}
|
||||
*(*uint64)(unsafe.Pointer(&data[i])) = value
|
||||
case 13:
|
||||
case 3:
|
||||
// Append a bunch of bytes.
|
||||
if uint64(len(data)) >= maxLen {
|
||||
retry = true
|
||||
@ -473,6 +406,146 @@ loop:
|
||||
for i := 0; i < n; i++ {
|
||||
data = append(data, byte(r.rand(256)))
|
||||
}
|
||||
case 4:
|
||||
// Replace int8/int16/int32/int64 with a random value.
|
||||
switch r.Intn(4) {
|
||||
case 0: // int8
|
||||
if len(data) == 0 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
data[r.Intn(len(data))] = byte(r.rand(1 << 8))
|
||||
case 1: // int16
|
||||
if len(data) < 2 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 1)
|
||||
p := (*uint16)(unsafe.Pointer(&data[i]))
|
||||
*p = uint16(r.rand(1 << 16))
|
||||
case 2: // int32
|
||||
if len(data) < 4 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 3)
|
||||
p := (*uint32)(unsafe.Pointer(&data[i]))
|
||||
*p = uint32(r.rand(1 << 32))
|
||||
case 3: // int64
|
||||
if len(data) < 8 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 7)
|
||||
p := (*uint64)(unsafe.Pointer(&data[i]))
|
||||
*p = r.Uint64()
|
||||
}
|
||||
case 5:
|
||||
// Add/subtract from an int8/int16/int32/int64.
|
||||
switch r.Intn(4) {
|
||||
case 0: // int8
|
||||
if len(data) == 0 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data))
|
||||
delta := byte(r.rand(2*maxInc+1) - maxInc)
|
||||
if delta == 0 {
|
||||
delta = 1
|
||||
}
|
||||
data[i] += delta
|
||||
case 1: // int16
|
||||
if len(data) < 2 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 1)
|
||||
p := (*uint16)(unsafe.Pointer(&data[i]))
|
||||
delta := uint16(r.rand(2*maxInc+1) - maxInc)
|
||||
if delta == 0 {
|
||||
delta = 1
|
||||
}
|
||||
if r.oneOf(10) {
|
||||
*p = swap16(swap16(*p) + delta)
|
||||
} else {
|
||||
*p += delta
|
||||
}
|
||||
case 2: // int32
|
||||
if len(data) < 4 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 3)
|
||||
p := (*uint32)(unsafe.Pointer(&data[i]))
|
||||
delta := uint32(r.rand(2*maxInc+1) - maxInc)
|
||||
if delta == 0 {
|
||||
delta = 1
|
||||
}
|
||||
if r.oneOf(10) {
|
||||
*p = swap32(swap32(*p) + delta)
|
||||
} else {
|
||||
*p += delta
|
||||
}
|
||||
case 3: // int64
|
||||
if len(data) < 8 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 7)
|
||||
p := (*uint64)(unsafe.Pointer(&data[i]))
|
||||
delta := r.rand(2*maxInc+1) - maxInc
|
||||
if delta == 0 {
|
||||
delta = 1
|
||||
}
|
||||
if r.oneOf(10) {
|
||||
*p = swap64(swap64(*p) + delta)
|
||||
} else {
|
||||
*p += delta
|
||||
}
|
||||
}
|
||||
case 6:
|
||||
// Set int8/int16/int32/int64 to an interesting value.
|
||||
switch r.Intn(4) {
|
||||
case 0: // int8
|
||||
if len(data) == 0 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
data[r.Intn(len(data))] = byte(r.randInt())
|
||||
case 1: // int16
|
||||
if len(data) < 2 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 1)
|
||||
value := uint16(r.randInt())
|
||||
if r.oneOf(10) {
|
||||
value = swap16(value)
|
||||
}
|
||||
*(*uint16)(unsafe.Pointer(&data[i])) = value
|
||||
case 2: // int32
|
||||
if len(data) < 4 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 3)
|
||||
value := uint32(r.randInt())
|
||||
if r.oneOf(10) {
|
||||
value = swap32(value)
|
||||
}
|
||||
*(*uint32)(unsafe.Pointer(&data[i])) = value
|
||||
case 3: // int64
|
||||
if len(data) < 8 {
|
||||
retry = true
|
||||
continue loop
|
||||
}
|
||||
i := r.Intn(len(data) - 7)
|
||||
value := r.randInt()
|
||||
if r.oneOf(10) {
|
||||
value = swap64(value)
|
||||
}
|
||||
*(*uint64)(unsafe.Pointer(&data[i])) = value
|
||||
}
|
||||
default:
|
||||
panic("bad")
|
||||
}
|
||||
|
18
prog/prog.go
18
prog/prog.go
@ -90,6 +90,24 @@ func (arg *ConstArg) Value() (uint64, uint64, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
func (arg *ConstArg) ValueForProc(pid uint64) uint64 {
|
||||
v, stride, be := arg.Value()
|
||||
v += stride * pid
|
||||
if be {
|
||||
switch arg.Size() {
|
||||
case 2:
|
||||
v = uint64(swap16(uint16(v)))
|
||||
case 4:
|
||||
v = uint64(swap32(uint32(v)))
|
||||
case 8:
|
||||
v = swap64(v)
|
||||
default:
|
||||
panic(fmt.Sprintf("bad const size %v", arg.Size()))
|
||||
}
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Used for PtrType and VmaType.
|
||||
type PointerArg struct {
|
||||
ArgCommon
|
||||
|
14
prog/rand.go
14
prog/rand.go
@ -469,15 +469,17 @@ func (r *randGen) generateArgImpl(s *state, typ Type, ignoreSpecial bool) (arg A
|
||||
|
||||
// Allow infinite recursion for optional pointers.
|
||||
if pt, ok := typ.(*PtrType); ok && typ.Optional() {
|
||||
if str, ok := pt.Type.(*StructType); ok {
|
||||
r.recDepth[str.Name()] += 1
|
||||
switch pt.Type.(type) {
|
||||
case *StructType, *ArrayType, *UnionType:
|
||||
name := pt.Type.Name()
|
||||
r.recDepth[name] += 1
|
||||
defer func() {
|
||||
r.recDepth[str.Name()] -= 1
|
||||
if r.recDepth[str.Name()] == 0 {
|
||||
delete(r.recDepth, str.Name())
|
||||
r.recDepth[name] -= 1
|
||||
if r.recDepth[name] == 0 {
|
||||
delete(r.recDepth, name)
|
||||
}
|
||||
}()
|
||||
if r.recDepth[str.Name()] >= 3 {
|
||||
if r.recDepth[name] >= 3 {
|
||||
return MakeNullPointerArg(typ), nil
|
||||
}
|
||||
}
|
||||
|
@ -33,6 +33,9 @@ func (target *Target) calcResourceCtors(kind []string, precise bool) []*Syscall
|
||||
|
||||
// isCompatibleResource returns true if resource of kind src can be passed as an argument of kind dst.
|
||||
func (target *Target) isCompatibleResource(dst, src string) bool {
|
||||
if dst == target.anyRes32.TypeName || dst == target.anyRes64.TypeName {
|
||||
return true
|
||||
}
|
||||
dstRes := target.resourceMap[dst]
|
||||
if dstRes == nil {
|
||||
panic(fmt.Sprintf("unknown resource '%v'", dst))
|
||||
|
@ -52,6 +52,7 @@ type Target struct {
|
||||
resourceMap map[string]*ResourceDesc
|
||||
// Maps resource name to a list of calls that can create the resource.
|
||||
resourceCtors map[string][]*Syscall
|
||||
anyTypes
|
||||
}
|
||||
|
||||
var targets = make(map[string]*Target)
|
||||
@ -148,6 +149,7 @@ func (target *Target) initTarget() {
|
||||
for _, res := range target.Resources {
|
||||
target.resourceCtors[res.Name] = target.calcResourceCtors(res.Kind, false)
|
||||
}
|
||||
initAnyTypes(target)
|
||||
}
|
||||
|
||||
type Gen struct {
|
||||
|
@ -24,7 +24,21 @@ const (
|
||||
DirInOut
|
||||
)
|
||||
|
||||
func (dir Dir) String() string {
|
||||
switch dir {
|
||||
case DirIn:
|
||||
return "in"
|
||||
case DirOut:
|
||||
return "out"
|
||||
case DirInOut:
|
||||
return "inout"
|
||||
default:
|
||||
panic("unknown dir")
|
||||
}
|
||||
}
|
||||
|
||||
type Type interface {
|
||||
String() string
|
||||
Name() string
|
||||
FieldName() string
|
||||
Dir() Dir
|
||||
@ -108,6 +122,10 @@ type ResourceType struct {
|
||||
Desc *ResourceDesc
|
||||
}
|
||||
|
||||
func (t *ResourceType) String() string {
|
||||
return t.Name()
|
||||
}
|
||||
|
||||
func (t *ResourceType) Default() uint64 {
|
||||
return t.Desc.Values[0]
|
||||
}
|
||||
@ -124,6 +142,10 @@ type IntTypeCommon struct {
|
||||
BitfieldMdl bool
|
||||
}
|
||||
|
||||
func (t *IntTypeCommon) String() string {
|
||||
return t.Name()
|
||||
}
|
||||
|
||||
func (t *IntTypeCommon) BitfieldOffset() uint64 {
|
||||
return t.BitfieldOff
|
||||
}
|
||||
@ -142,6 +164,13 @@ type ConstType struct {
|
||||
IsPad bool
|
||||
}
|
||||
|
||||
func (t *ConstType) String() string {
|
||||
if t.IsPad {
|
||||
return fmt.Sprintf("pad[%v]", t.Size())
|
||||
}
|
||||
return fmt.Sprintf("const[%v, %v]", t.Val, t.IntTypeCommon.String())
|
||||
}
|
||||
|
||||
type IntKind int
|
||||
|
||||
const (
|
||||
@ -193,12 +222,20 @@ type CsumType struct {
|
||||
Protocol uint64 // for CsumPseudo
|
||||
}
|
||||
|
||||
func (t *CsumType) String() string {
|
||||
return "csum"
|
||||
}
|
||||
|
||||
type VmaType struct {
|
||||
TypeCommon
|
||||
RangeBegin uint64 // in pages
|
||||
RangeEnd uint64
|
||||
}
|
||||
|
||||
func (t *VmaType) String() string {
|
||||
return "vma"
|
||||
}
|
||||
|
||||
type BufferKind int
|
||||
|
||||
const (
|
||||
@ -230,6 +267,10 @@ type BufferType struct {
|
||||
NoZ bool // non-zero terminated BufferString
|
||||
}
|
||||
|
||||
func (t *BufferType) String() string {
|
||||
return "buffer"
|
||||
}
|
||||
|
||||
type ArrayKind int
|
||||
|
||||
const (
|
||||
@ -245,17 +286,29 @@ type ArrayType struct {
|
||||
RangeEnd uint64
|
||||
}
|
||||
|
||||
func (t *ArrayType) String() string {
|
||||
return fmt.Sprintf("array[%v]", t.Type.String())
|
||||
}
|
||||
|
||||
type PtrType struct {
|
||||
TypeCommon
|
||||
Type Type
|
||||
}
|
||||
|
||||
func (t *PtrType) String() string {
|
||||
return fmt.Sprintf("ptr[%v, %v]", t.Dir(), t.Type.String())
|
||||
}
|
||||
|
||||
type StructType struct {
|
||||
Key StructKey
|
||||
FldName string
|
||||
*StructDesc
|
||||
}
|
||||
|
||||
func (t *StructType) String() string {
|
||||
return t.Name()
|
||||
}
|
||||
|
||||
func (t *StructType) FieldName() string {
|
||||
return t.FldName
|
||||
}
|
||||
@ -266,6 +319,10 @@ type UnionType struct {
|
||||
*StructDesc
|
||||
}
|
||||
|
||||
func (t *UnionType) String() string {
|
||||
return t.Name()
|
||||
}
|
||||
|
||||
func (t *UnionType) FieldName() string {
|
||||
return t.FldName
|
||||
}
|
||||
|
@ -9996,10 +9996,10 @@ var structDescs_386 = []*KeyedStruct{
|
||||
&UnionType{Key: StructKey{Name: "vmaddr_cid"}, FldName: "cid"},
|
||||
&ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "const", FldName: "pad", TypeSize: 4}}},
|
||||
}, AlignAttr: 8}},
|
||||
{Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation", IsVarlen: true}, Fields: []Type{
|
||||
{Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation", TypeSize: 24}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "full", TypeSize: 4}}, Kind: 2, RangeEnd: 1},
|
||||
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "count", TypeSize: 4}}, Buf: "frags"},
|
||||
&ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags", IsVarlen: true}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 1, RangeEnd: 4},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "count", TypeSize: 4}}, Kind: 2, RangeBegin: 1, RangeEnd: 4},
|
||||
&ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags", TypeSize: 16}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 4, RangeEnd: 4},
|
||||
}}},
|
||||
{Key: StructKey{Name: "vt_consize"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vt_consize", TypeSize: 12}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "rows", TypeSize: 2}}},
|
||||
@ -25032,4 +25032,4 @@ var consts_386 = []ConstValue{
|
||||
{Name: "bpf_insn_load_imm_dw", Value: 24},
|
||||
}
|
||||
|
||||
const revision_386 = "7fa1dc861170866b93bcdf1919d822e8d0a07cec"
|
||||
const revision_386 = "9ec0173f31cb1936a6a5913dd48542851e4e86c9"
|
||||
|
@ -10231,10 +10231,10 @@ var structDescs_amd64 = []*KeyedStruct{
|
||||
&UnionType{Key: StructKey{Name: "vmaddr_cid"}, FldName: "cid"},
|
||||
&ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "const", FldName: "pad", TypeSize: 4}}},
|
||||
}, AlignAttr: 8}},
|
||||
{Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation", IsVarlen: true}, Fields: []Type{
|
||||
{Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation", TypeSize: 24}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "full", TypeSize: 4}}, Kind: 2, RangeEnd: 1},
|
||||
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "count", TypeSize: 4}}, Buf: "frags"},
|
||||
&ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags", IsVarlen: true}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 1, RangeEnd: 4},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "count", TypeSize: 4}}, Kind: 2, RangeBegin: 1, RangeEnd: 4},
|
||||
&ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags", TypeSize: 16}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 4, RangeEnd: 4},
|
||||
}}},
|
||||
{Key: StructKey{Name: "vt_consize"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vt_consize", TypeSize: 12}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "rows", TypeSize: 2}}},
|
||||
@ -25633,4 +25633,4 @@ var consts_amd64 = []ConstValue{
|
||||
{Name: "bpf_insn_load_imm_dw", Value: 24},
|
||||
}
|
||||
|
||||
const revision_amd64 = "f5d957ae165e714c54b67d39db5982187b5393ec"
|
||||
const revision_amd64 = "3aed60c42df2cc7ef2ac7f3e16d21628ec0649c9"
|
||||
|
@ -9845,10 +9845,10 @@ var structDescs_arm = []*KeyedStruct{
|
||||
&UnionType{Key: StructKey{Name: "vmaddr_cid"}, FldName: "cid"},
|
||||
&ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "const", FldName: "pad", TypeSize: 4}}},
|
||||
}, AlignAttr: 8}},
|
||||
{Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation", IsVarlen: true}, Fields: []Type{
|
||||
{Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation", TypeSize: 24}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "full", TypeSize: 4}}, Kind: 2, RangeEnd: 1},
|
||||
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "count", TypeSize: 4}}, Buf: "frags"},
|
||||
&ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags", IsVarlen: true}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 1, RangeEnd: 4},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "count", TypeSize: 4}}, Kind: 2, RangeBegin: 1, RangeEnd: 4},
|
||||
&ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags", TypeSize: 16}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 4, RangeEnd: 4},
|
||||
}}},
|
||||
{Key: StructKey{Name: "vt_consize"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vt_consize", TypeSize: 12}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "rows", TypeSize: 2}}},
|
||||
@ -24871,4 +24871,4 @@ var consts_arm = []ConstValue{
|
||||
{Name: "bpf_insn_load_imm_dw", Value: 24},
|
||||
}
|
||||
|
||||
const revision_arm = "4b33f66a0aeae24040db5b4a35e18e6ff2977b10"
|
||||
const revision_arm = "c4a0e4b5eaf2ba6525f3c7ccd07e35532c7cc41e"
|
||||
|
@ -10007,10 +10007,10 @@ var structDescs_arm64 = []*KeyedStruct{
|
||||
&UnionType{Key: StructKey{Name: "vmaddr_cid"}, FldName: "cid"},
|
||||
&ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "const", FldName: "pad", TypeSize: 4}}},
|
||||
}, AlignAttr: 8}},
|
||||
{Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation", IsVarlen: true}, Fields: []Type{
|
||||
{Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation", TypeSize: 24}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "full", TypeSize: 4}}, Kind: 2, RangeEnd: 1},
|
||||
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "count", TypeSize: 4}}, Buf: "frags"},
|
||||
&ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags", IsVarlen: true}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 1, RangeEnd: 4},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "count", TypeSize: 4}}, Kind: 2, RangeBegin: 1, RangeEnd: 4},
|
||||
&ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags", TypeSize: 16}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 4, RangeEnd: 4},
|
||||
}}},
|
||||
{Key: StructKey{Name: "vt_consize"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vt_consize", TypeSize: 12}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "rows", TypeSize: 2}}},
|
||||
@ -25015,4 +25015,4 @@ var consts_arm64 = []ConstValue{
|
||||
{Name: "bpf_insn_load_imm_dw", Value: 24},
|
||||
}
|
||||
|
||||
const revision_arm64 = "95e5f9d1ee68c969b1db26d8fd6ef0fb8b329019"
|
||||
const revision_arm64 = "757e10e8ba130d265ef537544c5defb8dc52c0b6"
|
||||
|
@ -117,6 +117,9 @@ func (arch *arch) generateEbtables(g *prog.Gen, typ prog.Type, old prog.Arg) (
|
||||
arg = old
|
||||
calls = g.MutateArg(arg)
|
||||
}
|
||||
if g.Target().ArgContainsAny(arg) {
|
||||
return
|
||||
}
|
||||
hooksField, entriesField := 4, 7
|
||||
if g.Target().PtrSize == 8 {
|
||||
// Account for paddings.
|
||||
@ -155,6 +158,7 @@ func (arch *arch) generateEbtables(g *prog.Gen, typ prog.Type, old prog.Arg) (
|
||||
}
|
||||
hookArg.Val = addr
|
||||
}
|
||||
// TODO(dvyukov): assign jump targets for targets.
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -9887,10 +9887,10 @@ var structDescs_ppc64le = []*KeyedStruct{
|
||||
&UnionType{Key: StructKey{Name: "vmaddr_cid"}, FldName: "cid"},
|
||||
&ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "const", FldName: "pad", TypeSize: 4}}},
|
||||
}, AlignAttr: 8}},
|
||||
{Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation", IsVarlen: true}, Fields: []Type{
|
||||
{Key: StructKey{Name: "vnet_fragmentation"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vnet_fragmentation", TypeSize: 24}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "full", TypeSize: 4}}, Kind: 2, RangeEnd: 1},
|
||||
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "count", TypeSize: 4}}, Buf: "frags"},
|
||||
&ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags", IsVarlen: true}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 1, RangeEnd: 4},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "count", TypeSize: 4}}, Kind: 2, RangeBegin: 1, RangeEnd: 4},
|
||||
&ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "frags", TypeSize: 16}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}, Kind: 2, RangeEnd: 4096}, Kind: 1, RangeBegin: 4, RangeEnd: 4},
|
||||
}}},
|
||||
{Key: StructKey{Name: "vt_consize"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "vt_consize", TypeSize: 12}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16", FldName: "rows", TypeSize: 2}}},
|
||||
@ -24777,4 +24777,4 @@ var consts_ppc64le = []ConstValue{
|
||||
{Name: "bpf_insn_load_imm_dw", Value: 24},
|
||||
}
|
||||
|
||||
const revision_ppc64le = "067ce945ca9c59814a9ba64002ae646a553e757c"
|
||||
const revision_ppc64le = "a6de45082b1273527d9bb9832f7f0abc2820c50a"
|
||||
|
@ -10,8 +10,8 @@ vnet_fragmentation {
|
||||
# If set and we have remaining data after fragmentation, it is written in an additional fragment.
|
||||
# If not set, data remaining after fragmentation is discarded.
|
||||
full int32[0:1]
|
||||
count len[frags, int32]
|
||||
frags array[int32[0:4096], 1:4]
|
||||
count int32[1:4]
|
||||
frags array[int32[0:4096], 4]
|
||||
}
|
||||
|
||||
resource tcp_seq_num[int32]: 0x42424242
|
||||
|
@ -8,12 +8,38 @@ func init() {
|
||||
}
|
||||
|
||||
var resources_32 = []*ResourceDesc{
|
||||
{Name: "anyres32", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"anyres32"}, Values: []uint64{0}},
|
||||
{Name: "anyres64", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", TypeSize: 8}}}, Kind: []string{"anyres64"}, Values: []uint64{0}},
|
||||
{Name: "fd", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"fd"}, Values: []uint64{18446744073709551615}},
|
||||
{Name: "syz_missing_const_res", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"syz_missing_const_res"}, Values: []uint64{1}},
|
||||
{Name: "syz_res", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"syz_res"}, Values: []uint64{65535}},
|
||||
}
|
||||
|
||||
var structDescs_32 = []*KeyedStruct{
|
||||
{Key: StructKey{Name: "any0"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "any0", IsVarlen: true}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "f1", TypeSize: 1}}},
|
||||
&ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "pad", TypeSize: 3}}, IsPad: true},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "f2", TypeSize: 4}}},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16be", FldName: "f3", TypeSize: 2}, BigEndian: true}},
|
||||
&ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "pad", TypeSize: 6}}, IsPad: true},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", FldName: "f4", TypeSize: 8}}},
|
||||
&ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "f5", IsVarlen: true}, Type: &StructType{Key: StructKey{Name: "any1"}}},
|
||||
}, AlignAttr: 8}},
|
||||
{Key: StructKey{Name: "any1"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "any1", IsVarlen: true}, Fields: []Type{
|
||||
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "f1", TypeSize: 4, IsOptional: true}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", TypeSize: 1}}}},
|
||||
&UnionType{Key: StructKey{Name: "anyunion0"}, FldName: "f2"},
|
||||
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr64", FldName: "f3", TypeSize: 8, IsOptional: true}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", TypeSize: 1}}}},
|
||||
&UnionType{Key: StructKey{Name: "anyunion1"}, FldName: "f4"},
|
||||
&BufferType{TypeCommon: TypeCommon{TypeName: "array", FldName: "f5", IsVarlen: true}},
|
||||
}, AlignAttr: 2}},
|
||||
{Key: StructKey{Name: "anyunion0"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "anyunion0", TypeSize: 8}, Fields: []Type{
|
||||
&ResourceType{TypeCommon: TypeCommon{TypeName: "anyres32", FldName: "res32", TypeSize: 4}},
|
||||
&ResourceType{TypeCommon: TypeCommon{TypeName: "anyres64", FldName: "res64", TypeSize: 8}},
|
||||
}}},
|
||||
{Key: StructKey{Name: "anyunion1"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "anyunion1", IsVarlen: true}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "i8", TypeSize: 1}}},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "i32", TypeSize: 4}}},
|
||||
}}},
|
||||
{Key: StructKey{Name: "len_nontemp4"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "len_nontemp4", TypeSize: 4}, Fields: []Type{
|
||||
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "f1", TypeSize: 4}}, Buf: "len_temp3"},
|
||||
}}},
|
||||
@ -444,6 +470,13 @@ var structDescs_32 = []*KeyedStruct{
|
||||
}
|
||||
|
||||
var syscalls_32 = []*Syscall{
|
||||
{Name: "foo$any0", CallName: "foo", Args: []Type{
|
||||
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "a", TypeSize: 4}, Type: &StructType{Key: StructKey{Name: "any0"}}},
|
||||
}},
|
||||
{Name: "foo$anyres", CallName: "foo", Args: []Type{
|
||||
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "a0", TypeSize: 4}, Type: &ResourceType{TypeCommon: TypeCommon{TypeName: "anyres32", TypeSize: 4, ArgDir: 1}}},
|
||||
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "a1", TypeSize: 4}, Type: &ResourceType{TypeCommon: TypeCommon{TypeName: "anyres64", TypeSize: 8, ArgDir: 1}}},
|
||||
}},
|
||||
{Name: "mmap", CallName: "mmap", Args: []Type{
|
||||
&VmaType{TypeCommon: TypeCommon{TypeName: "vma", FldName: "addr", TypeSize: 4}},
|
||||
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "len", TypeSize: 4}}, Buf: "addr"},
|
||||
@ -739,4 +772,4 @@ var consts_32 = []ConstValue{
|
||||
{Name: "ONLY_32BITS_CONST", Value: 1},
|
||||
}
|
||||
|
||||
const revision_32 = "8e3bfbc4dd1f6619b4895bcb80e0004ef4c96928"
|
||||
const revision_32 = "0d78e9b1f441c9ae33361f9778195af0a245ffdd"
|
||||
|
@ -8,12 +8,38 @@ func init() {
|
||||
}
|
||||
|
||||
var resources_64 = []*ResourceDesc{
|
||||
{Name: "anyres32", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"anyres32"}, Values: []uint64{0}},
|
||||
{Name: "anyres64", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", TypeSize: 8}}}, Kind: []string{"anyres64"}, Values: []uint64{0}},
|
||||
{Name: "fd", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"fd"}, Values: []uint64{18446744073709551615}},
|
||||
{Name: "syz_missing_const_res", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"syz_missing_const_res"}, Values: []uint64{0}},
|
||||
{Name: "syz_res", Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", TypeSize: 4}}}, Kind: []string{"syz_res"}, Values: []uint64{65535}},
|
||||
}
|
||||
|
||||
var structDescs_64 = []*KeyedStruct{
|
||||
{Key: StructKey{Name: "any0"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "any0", IsVarlen: true}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "f1", TypeSize: 1}}},
|
||||
&ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "pad", TypeSize: 3}}, IsPad: true},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "f2", TypeSize: 4}}},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int16be", FldName: "f3", TypeSize: 2}, BigEndian: true}},
|
||||
&ConstType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "pad", TypeSize: 6}}, IsPad: true},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int64", FldName: "f4", TypeSize: 8}}},
|
||||
&ArrayType{TypeCommon: TypeCommon{TypeName: "array", FldName: "f5", IsVarlen: true}, Type: &StructType{Key: StructKey{Name: "any1"}}},
|
||||
}, AlignAttr: 8}},
|
||||
{Key: StructKey{Name: "any1"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "any1", IsVarlen: true}, Fields: []Type{
|
||||
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "f1", TypeSize: 8, IsOptional: true}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", TypeSize: 1}}}},
|
||||
&UnionType{Key: StructKey{Name: "anyunion0"}, FldName: "f2"},
|
||||
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr64", FldName: "f3", TypeSize: 8, IsOptional: true}, Type: &IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", TypeSize: 1}}}},
|
||||
&UnionType{Key: StructKey{Name: "anyunion1"}, FldName: "f4"},
|
||||
&BufferType{TypeCommon: TypeCommon{TypeName: "array", FldName: "f5", IsVarlen: true}},
|
||||
}, AlignAttr: 2}},
|
||||
{Key: StructKey{Name: "anyunion0"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "anyunion0", TypeSize: 8}, Fields: []Type{
|
||||
&ResourceType{TypeCommon: TypeCommon{TypeName: "anyres32", FldName: "res32", TypeSize: 4}},
|
||||
&ResourceType{TypeCommon: TypeCommon{TypeName: "anyres64", FldName: "res64", TypeSize: 8}},
|
||||
}}},
|
||||
{Key: StructKey{Name: "anyunion1"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "anyunion1", IsVarlen: true}, Fields: []Type{
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int8", FldName: "i8", TypeSize: 1}}},
|
||||
&IntType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "int32", FldName: "i32", TypeSize: 4}}},
|
||||
}}},
|
||||
{Key: StructKey{Name: "len_nontemp4"}, Desc: &StructDesc{TypeCommon: TypeCommon{TypeName: "len_nontemp4", TypeSize: 4}, Fields: []Type{
|
||||
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "f1", TypeSize: 4}}, Buf: "len_temp3"},
|
||||
}}},
|
||||
@ -443,6 +469,13 @@ var structDescs_64 = []*KeyedStruct{
|
||||
}
|
||||
|
||||
var syscalls_64 = []*Syscall{
|
||||
{Name: "foo$any0", CallName: "foo", Args: []Type{
|
||||
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "a", TypeSize: 8}, Type: &StructType{Key: StructKey{Name: "any0"}}},
|
||||
}},
|
||||
{Name: "foo$anyres", CallName: "foo", Args: []Type{
|
||||
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "a0", TypeSize: 8}, Type: &ResourceType{TypeCommon: TypeCommon{TypeName: "anyres32", TypeSize: 4, ArgDir: 1}}},
|
||||
&PtrType{TypeCommon: TypeCommon{TypeName: "ptr", FldName: "a1", TypeSize: 8}, Type: &ResourceType{TypeCommon: TypeCommon{TypeName: "anyres64", TypeSize: 8, ArgDir: 1}}},
|
||||
}},
|
||||
{Name: "mmap", CallName: "mmap", Args: []Type{
|
||||
&VmaType{TypeCommon: TypeCommon{TypeName: "vma", FldName: "addr", TypeSize: 8}},
|
||||
&LenType{IntTypeCommon: IntTypeCommon{TypeCommon: TypeCommon{TypeName: "len", FldName: "len", TypeSize: 8}}, Buf: "addr"},
|
||||
@ -737,4 +770,4 @@ var consts_64 = []ConstValue{
|
||||
{Name: "IPPROTO_UDP", Value: 17},
|
||||
}
|
||||
|
||||
const revision_64 = "4a4abb9774bf056d0952d60f2fffdfdc392353a2"
|
||||
const revision_64 = "e361957ea430829459298bc20840e4edbd324930"
|
||||
|
35
sys/test/any.txt
Normal file
35
sys/test/any.txt
Normal file
@ -0,0 +1,35 @@
|
||||
# Copyright 2018 syzkaller project authors. All rights reserved.
|
||||
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
||||
|
||||
resource anyres32[int32]
|
||||
resource anyres64[int64]
|
||||
|
||||
foo$anyres(a0 ptr[out, anyres32], a1 ptr[out, anyres64])
|
||||
|
||||
foo$any0(a ptr[in, any0])
|
||||
|
||||
any0 {
|
||||
f1 int8
|
||||
f2 int32
|
||||
f3 int16be
|
||||
f4 int64
|
||||
f5 array[any1]
|
||||
} [align_8]
|
||||
|
||||
any1 {
|
||||
f1 ptr[in, int8, opt]
|
||||
f2 anyunion0
|
||||
f3 ptr64[in, int8, opt]
|
||||
f4 anyunion1
|
||||
f5 array[int8]
|
||||
} [packed, align_2]
|
||||
|
||||
anyunion0 [
|
||||
res32 anyres32
|
||||
res64 anyres64
|
||||
]
|
||||
|
||||
anyunion1 [
|
||||
i8 int8
|
||||
i32 int32
|
||||
] [varlen]
|
@ -478,11 +478,11 @@ func (fuzzer *Fuzzer) corpusSignalDiff(sign signal.Signal) signal.Signal {
|
||||
return fuzzer.corpusSignal.Diff(sign)
|
||||
}
|
||||
|
||||
func (fuzzer *Fuzzer) checkNewSignal(info []ipc.CallInfo) (calls []int) {
|
||||
func (fuzzer *Fuzzer) checkNewSignal(p *prog.Prog, info []ipc.CallInfo) (calls []int) {
|
||||
fuzzer.signalMu.RLock()
|
||||
defer fuzzer.signalMu.RUnlock()
|
||||
for i, inf := range info {
|
||||
diff := fuzzer.maxSignal.DiffRaw(inf.Signal, signalPrio(&inf))
|
||||
diff := fuzzer.maxSignal.DiffRaw(inf.Signal, signalPrio(p.Target, p.Calls[i], &inf))
|
||||
if diff.Empty() {
|
||||
continue
|
||||
}
|
||||
@ -497,11 +497,14 @@ func (fuzzer *Fuzzer) checkNewSignal(info []ipc.CallInfo) (calls []int) {
|
||||
return
|
||||
}
|
||||
|
||||
func signalPrio(ci *ipc.CallInfo) uint8 {
|
||||
func signalPrio(target *prog.Target, c *prog.Call, ci *ipc.CallInfo) (prio uint8) {
|
||||
if ci.Errno == 0 {
|
||||
return 1
|
||||
prio |= 1 << 1
|
||||
}
|
||||
return 0
|
||||
if !target.CallContainsAny(c) {
|
||||
prio |= 1 << 0
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (fuzzer *Fuzzer) leakCheckCallback() {
|
||||
|
@ -103,13 +103,13 @@ func (proc *Proc) triageInput(item *WorkTriage) {
|
||||
panic("should not be called when coverage is disabled")
|
||||
}
|
||||
|
||||
inputSignal := signal.FromRaw(item.info.Signal, signalPrio(&item.info))
|
||||
call := item.p.Calls[item.call]
|
||||
inputSignal := signal.FromRaw(item.info.Signal, signalPrio(item.p.Target, call, &item.info))
|
||||
newSignal := proc.fuzzer.corpusSignalDiff(inputSignal)
|
||||
if newSignal.Empty() {
|
||||
return
|
||||
}
|
||||
call := item.p.Calls[item.call].Meta
|
||||
Logf(3, "triaging input for %v (new signal=%v)", call.CallName, newSignal.Len())
|
||||
Logf(3, "triaging input for %v (new signal=%v)", call.Meta.CallName, newSignal.Len())
|
||||
var inputCover cover.Cover
|
||||
const (
|
||||
signalRuns = 3
|
||||
@ -128,7 +128,7 @@ func (proc *Proc) triageInput(item *WorkTriage) {
|
||||
continue
|
||||
}
|
||||
inf := info[item.call]
|
||||
thisSignal := signal.FromRaw(inf.Signal, signalPrio(&inf))
|
||||
thisSignal := signal.FromRaw(inf.Signal, signalPrio(item.p.Target, call, &inf))
|
||||
newSignal = newSignal.Intersection(thisSignal)
|
||||
// Without !minimized check manager starts losing some considerable amount
|
||||
// of coverage after each restart. Mechanics of this are not completely clear.
|
||||
@ -151,7 +151,8 @@ func (proc *Proc) triageInput(item *WorkTriage) {
|
||||
// Successful calls are much more valuable.
|
||||
return false
|
||||
}
|
||||
thisSignal := signal.FromRaw(inf.Signal, signalPrio(&inf))
|
||||
prio := signalPrio(p1.Target, p1.Calls[call1], &inf)
|
||||
thisSignal := signal.FromRaw(inf.Signal, prio)
|
||||
if newSignal.Intersection(thisSignal).Len() == newSignal.Len() {
|
||||
return true
|
||||
}
|
||||
@ -163,9 +164,9 @@ func (proc *Proc) triageInput(item *WorkTriage) {
|
||||
data := item.p.Serialize()
|
||||
sig := hash.Hash(data)
|
||||
|
||||
Logf(2, "added new input for %v to corpus:\n%s", call.CallName, data)
|
||||
Logf(2, "added new input for %v to corpus:\n%s", call.Meta.CallName, data)
|
||||
proc.fuzzer.sendInputToManager(RpcInput{
|
||||
Call: call.CallName,
|
||||
Call: call.Meta.CallName,
|
||||
Prog: data,
|
||||
Signal: inputSignal.Serialize(),
|
||||
Cover: inputCover.Serialize(),
|
||||
@ -227,7 +228,7 @@ func (proc *Proc) executeHintSeed(p *prog.Prog, call int) {
|
||||
|
||||
func (proc *Proc) execute(execOpts *ipc.ExecOpts, p *prog.Prog, flags ProgTypes, stat Stat) []ipc.CallInfo {
|
||||
info := proc.executeRaw(execOpts, p, stat)
|
||||
for _, callIndex := range proc.fuzzer.checkNewSignal(info) {
|
||||
for _, callIndex := range proc.fuzzer.checkNewSignal(p, info) {
|
||||
info := info[callIndex]
|
||||
// info.Signal points to the output shmem region, detach it before queueing.
|
||||
info.Signal = append([]uint32{}, info.Signal...)
|
||||
|
Loading…
Reference in New Issue
Block a user