diff options
| author | Mara Mihali <maramihali@google.com> | 2021-07-07 16:51:39 +0000 |
|---|---|---|
| committer | Marco Elver <me@marcoelver.com> | 2021-07-08 10:00:58 +0200 |
| commit | 1b20171a857edaeb6232e42ae1e0b783d4c5f666 (patch) | |
| tree | 539072b62129cc09f964f34ea64adcfae606ab9f | |
| parent | 1aade7546f2c85b87c16978919f101686593c956 (diff) | |
syz-verifier: improve readability of results
| -rwxr-xr-x | syz-verifier/main.go | 33 | ||||
| -rw-r--r-- | syz-verifier/main_test.go | 38 | ||||
| -rw-r--r-- | syz-verifier/verf/verifier.go | 5 | ||||
| -rw-r--r-- | syz-verifier/verf/verifier_test.go | 6 |
4 files changed, 57 insertions, 25 deletions
diff --git a/syz-verifier/main.go b/syz-verifier/main.go index 65a7a5cdd..b277d3176 100755 --- a/syz-verifier/main.go +++ b/syz-verifier/main.go @@ -11,6 +11,7 @@ import ( "os" "path/filepath" "strconv" + "strings" "sync" "time" @@ -312,7 +313,8 @@ func (vrf *Verifier) processResults(res []*verf.Result, prog *prog.Prog) { } } - err := osutil.WriteFile(filepath.Join(vrf.resultsdir, fmt.Sprintf("result-%d", oldest)), createReport(rr)) + err := osutil.WriteFile(filepath.Join(vrf.resultsdir, + fmt.Sprintf("result-%d", oldest)), createReport(rr, len(vrf.pools))) if err != nil { log.Printf("failed to write result-%d file, err %v", oldest, err) } @@ -320,20 +322,29 @@ func (vrf *Verifier) processResults(res []*verf.Result, prog *prog.Prog) { log.Printf("result-%d written successfully", oldest) } -func createReport(rr *verf.ResultReport) []byte { - data := fmt.Sprintf("Errno mismatches found for program:\n%s\n", rr.Prog) - data += "CALL REPORTS FOUND BELOW\n" - - for _, cr := range rr.Reports { - data += fmt.Sprintf("Report for call: %s", cr.Call) +func createReport(rr *verf.ResultReport, pools int) []byte { + calls := strings.Split(rr.Prog, "\n") + calls = calls[:len(calls)-1] + data := "ERRNO mismatches found for program:\n\n" + for idx, cr := range rr.Reports { + tick := "[=]" if cr.Mismatch { - data += " - MISMATCH FOUND" + tick = "[!]" } - data += "\n" - for pool, errno := range cr.Errnos { - data += fmt.Sprintf("Pool: %d, Errno: %d, Flag: %d\n", pool, errno, cr.Flags[pool]) + data += fmt.Sprintf("%s %s\n", tick, calls[idx]) + + // Ensure results are ordered by pool index. + for i := 0; i < pools; i++ { + errno, ok := cr.Errnos[i] + if !ok { + // VM crashed so we don't have reports from this pool. + continue + } + + data += fmt.Sprintf("\t↳ Pool: %d, Errno: %d, Flag: %d\n", i, errno, cr.Flags[i]) } + data += "\n" } diff --git a/syz-verifier/main_test.go b/syz-verifier/main_test.go index d17e56a40..7fde58ea1 100644 --- a/syz-verifier/main_test.go +++ b/syz-verifier/main_test.go @@ -3,7 +3,6 @@ package main import ( - "log" "math/rand" "os" "path/filepath" @@ -170,11 +169,10 @@ func TestProcessResults(t *testing.T) { "minimize$0(0x1, 0x1)\n" + "test$res0()\n" tests := []struct { - name string - res []*verf.Result - prog string - wantExist bool - wantResIdx int + name string + res []*verf.Result + prog string + wantExist bool }{ { name: "report written", @@ -215,10 +213,36 @@ func TestProcessResults(t *testing.T) { vrf.processResults(test.res, prog) if got, want := osutil.IsExist(resultFile), test.wantExist; got != want { - log.Printf("%v", test.wantExist) t.Errorf("osutil.IsExist report file: got %v want %v", got, want) } os.Remove(filepath.Join(vrf.resultsdir, "result-3")) }) } } + +func TestCreateReport(t *testing.T) { + rr := verf.ResultReport{ + Prog: "breaks_returns()\n" + + "minimize$0(0x1, 0x1)\n" + + "test$res0()\n", + Reports: []verf.CallReport{ + {Errnos: map[int]int{1: 1, 2: 1, 3: 1}, Flags: map[int]ipc.CallFlags{1: 1, 2: 1, 3: 1}}, + {Errnos: map[int]int{1: 3, 2: 3, 3: 3}, Flags: map[int]ipc.CallFlags{1: 3, 2: 3, 3: 3}}, + {Errnos: map[int]int{1: 2, 2: 5, 3: 22}, Flags: map[int]ipc.CallFlags{1: 7, 2: 3, 3: 1}, Mismatch: true}, + }, + } + got := string(createReport(&rr, 3)) + want := "ERRNO mismatches found for program:\n\n" + + "[=] breaks_returns()\n" + + "\t↳ Pool: 1, Errno: 1, Flag: 1\n" + + "\t↳ Pool: 2, Errno: 1, Flag: 1\n\n" + + "[=] minimize$0(0x1, 0x1)\n" + + "\t↳ Pool: 1, Errno: 3, Flag: 3\n" + + "\t↳ Pool: 2, Errno: 3, Flag: 3\n\n" + + "[!] test$res0()\n" + + "\t↳ Pool: 1, Errno: 2, Flag: 7\n" + + "\t↳ Pool: 2, Errno: 5, Flag: 3\n\n" + if got != want { + t.Errorf("createReport: got %q want %q", got, want) + } +} diff --git a/syz-verifier/verf/verifier.go b/syz-verifier/verf/verifier.go index 3911d3229..3545ee8dd 100644 --- a/syz-verifier/verf/verifier.go +++ b/syz-verifier/verf/verifier.go @@ -29,8 +29,6 @@ type ResultReport struct { } type CallReport struct { - // Call is the name of the system call. - Call string // Errno is a map between pools and the errno returned by executing the // system call on a VM spawned by the respective pool. Errnos map[int]int @@ -48,9 +46,8 @@ func Verify(res []*Result, prog *prog.Prog) *ResultReport { Prog: string(prog.Serialize()), } c0 := res[0].Info.Calls - for idx, c := range c0 { + for _, c := range c0 { cr := CallReport{ - Call: prog.Calls[idx].Meta.Name, Errnos: map[int]int{res[0].Pool: c.Errno}, Flags: map[int]ipc.CallFlags{res[0].Pool: c.Flags}, } diff --git a/syz-verifier/verf/verifier_test.go b/syz-verifier/verf/verifier_test.go index afe2d2076..b32b65f1d 100644 --- a/syz-verifier/verf/verifier_test.go +++ b/syz-verifier/verf/verifier_test.go @@ -43,9 +43,9 @@ func TestVerify(t *testing.T) { want: &ResultReport{ Prog: p, Reports: []CallReport{ - {Call: "breaks_returns", Errnos: map[int]int{1: 1, 4: 1}, Flags: map[int]ipc.CallFlags{1: 1, 4: 1}}, - {Call: "minimize$0", Errnos: map[int]int{1: 3, 4: 3}, Flags: map[int]ipc.CallFlags{1: 3, 4: 3}}, - {Call: "test$res0", Errnos: map[int]int{1: 2, 4: 5}, Flags: map[int]ipc.CallFlags{1: 7, 4: 3}, Mismatch: true}, + {Errnos: map[int]int{1: 1, 4: 1}, Flags: map[int]ipc.CallFlags{1: 1, 4: 1}}, + {Errnos: map[int]int{1: 3, 4: 3}, Flags: map[int]ipc.CallFlags{1: 3, 4: 3}}, + {Errnos: map[int]int{1: 2, 4: 5}, Flags: map[int]ipc.CallFlags{1: 7, 4: 3}, Mismatch: true}, }, }, }, |
