aboutsummaryrefslogtreecommitdiffstats
path: root/prog/rand.go
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2023-12-28 21:31:00 +0100
committerAleksandr Nogikh <nogikh@google.com>2024-02-19 11:54:01 +0000
commit31179bc75602cbe8f0421b44f19ff1b960039644 (patch)
tree9804abe8e2ca0218da0e2c71b61a8b411f26e800 /prog/rand.go
parented571339c6ff5ed764283737a0aa68451085e84d (diff)
prog: support conditional fields
pkg/compiler restructures conditional fields in structures into unions, so we only have to implement the support for unions. Semantics is as follows: If a union has conditions, syzkaller picks the first field whose condition matches. Since we require the last union field to have no conditions, we can always construct an object. Changes from this commit aim at ensuring that the selected union fields always follow the rule above.
Diffstat (limited to 'prog/rand.go')
-rw-r--r--prog/rand.go9
1 files changed, 8 insertions, 1 deletions
diff --git a/prog/rand.go b/prog/rand.go
index c7f9053aa..742dbaa7c 100644
--- a/prog/rand.go
+++ b/prog/rand.go
@@ -27,6 +27,7 @@ type randGen struct {
*rand.Rand
target *Target
inGenerateResource bool
+ inPatchConditional bool
recDepth map[string]int
}
@@ -598,8 +599,9 @@ func (r *randGen) generateParticularCall(s *state, meta *Syscall) (calls []*Call
}
c := MakeCall(meta, nil)
c.Args, calls = r.generateArgs(s, meta.Args, DirIn)
+ moreCalls, _ := r.patchConditionalFields(c, s)
r.target.assignSizesCall(c)
- return append(calls, c)
+ return append(append(calls, moreCalls...), c)
}
// GenerateAllSyzProg generates a program that contains all pseudo syz_ calls for testing.
@@ -881,6 +883,11 @@ func (a *StructType) generate(r *randGen, s *state, dir Dir) (arg Arg, calls []*
}
func (a *UnionType) generate(r *randGen, s *state, dir Dir) (arg Arg, calls []*Call) {
+ if a.isConditional() {
+ // Conditions may reference other fields that may not have already
+ // been generated. We'll fill them in later.
+ return a.DefaultArg(dir), nil
+ }
index := r.Intn(len(a.Fields))
optType, optDir := a.Fields[index].Type, a.Fields[index].Dir(dir)
opt, calls := r.generateArg(s, optType, optDir)