aboutsummaryrefslogtreecommitdiffstats
path: root/prog/collide_test.go
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2021-09-23 16:15:41 +0000
committerAleksandr Nogikh <wp32pw@gmail.com>2021-12-10 12:30:07 +0100
commitfd8caa5462e64f37cb9eebd75ffca1737dde447d (patch)
treebfa900ebf41099b21476e72acdf063ee630178c9 /prog/collide_test.go
parent4d4ce9bc2a12073dcc8b917f9fc2a4ecba26c4c5 (diff)
all: replace collide mode by `async` call property
Replace the currently existing straightforward approach to race triggering (that was almost entirely implemented inside syz-executor) with a more flexible one. The `async` call property instructs syz-executor not to block until the call has completed execution and proceed immediately to the next call. The decision on what calls to mark with `async` is made by syz-fuzzer. Ultimately this should let us implement more intelligent race provoking strategies as well as make more fine-grained reproducers.
Diffstat (limited to 'prog/collide_test.go')
-rw-r--r--prog/collide_test.go84
1 files changed, 84 insertions, 0 deletions
diff --git a/prog/collide_test.go b/prog/collide_test.go
new file mode 100644
index 000000000..614b677ef
--- /dev/null
+++ b/prog/collide_test.go
@@ -0,0 +1,84 @@
+// Copyright 2021 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 (
+ "math/rand"
+ "testing"
+)
+
+func TestAssignRandomAsync(t *testing.T) {
+ tests := []struct {
+ os string
+ arch string
+ orig string
+ check func(*Prog) bool
+ }{
+ {
+ "linux", "amd64",
+ `r0 = openat(0xffffffffffffff9c, &AUTO='./file1\x00', 0x42, 0x1ff)
+write(r0, &AUTO="01010101", 0x4)
+read(r0, &AUTO=""/4, 0x4)
+close(r0)
+`,
+ func(p *Prog) bool {
+ return !p.Calls[0].Props.Async
+ },
+ },
+ {
+ "linux", "amd64",
+ `r0 = openat(0xffffffffffffff9c, &AUTO='./file1\x00', 0x42, 0x1ff)
+nanosleep(&AUTO={0x0,0x4C4B40}, &AUTO={0,0})
+write(r0, &AUTO="01010101", 0x4)
+read(r0, &AUTO=""/4, 0x4)
+close(r0)
+`,
+ func(p *Prog) bool {
+ return !p.Calls[0].Props.Async || !p.Calls[1].Props.Async
+ },
+ },
+ {
+ "linux", "amd64",
+ `r0 = openat(0xffffffffffffff9c, &AUTO='./file1\x00', 0x42, 0x1ff)
+r1 = dup(r0)
+r2 = dup(r1)
+r3 = dup(r2)
+r4 = dup(r3)
+`,
+ func(p *Prog) bool {
+ for _, call := range p.Calls[0 : len(p.Calls)-1] {
+ if call.Props.Async {
+ return false
+ }
+ }
+ return true
+ },
+ },
+ }
+ _, rs, iters := initTest(t)
+ r := rand.New(rs)
+ anyAsync := false
+ for _, test := range tests {
+ target, err := GetTarget(test.os, test.arch)
+ if err != nil {
+ t.Fatal(err)
+ }
+ p, err := target.Deserialize([]byte(test.orig), Strict)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for i := 0; i < iters; i++ {
+ collided := AssignRandomAsync(p, r)
+ if !test.check(collided) {
+ t.Fatalf("bad async assignment:\n%s\n", collided.Serialize())
+ }
+ for _, call := range collided.Calls {
+ anyAsync = anyAsync || call.Props.Async
+ }
+ }
+ }
+ if !anyAsync {
+ t.Fatalf("not a single async was assigned")
+ }
+}