syz-manager: implement fallback coverage report

This commit is contained in:
Dmitry Vyukov 2018-06-29 18:15:41 +02:00
parent b6b4ddad63
commit 0a971ab1d0
3 changed files with 90 additions and 1 deletions
pkg
syz-manager

@ -19,6 +19,7 @@ import (
"unsafe"
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/pkg/signal"
"github.com/google/syzkaller/prog"
"github.com/google/syzkaller/sys/targets"
)
@ -333,7 +334,7 @@ func addFallbackSignal(p *prog.Prog, info []CallInfo) {
if !inf.Executed || len(inf.Signal) != 0 {
continue
}
inf.Signal = []uint32{uint32(call.Meta.ID)<<16 | uint32(inf.Errno)&0x3ff}
inf.Signal = []uint32{signal.EncodeFallback(call.Meta.ID, inf.Errno)}
}
}

@ -191,3 +191,11 @@ func Minimize(corpus []Context) []interface{} {
}
return result
}
func EncodeFallback(id, errno int) uint32 {
return uint32(id)<<16 | uint32(errno)&0x3ff
}
func DecodeFallback(s uint32) (int, int) {
return int(s >> 16), int(s & 0x3ff)
}

@ -23,6 +23,7 @@ import (
"github.com/google/syzkaller/pkg/cover"
"github.com/google/syzkaller/pkg/log"
"github.com/google/syzkaller/pkg/osutil"
"github.com/google/syzkaller/pkg/signal"
)
const dateFormat = "Jan 02 2006 15:04:05 MST"
@ -202,6 +203,14 @@ func (mgr *Manager) httpCover(w http.ResponseWriter, r *http.Request) {
mgr.mu.Lock()
defer mgr.mu.Unlock()
if mgr.cfg.Cover {
mgr.httpCoverCover(w, r)
} else {
mgr.httpCoverFallback(w, r)
}
}
func (mgr *Manager) httpCoverCover(w http.ResponseWriter, r *http.Request) {
if mgr.cfg.KernelObj == "" {
http.Error(w, fmt.Sprintf("no kernel_obj in config file"), http.StatusInternalServerError)
return
@ -225,6 +234,40 @@ func (mgr *Manager) httpCover(w http.ResponseWriter, r *http.Request) {
runtime.GC()
}
func (mgr *Manager) httpCoverFallback(w http.ResponseWriter, r *http.Request) {
calls := make(map[int][]int)
for s, _ := range mgr.maxSignal {
id, errno := signal.DecodeFallback(uint32(s))
calls[id] = append(calls[id], errno)
}
data := &UIFallbackCoverData{}
for id, errnos := range calls {
if id < 0 || id >= len(mgr.target.Syscalls) {
http.Error(w, fmt.Sprintf("bad call ID %v", id), http.StatusInternalServerError)
return
}
sort.Ints(errnos)
ok := false
if errnos[0] == 0 {
ok = true
errnos = errnos[1:]
}
data.Calls = append(data.Calls, UIFallbackCall{
Name: mgr.target.Syscalls[id].Name,
Errnos: errnos,
OK: ok,
})
}
sort.Slice(data.Calls, func(i, j int) bool {
return data.Calls[i].Name < data.Calls[j].Name
})
if err := fallbackCoverTemplate.Execute(w, data); err != nil {
http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError)
return
}
}
func (mgr *Manager) httpPrio(w http.ResponseWriter, r *http.Request) {
mgr.mu.Lock()
defer mgr.mu.Unlock()
@ -713,6 +756,43 @@ Priorities for {{$.Call}} <br> <br>
</body></html>
`)))
type UIFallbackCoverData struct {
Calls []UIFallbackCall
}
type UIFallbackCall struct {
Name string
OK bool
Errnos []int
}
var fallbackCoverTemplate = template.Must(template.New("").Parse(addStyle(`
<!doctype html>
<html>
<head>
<title>syzkaller coverage</title>
{{STYLE}}
</head>
<body>
<table>
<tr>
<th>Call</th>
<th>Succeeded</th>
<th>Errnos</th>
</tr>
{{range $c := $.Calls}}
<tr>
<td>{{$c.Name}}</td>
<td>{{if $c.OK}}YES{{end}}</td>
<td>
{{range $e := $c.Errnos}}{{$e}}&nbsp;{{end}}
</td>
</tr>
{{end}}
</table>
</body></html>
`)))
func addStyle(html string) string {
return strings.Replace(html, "{{STYLE}}", htmlStyle, -1)
}