diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2024-10-20 22:55:31 +0200 |
|---|---|---|
| committer | Taras Madan <tarasmadan@google.com> | 2024-10-25 12:08:02 +0000 |
| commit | f63b8696b67a1c47ecd4fced47215acd6805a14a (patch) | |
| tree | c7d5795c124fdc9a99b309db8ed75f56b2c6ffe9 /pkg/manager/http.go | |
| parent | c0390c277e5fcda8d7288b717ff952e01dcdcb8d (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.go | 144 |
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> |
