aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/compiler/types.go23
-rw-r--r--pkg/host/syscalls.go20
-rw-r--r--prog/any.go99
-rw-r--r--prog/decl_test.go3
-rw-r--r--prog/rand.go2
-rw-r--r--prog/size.go2
-rw-r--r--prog/target.go19
-rw-r--r--sys/syz-sysgen/sysgen.go6
8 files changed, 71 insertions, 103 deletions
diff --git a/pkg/compiler/types.go b/pkg/compiler/types.go
index 2fddb4917..fd021cefc 100644
--- a/pkg/compiler/types.go
+++ b/pkg/compiler/types.go
@@ -964,6 +964,29 @@ type optional[T] [
val T
void void
] [varlen]
+
+# prog/any.go knows layout of these types.
+ANYUNION [
+ ANYBLOB array[int8]
+ ANYRES16 ANYRES16
+ ANYRES32 ANYRES32
+ ANYRES64 ANYRES64
+ ANYRESDEC fmt[dec, ANYRES64]
+ ANYRESHEX fmt[hex, ANYRES64]
+ ANYRESOCT fmt[oct, ANYRES64]
+] [varlen]
+
+ANYPTRS [
+ ANYPTR ptr[in, array[ANYUNION]]
+ ANYPTR64 ptr64[in, array[ANYUNION]]
+]
+
+resource ANYRES16[int16]: -1, 0
+resource ANYRES32[int32]: -1, 0
+resource ANYRES64[int64]: -1, 0
+
+syz_builtin0(a ptr[in, ANYPTRS]) (disabled)
+syz_builtin1(a ptr[out, ANYUNION]) (disabled)
`
func init() {
diff --git a/pkg/host/syscalls.go b/pkg/host/syscalls.go
index d63c7ceef..e322fc3b1 100644
--- a/pkg/host/syscalls.go
+++ b/pkg/host/syscalls.go
@@ -16,16 +16,24 @@ func DetectSupportedSyscalls(target *prog.Target, sandbox string) (
log.Logf(1, "detecting supported syscalls")
supported := make(map[*prog.Syscall]bool)
unsupported := make(map[*prog.Syscall]string)
+ const disabledAttribute = "has disabled attribute in descriptions"
// These do not have own host and parasitize on some other OS.
if targets.Get(target.OS, target.Arch).HostFuzzer {
for _, c := range target.Syscalls {
- supported[c] = true
+ if c.Attrs.Disabled {
+ unsupported[c] = disabledAttribute
+ } else {
+ supported[c] = true
+ }
}
} else {
for _, c := range target.Syscalls {
ok, reason := false, ""
- switch c.CallName {
- case "syz_execute_func":
+ switch {
+ case c.Attrs.Disabled:
+ ok = false
+ reason = disabledAttribute
+ case c.CallName == "syz_execute_func":
// syz_execute_func caused multiple problems:
// 1. First it lead to corpus exploision. The program used existing values in registers
// to pollute output area. We tried to zero registers (though, not reliably).
@@ -55,12 +63,6 @@ func DetectSupportedSyscalls(target *prog.Target, sandbox string) (
}
}
}
- for c := range supported {
- if c.Attrs.Disabled {
- delete(supported, c)
- unsupported[c] = "has disabled attribute in descriptions"
- }
- }
return supported, unsupported, nil
}
diff --git a/prog/any.go b/prog/any.go
index ce3736a4b..7bf38b6be 100644
--- a/prog/any.go
+++ b/prog/any.go
@@ -21,88 +21,29 @@ type anyTypes struct {
resoct *ResourceType
}
-// This generates type descriptions for:
-//
-// resource ANYRES16[int16]: 0xffffffffffffffff, 0
-// resource ANYRES32[int32]: 0xffffffffffffffff, 0
-// resource ANYRES64[int64]: 0xffffffffffffffff, 0
-// ANY [
-// bin array[int8]
-// res16 ANYRES16
-// res32 ANYRES32
-// res64 ANYRES64
-// resdec fmt[dec, ANYRES64]
-// reshex fmt[hex, ANYRES64]
-// resoct fmt[oct, ANYRES64]
-// ] [varlen]
-func initAnyTypes(target *Target) {
- target.any.union = &UnionType{
- TypeCommon: TypeCommon{
- TypeName: "ANYUNION",
- IsVarlen: true,
- },
- }
- target.any.array = &ArrayType{
- TypeCommon: TypeCommon{
- TypeName: "ANYARRAY",
- IsVarlen: true,
- },
- Elem: target.any.union,
- }
- target.any.ptrPtr = &PtrType{
- TypeCommon: TypeCommon{
- TypeName: "ANYPTR",
- TypeSize: target.PtrSize,
- IsOptional: true,
- },
- Elem: target.any.array,
- ElemDir: DirIn,
- }
- target.any.ptr64 = &PtrType{
- TypeCommon: TypeCommon{
- TypeName: "ANYPTR64",
- TypeSize: 8,
- IsOptional: true,
- },
- Elem: target.any.array,
- ElemDir: DirIn,
- }
- target.any.blob = &BufferType{
- TypeCommon: TypeCommon{
- TypeName: "ANYBLOB",
- IsVarlen: true,
- },
- }
- createResource := func(name, base string, bf BinaryFormat, size uint64) *ResourceType {
- return &ResourceType{
- TypeCommon: TypeCommon{
- TypeName: name,
- TypeSize: size,
- IsOptional: true,
- },
- ArgFormat: bf,
- Desc: &ResourceDesc{
- Name: name,
- Kind: []string{name},
- Values: []uint64{^uint64(0), 0},
- },
+func (target *Target) initAnyTypes() {
+ var anyPtrs *UnionType
+ for _, typ := range target.types {
+ if typ.Name() == "ANYPTRS" {
+ anyPtrs = typ.(*UnionType)
+ break
}
}
- target.any.res16 = createResource("ANYRES16", "int16", FormatNative, 2)
- target.any.res32 = createResource("ANYRES32", "int32", FormatNative, 4)
- target.any.res64 = createResource("ANYRES64", "int64", FormatNative, 8)
- target.any.resdec = createResource("ANYRESDEC", "int64", FormatStrDec, 20)
- target.any.reshex = createResource("ANYRESHEX", "int64", FormatStrHex, 18)
- target.any.resoct = createResource("ANYRESOCT", "int64", FormatStrOct, 23)
- target.any.union.Fields = []Field{
- {Name: "ANYBLOB", Type: target.any.blob},
- {Name: "ANYRES16", Type: target.any.res16},
- {Name: "ANYRES32", Type: target.any.res32},
- {Name: "ANYRES64", Type: target.any.res64},
- {Name: "ANYRESDEC", Type: target.any.resdec},
- {Name: "ANYRESHEX", Type: target.any.reshex},
- {Name: "ANYRESOCT", Type: target.any.resoct},
+ if anyPtrs == nil {
+ panic("no builtin ANYPTRS type")
}
+ // These types are generated by builtin descriptions in pkg/compiler/types.go.
+ target.any.ptrPtr = anyPtrs.Fields[0].Type.(*PtrType)
+ target.any.ptr64 = anyPtrs.Fields[1].Type.(*PtrType)
+ target.any.array = target.any.ptrPtr.Elem.(*ArrayType)
+ target.any.union = target.any.array.Elem.(*UnionType)
+ target.any.blob = target.any.union.Fields[0].Type.(*BufferType)
+ target.any.res16 = target.any.union.Fields[1].Type.(*ResourceType)
+ target.any.res32 = target.any.union.Fields[2].Type.(*ResourceType)
+ target.any.res64 = target.any.union.Fields[3].Type.(*ResourceType)
+ target.any.resdec = target.any.union.Fields[4].Type.(*ResourceType)
+ target.any.reshex = target.any.union.Fields[5].Type.(*ResourceType)
+ target.any.resoct = target.any.union.Fields[6].Type.(*ResourceType)
}
func (target *Target) getAnyPtrType(size uint64) *PtrType {
diff --git a/prog/decl_test.go b/prog/decl_test.go
index f999ae589..5f1795ec6 100644
--- a/prog/decl_test.go
+++ b/prog/decl_test.go
@@ -13,9 +13,8 @@ func TestResourceCtors(t *testing.T) {
t.Skip("too slow")
}
testEachTarget(t, func(t *testing.T, target *Target) {
- expectFail := false
for _, res := range target.Resources {
- if len(target.calcResourceCtors(res, true)) == 0 != expectFail {
+ if len(target.calcResourceCtors(res, true)) == 0 && !strings.HasPrefix(res.Name, "ANY") {
t.Errorf("resource %v can't be created", res.Name)
}
}
diff --git a/prog/rand.go b/prog/rand.go
index 150f4b266..18c86d77a 100644
--- a/prog/rand.go
+++ b/prog/rand.go
@@ -568,7 +568,7 @@ func (target *Target) GenerateAllSyzProg(rs rand.Source) *Prog {
s := newState(target, target.DefaultChoiceTable(), nil)
handled := make(map[string]bool)
for _, meta := range target.Syscalls {
- if !strings.HasPrefix(meta.CallName, "syz_") || handled[meta.CallName] {
+ if !strings.HasPrefix(meta.CallName, "syz_") || handled[meta.CallName] || meta.Attrs.Disabled {
continue
}
handled[meta.CallName] = true
diff --git a/prog/size.go b/prog/size.go
index 61d382723..6eccec50f 100644
--- a/prog/size.go
+++ b/prog/size.go
@@ -55,7 +55,7 @@ func (target *Target) assignSize(dst *ConstArg, pos Arg, path []string, args []A
offset += buf.Size()
continue
}
- if typ := buf.Type().Name(); typ == target.any.ptrPtr.Name() || typ == target.any.ptr64.Name() {
+ if typ := buf.Type(); typ == target.any.ptrPtr || typ == target.any.ptr64 {
// If path points into squashed argument, we don't have the target argument.
// In such case we simply leave size argument as is. It can't happen during generation,
// only during mutation and mutation can set size to random values, so it should be fine.
diff --git a/prog/target.go b/prog/target.go
index af03dc47f..630fb7cbf 100644
--- a/prog/target.go
+++ b/prog/target.go
@@ -23,7 +23,6 @@ type Target struct {
Syscalls []*Syscall
Resources []*ResourceDesc
Consts []ConstValue
- Types []Type
// MakeDataMmap creates calls that mmaps target data memory range.
MakeDataMmap func() []*Call
@@ -57,10 +56,12 @@ type Target struct {
SpecialPointers []uint64
// Filled by prog package:
+ SyscallMap map[string]*Syscall
+ ConstMap map[string]uint64
+
init sync.Once
initArch func(target *Target)
- SyscallMap map[string]*Syscall
- ConstMap map[string]uint64
+ types []Type
resourceMap map[string]*ResourceDesc
// Maps resource name to a list of calls that can create the resource.
resourceCtors map[string][]*Syscall
@@ -75,12 +76,13 @@ const maxSpecialPointers = 16
var targets = make(map[string]*Target)
-func RegisterTarget(target *Target, initArch func(target *Target)) {
+func RegisterTarget(target *Target, types []Type, initArch func(target *Target)) {
key := target.OS + "/" + target.Arch
if targets[key] != nil {
panic(fmt.Sprintf("duplicate target %v", key))
}
target.initArch = initArch
+ target.types = types
targets[key] = target
}
@@ -122,7 +124,6 @@ func (target *Target) lazyInit() {
target.AnnotateCall = func(c ExecCall) string { return "" }
target.initTarget()
target.initArch(target)
- target.ConstMap = nil // currently used only by initArch
// Give these 2 known addresses fixed positions and prepend target-specific ones at the end.
target.SpecialPointers = append([]uint64{
0x0000000000000000, // NULL pointer (keep this first because code uses special index=0 as NULL)
@@ -132,6 +133,9 @@ func (target *Target) lazyInit() {
if len(target.SpecialPointers) > maxSpecialPointers {
panic("too many special pointers")
}
+ // These are used only during lazyInit.
+ target.ConstMap = nil
+ target.types = nil
}
func (target *Target) initTarget() {
@@ -140,8 +144,8 @@ func (target *Target) initTarget() {
target.ConstMap[c.Name] = c.Value
}
- target.resourceMap = restoreLinks(target.Syscalls, target.Resources, target.Types)
- target.Types = nil
+ target.resourceMap = restoreLinks(target.Syscalls, target.Resources, target.types)
+ target.initAnyTypes()
target.SyscallMap = make(map[string]*Syscall)
for i, c := range target.Syscalls {
@@ -156,7 +160,6 @@ func (target *Target) initTarget() {
for _, res := range target.Resources {
target.resourceCtors[res.Name] = target.calcResourceCtors(res, false)
}
- initAnyTypes(target)
}
func (target *Target) GetConst(name string) uint64 {
diff --git a/sys/syz-sysgen/sysgen.go b/sys/syz-sysgen/sysgen.go
index bf39ba9ee..654664af6 100644
--- a/sys/syz-sysgen/sysgen.go
+++ b/sys/syz-sysgen/sysgen.go
@@ -189,8 +189,8 @@ func generate(target *targets.Target, prg *compiler.Prog, consts map[string]uint
fmt.Fprintf(out, "\tRegisterTarget(&Target{"+
"OS: %q, Arch: %q, Revision: revision_%v, PtrSize: %v, "+
"PageSize: %v, NumPages: %v, DataOffset: %v, Syscalls: syscalls_%v, "+
- "Resources: resources_%v, Types: types_%v, Consts: consts_%v}, "+
- "InitTarget)\n}\n\n",
+ "Resources: resources_%v, Consts: consts_%v}, "+
+ "types_%v, InitTarget)\n}\n\n",
target.OS, target.Arch, target.Arch, target.PtrSize,
target.PageSize, target.NumPages, target.DataOffset,
target.Arch, target.Arch, target.Arch, target.Arch)
@@ -267,7 +267,7 @@ func generateExecutorSyscalls(target *targets.Target, syscalls []*prog.Syscall,
Name: c.Name,
CallName: c.CallName,
NR: int32(c.NR),
- NeedCall: !target.SyscallNumbers || strings.HasPrefix(c.CallName, "syz_"),
+ NeedCall: (!target.SyscallNumbers || strings.HasPrefix(c.CallName, "syz_")) && !c.Attrs.Disabled,
Attrs: attrVals[:last+1],
})
}