mirror of
https://github.com/reactos/syzkaller.git
synced 2025-02-12 23:22:31 +00:00
8af91f61b4
Currently hub allows managers to exchange programs from corpus. But reproducers are not exchanged and we don't know if a crash happens on other managers as well or not. Allow hub to exchange reproducers. Reproducers are stored in a separate db file with own sequence numbers. This allows to throttle distribution of reproducers to managers, so that they are not overloaded with reproducers and don't lose them on restarts. Based on patch by Andrey Konovalov: https://github.com/google/syzkaller/pull/325 Fixes #282
167 lines
3.4 KiB
Go
167 lines
3.4 KiB
Go
// Copyright 2016 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 main
|
|
|
|
import (
|
|
"fmt"
|
|
"html/template"
|
|
"net"
|
|
"net/http"
|
|
"sort"
|
|
"strings"
|
|
|
|
. "github.com/google/syzkaller/pkg/log"
|
|
)
|
|
|
|
func (hub *Hub) initHttp(addr string) {
|
|
http.HandleFunc("/", hub.httpSummary)
|
|
|
|
ln, err := net.Listen("tcp4", addr)
|
|
if err != nil {
|
|
Fatalf("failed to listen on %v: %v", addr, err)
|
|
}
|
|
Logf(0, "serving http on http://%v", ln.Addr())
|
|
go func() {
|
|
err := http.Serve(ln, nil)
|
|
Fatalf("failed to serve http: %v", err)
|
|
}()
|
|
}
|
|
|
|
func (hub *Hub) httpSummary(w http.ResponseWriter, r *http.Request) {
|
|
hub.mu.Lock()
|
|
defer hub.mu.Unlock()
|
|
|
|
data := &UISummaryData{
|
|
Log: CachedLogOutput(),
|
|
}
|
|
total := UIManager{
|
|
Name: "total",
|
|
Corpus: len(hub.st.Corpus.Records),
|
|
Repros: len(hub.st.Repros.Records),
|
|
}
|
|
for name, mgr := range hub.st.Managers {
|
|
total.Added += mgr.Added
|
|
total.Deleted += mgr.Deleted
|
|
total.New += mgr.New
|
|
total.SentRepros += mgr.SentRepros
|
|
total.RecvRepros += mgr.RecvRepros
|
|
data.Managers = append(data.Managers, UIManager{
|
|
Name: name,
|
|
Corpus: len(mgr.Corpus.Records),
|
|
Added: mgr.Added,
|
|
Deleted: mgr.Deleted,
|
|
New: mgr.New,
|
|
SentRepros: mgr.SentRepros,
|
|
RecvRepros: mgr.RecvRepros,
|
|
})
|
|
}
|
|
sort.Sort(UIManagerArray(data.Managers))
|
|
data.Managers = append([]UIManager{total}, data.Managers...)
|
|
if err := summaryTemplate.Execute(w, data); err != nil {
|
|
Logf(0, "failed to execute template: %v", err)
|
|
http.Error(w, fmt.Sprintf("failed to execute template: %v", err), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
}
|
|
|
|
func compileTemplate(html string) *template.Template {
|
|
return template.Must(template.New("").Parse(strings.Replace(html, "{{STYLE}}", htmlStyle, -1)))
|
|
}
|
|
|
|
type UISummaryData struct {
|
|
Managers []UIManager
|
|
Log string
|
|
}
|
|
|
|
type UIManager struct {
|
|
Name string
|
|
Corpus int
|
|
Added int
|
|
Deleted int
|
|
New int
|
|
Repros int
|
|
SentRepros int
|
|
RecvRepros int
|
|
}
|
|
|
|
type UIManagerArray []UIManager
|
|
|
|
func (a UIManagerArray) Len() int { return len(a) }
|
|
func (a UIManagerArray) Less(i, j int) bool { return a[i].Name < a[j].Name }
|
|
func (a UIManagerArray) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
|
|
|
|
var summaryTemplate = compileTemplate(`
|
|
<!doctype html>
|
|
<html>
|
|
<head>
|
|
<title>syz-hub</title>
|
|
{{STYLE}}
|
|
</head>
|
|
<body>
|
|
<b>syz-hub</b>
|
|
<br><br>
|
|
|
|
<table>
|
|
<caption>Managers:</caption>
|
|
<tr>
|
|
<th>Name</th>
|
|
<th>Corpus</th>
|
|
<th>Added</th>
|
|
<th>Deleted</th>
|
|
<th>New</th>
|
|
<th>Repros</th>
|
|
<th>Sent</th>
|
|
<th>Recv</th>
|
|
</tr>
|
|
{{range $m := $.Managers}}
|
|
<tr>
|
|
<td>{{$m.Name}}</td>
|
|
<td>{{$m.Corpus}}</td>
|
|
<td>{{$m.Added}}</td>
|
|
<td>{{$m.Deleted}}</td>
|
|
<td>{{$m.New}}</td>
|
|
<td>{{$m.Repros}}</td>
|
|
<td>{{$m.SentRepros}}</td>
|
|
<td>{{$m.RecvRepros}}</td>
|
|
</tr>
|
|
{{end}}
|
|
</table>
|
|
<br><br>
|
|
|
|
Log:
|
|
<br>
|
|
<textarea id="log_textarea" readonly rows="50">
|
|
{{.Log}}
|
|
</textarea>
|
|
<script>
|
|
var textarea = document.getElementById("log_textarea");
|
|
textarea.scrollTop = textarea.scrollHeight;
|
|
</script>
|
|
|
|
</body></html>
|
|
`)
|
|
|
|
const htmlStyle = `
|
|
<style type="text/css" media="screen">
|
|
table {
|
|
border-collapse:collapse;
|
|
border:1px solid;
|
|
}
|
|
table caption {
|
|
font-weight: bold;
|
|
}
|
|
table td {
|
|
border:1px solid;
|
|
padding: 3px;
|
|
}
|
|
table th {
|
|
border:1px solid;
|
|
padding: 3px;
|
|
}
|
|
textarea {
|
|
width:100%;
|
|
}
|
|
</style>
|
|
`
|