aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/manager/http.go
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2024-10-20 22:55:31 +0200
committerTaras Madan <tarasmadan@google.com>2024-10-25 12:08:02 +0000
commitf63b8696b67a1c47ecd4fced47215acd6805a14a (patch)
treec7d5795c124fdc9a99b309db8ed75f56b2c6ffe9 /pkg/manager/http.go
parentc0390c277e5fcda8d7288b717ff952e01dcdcb8d (diff)
tools: add a syz-diff tool
This is the prototype version of the patch series fuzzing functionality based on the syzkaller fuzzing engine. The tool takes two syzkaller configs -- one for the base kernel, one for the patched kernel. Optionally the patch itself can be also provided. syz-diff will consider a bug patched-only if: 1) It happened while fuzzing the patched kernel. 2) It was never observed on the base kernel. 3) The tool found a repro on the patched kernel. 4) The repro did not crash the base kernel.
Diffstat (limited to 'pkg/manager/http.go')
-rw-r--r--pkg/manager/http.go144
1 files changed, 134 insertions, 10 deletions
diff --git a/pkg/manager/http.go b/pkg/manager/http.go
index 155765534..c94ce727f 100644
--- a/pkg/manager/http.go
+++ b/pkg/manager/http.go
@@ -51,6 +51,7 @@ type HTTPServer struct {
StartTime time.Time
Corpus *corpus.Corpus
CrashStore *CrashStore
+ DiffStore *DiffFuzzerStore
// Set dynamically.
Fuzzer atomic.Pointer[fuzzer.Fuzzer]
@@ -77,13 +78,15 @@ func (serv *HTTPServer) Serve() {
handle("/syscalls", serv.httpSyscalls)
handle("/corpus", serv.httpCorpus)
handle("/corpus.db", serv.httpDownloadCorpus)
- handle("/crash", serv.httpCrash)
+ if serv.CrashStore != nil {
+ handle("/crash", serv.httpCrash)
+ handle("/report", serv.httpReport)
+ }
handle("/cover", serv.httpCover)
handle("/subsystemcover", serv.httpSubsystemCover)
handle("/modulecover", serv.httpModuleCover)
handle("/prio", serv.httpPrio)
handle("/file", serv.httpFile)
- handle("/report", serv.httpReport)
handle("/rawcover", serv.httpRawCover)
handle("/rawcoverfiles", serv.httpRawCoverFiles)
handle("/filterpcs", serv.httpFilterPCs)
@@ -125,11 +128,15 @@ func (serv *HTTPServer) httpSummary(w http.ResponseWriter, r *http.Request) {
Link: stat.Link,
})
}
-
- var err error
- if data.Crashes, err = serv.collectCrashes(serv.Cfg.Workdir); err != nil {
- http.Error(w, fmt.Sprintf("failed to collect crashes: %v", err), http.StatusInternalServerError)
- return
+ if serv.CrashStore != nil {
+ var err error
+ if data.Crashes, err = serv.collectCrashes(serv.Cfg.Workdir); err != nil {
+ http.Error(w, fmt.Sprintf("failed to collect crashes: %v", err), http.StatusInternalServerError)
+ return
+ }
+ }
+ if serv.DiffStore != nil {
+ data.PatchedOnly, data.AffectsBoth, data.InProgress = serv.collectDiffCrashes()
}
executeTemplate(w, summaryTemplate, data)
}
@@ -695,15 +702,61 @@ func (serv *HTTPServer) httpFilterPCs(w http.ResponseWriter, r *http.Request) {
serv.httpCoverCover(w, r, DoFilterPCs)
}
-func (serv *HTTPServer) collectCrashes(workdir string) ([]*UICrashType, error) {
- var repros map[string]bool
+func (serv *HTTPServer) collectDiffCrashes() (patchedOnly, both, inProgress *UIDiffTable) {
+ for _, item := range serv.allDiffCrashes() {
+ if item.PatchedOnly() {
+ if patchedOnly == nil {
+ patchedOnly = &UIDiffTable{Title: "Patched-only"}
+ }
+ patchedOnly.List = append(patchedOnly.List, item)
+ } else if item.AffectsBoth() {
+ if both == nil {
+ both = &UIDiffTable{Title: "Affects both"}
+ }
+ both.List = append(both.List, item)
+ } else {
+ if inProgress == nil {
+ inProgress = &UIDiffTable{Title: "In Progress"}
+ }
+ inProgress.List = append(inProgress.List, item)
+ }
+ }
+ return
+}
+
+func (serv *HTTPServer) allDiffCrashes() []UIDiffBug {
+ repros := serv.nowReproducing()
+ var list []UIDiffBug
+ for _, bug := range serv.DiffStore.List() {
+ list = append(list, UIDiffBug{
+ DiffBug: bug,
+ Reproducing: repros[bug.Title],
+ })
+ }
+ sort.Slice(list, func(i, j int) bool {
+ first, second := list[i], list[j]
+ firstPatched, secondPatched := first.PatchedOnly(), second.PatchedOnly()
+ if firstPatched != secondPatched {
+ return firstPatched
+ }
+ return first.Title < second.Title
+ })
+ return list
+}
+
+func (serv *HTTPServer) nowReproducing() map[string]bool {
if reproLoop := serv.ReproLoop.Load(); reproLoop != nil {
- repros = reproLoop.Reproducing()
+ return reproLoop.Reproducing()
}
+ return nil
+}
+
+func (serv *HTTPServer) collectCrashes(workdir string) ([]*UICrashType, error) {
list, err := serv.CrashStore.BugList()
if err != nil {
return nil, err
}
+ repros := serv.nowReproducing()
var ret []*UICrashType
for _, info := range list {
ret = append(ret, makeUICrashType(info, serv.StartTime, repros))
@@ -788,9 +841,17 @@ type UISummaryData struct {
Expert bool
Stats []UIStat
Crashes []*UICrashType
+ PatchedOnly *UIDiffTable
+ AffectsBoth *UIDiffTable
+ InProgress *UIDiffTable
Log string
}
+type UIDiffTable struct {
+ Title string
+ List []UIDiffBug
+}
+
type UIVMData struct {
Name string
VMs []UIVMInfo
@@ -825,6 +886,11 @@ type UICrash struct {
Active bool
}
+type UIDiffBug struct {
+ DiffBug
+ Reproducing bool
+}
+
type UIStat struct {
Name string
Value string
@@ -881,6 +947,7 @@ var summaryTemplate = pages.Create(`
{{end}}
</table>
+{{if .Crashes}}
<table class="list_table">
<caption>Crashes:</caption>
<tr>
@@ -905,6 +972,63 @@ var summaryTemplate = pages.Create(`
</tr>
{{end}}
</table>
+{{end}}
+
+{{define "diff_crashes"}}
+<table class="list_table">
+ <caption>{{.Title}}:</caption>
+ <tr>
+ <th>Description</th>
+ <th>Base</th>
+ <th>Patched</th>
+ </tr>
+ {{range $bug := .List}}
+ <tr>
+ <td class="title">{{$bug.Title}}</td>
+ <td class="title">
+ {{if gt $bug.Base.Crashes 0}}
+ {{$bug.Base.Crashes}} crashes
+ {{else if $bug.Base.NotCrashed}}
+ Not affected
+ {{else}} ? {{end}}
+ {{if $bug.Base.Report}}
+ <a href="/file?name={{$bug.Base.Report}}">[report]</a>
+ {{end}}
+ </td>
+ <td class="title">
+ {{if gt $bug.Patched.Crashes 0}}
+ {{$bug.Patched.Crashes}} crashes
+ {{else}} ? {{end}}
+ {{if $bug.Patched.Report}}
+ <a href="/file?name={{$bug.Patched.Report}}">[report]</a>
+ {{end}}
+ {{if $bug.Patched.CrashLog}}
+ <a href="/file?name={{$bug.Patched.CrashLog}}">[crash log]</a>
+ {{end}}
+ {{if $bug.Patched.Repro}}
+ <a href="/file?name={{$bug.Patched.Repro}}">[syz repro]</a>
+ {{end}}
+ {{if $bug.Patched.ReproLog}}
+ <a href="/file?name={{$bug.Patched.ReproLog}}">[repro log]</a>
+ {{end}}
+ {{if $bug.Reproducing}}[reproducing]{{end}}
+ </td>
+ </tr>
+ {{end}}
+</table>
+{{end}}
+
+{{if .PatchedOnly}}
+{{template "diff_crashes" .PatchedOnly}}
+{{end}}
+
+{{if .AffectsBoth}}
+{{template "diff_crashes" .AffectsBoth}}
+{{end}}
+
+{{if .InProgress}}
+{{template "diff_crashes" .InProgress}}
+{{end}}
<b>Log:</b>
<br>