aboutsummaryrefslogtreecommitdiffstats
path: root/prog/any_test.go
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-05-03 07:13:00 +0200
committerDmitry Vyukov <dvyukov@google.com>2024-05-03 08:23:29 +0000
commit2ca36995aaecbfcd2268b19cf3445fdf64bb508e (patch)
tree8b4a125e7f593a6c70b754d954f0f3d0b89dc67b /prog/any_test.go
parent375d4445a31b220afd91f42a7aa1b610d689a897 (diff)
prog: fix panic during squashing
Netbsd syzbot instance crashes trying to squash a pointer. Pointers must not be squashed. This happens because of recursive ucontext_t type that contains a pointer to itself. When we assign SquashableElem recursive struct types may not be fully generated yet, and ForeachArgType won't observe all types. Assign SquashableElem after all types are fully generated.
Diffstat (limited to 'prog/any_test.go')
-rw-r--r--prog/any_test.go90
1 files changed, 46 insertions, 44 deletions
diff --git a/prog/any_test.go b/prog/any_test.go
index 333266622..8c3f3c8c1 100644
--- a/prog/any_test.go
+++ b/prog/any_test.go
@@ -5,6 +5,7 @@ package prog
import (
"fmt"
+ "math/rand"
"sort"
"strings"
"testing"
@@ -13,56 +14,57 @@ import (
)
func TestIsComplexPtr(t *testing.T) {
- target, rs, _ := initRandomTargetTest(t, "linux", "amd64")
- allComplex := make(map[string]bool)
- ForeachType(target.Syscalls, func(t Type, ctx *TypeCtx) {
- if ptr, ok := t.(*PtrType); ok && ptr.SquashableElem {
- allComplex[ptr.Elem.String()] = true
+ testEachTargetRandom(t, func(t *testing.T, target *Target, rs rand.Source, iters int) {
+ allComplex := make(map[string]bool)
+ ForeachType(target.Syscalls, func(t Type, ctx *TypeCtx) {
+ if ptr, ok := t.(*PtrType); ok && ptr.SquashableElem {
+ allComplex[ptr.Elem.String()] = true
+ }
+ })
+ var arr []string
+ for id := range allComplex {
+ arr = append(arr, id)
}
- })
- var arr []string
- for id := range allComplex {
- arr = append(arr, id)
- }
- sort.Strings(arr)
- // Log all complex types for manual inspection.
- t.Log("complex types:\n" + strings.Join(arr, "\n"))
- if testing.Short() || testutil.RaceEnabled {
- return
- }
- // Compare with what we can generate at runtime.
- // We cannot guarantee that we will generate 100% of complex types
- // (some are no_generate, and the process is random), but we should
- // generate at least 90% or there is something wrong.
- ct := target.DefaultChoiceTable()
- r := newRand(target, rs)
- generatedComplex := make(map[string]bool)
- for _, meta := range target.Syscalls {
- if meta.Attrs.Disabled || meta.Attrs.NoGenerate {
- continue
+ sort.Strings(arr)
+ // Log all complex types for manual inspection.
+ t.Log("complex types:\n" + strings.Join(arr, "\n"))
+ if testing.Short() || testutil.RaceEnabled {
+ return
}
- for i := 0; i < 10; i++ {
- s := newState(target, ct, nil)
- calls := r.generateParticularCall(s, meta)
- p := &Prog{Target: target, Calls: calls}
- for _, arg := range p.complexPtrs() {
- generatedComplex[arg.arg.Res.Type().String()] = true
+ // Compare with what we can generate at runtime.
+ // We cannot guarantee that we will generate 100% of complex types
+ // (some are no_generate, and the process is random), but we should
+ // generate at least 90% or there is something wrong.
+ ct := target.DefaultChoiceTable()
+ r := newRand(target, rs)
+ generatedComplex := make(map[string]bool)
+ for _, meta := range target.Syscalls {
+ if meta.Attrs.Disabled || meta.Attrs.NoGenerate {
+ continue
+ }
+ for i := 0; i < 10; i++ {
+ s := newState(target, ct, nil)
+ calls := r.generateParticularCall(s, meta)
+ p := &Prog{Target: target, Calls: calls}
+ for _, arg := range p.complexPtrs() {
+ generatedComplex[arg.arg.Res.Type().String()] = true
+ }
}
}
- }
- for id := range generatedComplex {
- if !allComplex[id] {
- t.Errorf("generated complex %v that is not statically complex", id)
+ for id := range generatedComplex {
+ if !allComplex[id] {
+ t.Errorf("generated complex %v that is not statically complex", id)
+ }
}
- }
- for id := range allComplex {
- if !generatedComplex[id] {
- t.Logf("did not generate %v", id)
+ for id := range allComplex {
+ if !generatedComplex[id] {
+ t.Logf("did not generate %v", id)
+ }
}
- }
- if len(generatedComplex) < len(allComplex)*9/10 {
- t.Errorf("generated too few complex types: %v/%v", len(generatedComplex), len(allComplex))
- }
+ if len(generatedComplex) < len(allComplex)*9/10 {
+ t.Errorf("generated too few complex types: %v/%v", len(generatedComplex), len(allComplex))
+ }
+ })
}
func TestSquash(t *testing.T) {