diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2021-09-23 16:15:41 +0000 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2021-12-10 12:30:07 +0100 |
| commit | fd8caa5462e64f37cb9eebd75ffca1737dde447d (patch) | |
| tree | bfa900ebf41099b21476e72acdf063ee630178c9 /prog/collide_test.go | |
| parent | 4d4ce9bc2a12073dcc8b917f9fc2a4ecba26c4c5 (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.go | 84 |
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") + } +} |
