diff options
| author | Mara Mihali <maramihali@google.com> | 2021-06-23 16:24:21 +0000 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2021-06-30 09:35:14 +0200 |
| commit | f96cd674af0bf3997d17277fa0a028bede05ca54 (patch) | |
| tree | d7ecbf345d41d7854ed44dba712adf2f09a29b89 | |
| parent | bf86d29b9edb7e1346978c74ea837b5ec3683b2d (diff) | |
syz-verifier/verf: add the first version of the Verifier
This checks whether the errno returned by a program's system call executed by different Runners are the same.
| -rw-r--r-- | syz-verifier/verf/verifier.go | 45 | ||||
| -rw-r--r-- | syz-verifier/verf/verifier_test.go | 86 |
2 files changed, 131 insertions, 0 deletions
diff --git a/syz-verifier/verf/verifier.go b/syz-verifier/verf/verifier.go new file mode 100644 index 000000000..2678af23b --- /dev/null +++ b/syz-verifier/verf/verifier.go @@ -0,0 +1,45 @@ +// 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 verf contains utilities for verifying the execution of the same +// program on different kernels yield the same results. +package verf + +import ( + "github.com/google/syzkaller/pkg/ipc" + "github.com/google/syzkaller/prog" +) + +// Result stores the results of executing a program. +type Result struct { + // Pool is the index of the pool. + Pool int + // Hanged is set to true when a program was killed due to hanging. + Hanged bool + // Info contains information about the execution of each system call + // in the generated programs. + Info ipc.ProgInfo +} + +// Verify checks whether the Results of the same program, executed on different +// kernels are the same. If that's the case, it returns true, otherwise it +// returns false. +func Verify(res []*Result, prog *prog.Prog) bool { + for i := 1; i < len(res); i++ { + if !VerifyErrnos(res[0].Info.Calls, res[i].Info.Calls) { + return false + } + } + return true +} + +// VerifyErrnos checks whether the returned system call errnos of the same +// program, executed on two different kernels, are the same. +func VerifyErrnos(c1, c2 []ipc.CallInfo) bool { + for idx, c := range c1 { + if c.Errno != c2[idx].Errno { + return false + } + } + return true +} diff --git a/syz-verifier/verf/verifier_test.go b/syz-verifier/verf/verifier_test.go new file mode 100644 index 000000000..c9a25acb5 --- /dev/null +++ b/syz-verifier/verf/verifier_test.go @@ -0,0 +1,86 @@ +// 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 verf + +import ( + "testing" + + "github.com/google/syzkaller/pkg/ipc" +) + +func TestVerify(t *testing.T) { + tests := []struct { + name string + res []*Result + wantMatch bool + }{ + { + + name: "results should match", + res: []*Result{ + {2, false, ipc.ProgInfo{ + Calls: []ipc.CallInfo{{Errno: 1}, {Errno: 2}, {Errno: 3}}, Extra: ipc.CallInfo{}, + }, + }, + {4, false, ipc.ProgInfo{ + Calls: []ipc.CallInfo{{Errno: 1}, {Errno: 2}, {Errno: 3}}, + Extra: ipc.CallInfo{}, + }, + }, + }, + + wantMatch: true, + }, + { + name: "results should not match", + res: []*Result{ + {4, false, ipc.ProgInfo{ + Calls: []ipc.CallInfo{{Errno: 1}, {Errno: 2}, {Errno: 5}}, + }, + }, + {8, false, ipc.ProgInfo{ + Calls: []ipc.CallInfo{{Errno: 1}, {Errno: 3}, {Errno: 5}}, + }, + }, + }, + wantMatch: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got, want := Verify(test.res, nil), test.wantMatch; got != want { + t.Errorf("Verify: got %v, want %v", got, want) + } + }) + } +} + +func TestVerifyErrno(t *testing.T) { + tests := []struct { + name string + c1, c2 []ipc.CallInfo + wantMatch bool + }{ + { + name: "errno should match", + c1: []ipc.CallInfo{{Errno: 1}, {Errno: 2}, {Errno: 5}}, + c2: []ipc.CallInfo{{Errno: 1}, {Errno: 2}, {Errno: 5}}, + wantMatch: true, + }, + { + name: "errno should not match", + c1: []ipc.CallInfo{{Errno: 1}, {Errno: 2}, {Errno: 5}}, + c2: []ipc.CallInfo{{Errno: 1}, {Errno: 4}, {Errno: 5}}, + wantMatch: false, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got, want := VerifyErrnos(test.c1, test.c2), test.wantMatch; got != want { + t.Errorf("VerifyErrno: got %v, want %v", got, want) + } + }) + } +} |
