aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMara Mihali <maramihali@google.com>2021-07-07 16:51:39 +0000
committerMarco Elver <me@marcoelver.com>2021-07-08 10:00:58 +0200
commit1b20171a857edaeb6232e42ae1e0b783d4c5f666 (patch)
tree539072b62129cc09f964f34ea64adcfae606ab9f
parent1aade7546f2c85b87c16978919f101686593c956 (diff)
syz-verifier: improve readability of results
-rwxr-xr-xsyz-verifier/main.go33
-rw-r--r--syz-verifier/main_test.go38
-rw-r--r--syz-verifier/verf/verifier.go5
-rw-r--r--syz-verifier/verf/verifier_test.go6
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},
},
},
},