aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2023-05-03 17:17:58 +0200
committerAleksandr Nogikh <wp32pw@gmail.com>2023-05-04 12:34:39 +0200
commit8e1412d59319a19d61ea48985b13ef550e3ab9ec (patch)
tree898f98fe6393d9e33ce9b3cec04e9b42e05a273b
parent44cadb8c63089bc856779dc81dc1b3df8de361ed (diff)
pkg/csource: compile single pseudo syscalls
There seem to be a lot of unclear dependencies between pseudo syscall code and global methods. By testing them only together we have little chance to detect these problems because implementations can indiretly help one another. In addition to existing tests, also compile all pseudo syscalls independently.
-rw-r--r--pkg/csource/csource_test.go17
-rw-r--r--prog/rand.go36
2 files changed, 48 insertions, 5 deletions
diff --git a/pkg/csource/csource_test.go b/pkg/csource/csource_test.go
index 3e2c75a23..2eb8cd150 100644
--- a/pkg/csource/csource_test.go
+++ b/pkg/csource/csource_test.go
@@ -53,6 +53,23 @@ func TestGenerate(t *testing.T) {
checked[target.OS] = true
t.Parallel()
testTarget(t, target, full)
+ testPseudoSyscalls(t, target)
+ })
+ }
+}
+
+func testPseudoSyscalls(t *testing.T, target *prog.Target) {
+ // Use options that are as minimal as possible.
+ // We want to ensure that the code can always be compiled.
+ opts := Options{
+ Slowdown: 1,
+ }
+ rs := testutil.RandSource(t)
+ for _, meta := range target.PseudoSyscalls() {
+ p := target.GenSampleProg(meta, rs)
+ t.Run(fmt.Sprintf("single_%s", meta.CallName), func(t *testing.T) {
+ t.Parallel()
+ testOne(t, p, opts)
})
}
}
diff --git a/prog/rand.go b/prog/rand.go
index c91ffeee4..560e1e176 100644
--- a/prog/rand.go
+++ b/prog/rand.go
@@ -593,7 +593,23 @@ func (target *Target) GenerateAllSyzProg(rs rand.Source) *Prog {
}
r := newRand(target, rs)
s := newState(target, target.DefaultChoiceTable(), nil)
+ for _, meta := range target.PseudoSyscalls() {
+ calls := r.generateParticularCall(s, meta)
+ for _, c := range calls {
+ s.analyze(c)
+ p.Calls = append(p.Calls, c)
+ }
+ }
+ if err := p.validate(); err != nil {
+ panic(err)
+ }
+ return p
+}
+
+// PseudoSyscalls selects one *Syscall for each pseudosyscall.
+func (target *Target) PseudoSyscalls() []*Syscall {
handled := make(map[string]bool)
+ var ret []*Syscall
for _, meta := range target.Syscalls {
if !strings.HasPrefix(meta.CallName, "syz_") ||
handled[meta.CallName] ||
@@ -601,12 +617,22 @@ func (target *Target) GenerateAllSyzProg(rs rand.Source) *Prog {
meta.Attrs.NoGenerate {
continue
}
+ ret = append(ret, meta)
handled[meta.CallName] = true
- calls := r.generateParticularCall(s, meta)
- for _, c := range calls {
- s.analyze(c)
- p.Calls = append(p.Calls, c)
- }
+ }
+ return ret
+}
+
+// GenSampleProg generates a single sample program for the call.
+func (target *Target) GenSampleProg(meta *Syscall, rs rand.Source) *Prog {
+ r := newRand(target, rs)
+ s := newState(target, target.DefaultChoiceTable(), nil)
+ p := &Prog{
+ Target: target,
+ }
+ for _, c := range r.generateParticularCall(s, meta) {
+ s.analyze(c)
+ p.Calls = append(p.Calls, c)
}
if err := p.validate(); err != nil {
panic(err)