From 6d01f20890edf11b99bb54573025b11c1acd2d52 Mon Sep 17 00:00:00 2001 From: zsm-oss <31279919+zsm-oss@users.noreply.github.com> Date: Thu, 15 Jun 2023 06:58:56 -0700 Subject: syz-cover: accept canonical module info (#3964) * syz-manager: endpoint to display canonical modules Add a "/modules" endpoint that displays canonical module information. * tools/syz-cover: accept module info Add support to syz-cover to generate coverage reports for drivers that are built as kernel modules. At the moment, ReportGenerator instances are created with no []host.KernelModule information. As a result, discoverModulesLinux() does not process kernel modules, only the vmlinux. Add a "-modules" flag that accepts module info. This info can be fetched from the web UI at "/modules". Usage: $ ./bin/syz-cover -arch arm64 -kernel_obj ${KOBJ} -kernel_src ${KSRC} \ -json ~/report.json -modules ~/modules \ ~/rawcover --- pkg/host/machine_info.go | 6 +++--- syz-manager/html.go | 16 ++++++++++++++++ tools/syz-cover/syz-cover.go | 25 ++++++++++++++++++++++++- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/pkg/host/machine_info.go b/pkg/host/machine_info.go index 6dd2f0686..3c04becab 100644 --- a/pkg/host/machine_info.go +++ b/pkg/host/machine_info.go @@ -55,7 +55,7 @@ type machineInfoFunc struct { } type KernelModule struct { - Name string - Addr uint64 - Size uint64 + Name string `json:"Name"` + Addr uint64 `json:"Addr"` + Size uint64 `json:"Size"` } diff --git a/syz-manager/html.go b/syz-manager/html.go index d0d20542d..52086ca77 100644 --- a/syz-manager/html.go +++ b/syz-manager/html.go @@ -55,6 +55,7 @@ func (mgr *Manager) initHTTP() { handle("/filecover", mgr.httpFileCover) handle("/input", mgr.httpInput) handle("/debuginput", mgr.httpDebugInput) + handle("/modules", mgr.modulesInfo) // Browsers like to request this, without special handler this goes to / handler. handle("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {}) @@ -507,6 +508,21 @@ func (mgr *Manager) httpDebugInput(w http.ResponseWriter, r *http.Request) { executeTemplate(w, rawCoverTemplate, data) } +func (mgr *Manager) modulesInfo(w http.ResponseWriter, r *http.Request) { + if mgr.serv.canonicalModules == nil { + fmt.Fprintf(w, "module information not retrieved yet, please retry after fuzzing starts\n") + return + } + // NewCanonicalizer() is initialized with serv.modules. + modules, err := json.MarshalIndent(mgr.serv.modules, "", "\t") + if err != nil { + fmt.Fprintf(w, "unable to create JSON modules info: %v", err) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(modules) +} + func (mgr *Manager) httpReport(w http.ResponseWriter, r *http.Request) { mgr.mu.Lock() defer mgr.mu.Unlock() diff --git a/tools/syz-cover/syz-cover.go b/tools/syz-cover/syz-cover.go index 80c58ffc5..a28d8db5d 100644 --- a/tools/syz-cover/syz-cover.go +++ b/tools/syz-cover/syz-cover.go @@ -19,6 +19,7 @@ package main import ( "bufio" "bytes" + "encoding/json" "flag" "fmt" "os" @@ -28,6 +29,7 @@ import ( "strings" "github.com/google/syzkaller/pkg/cover" + "github.com/google/syzkaller/pkg/host" "github.com/google/syzkaller/pkg/osutil" "github.com/google/syzkaller/pkg/tool" "github.com/google/syzkaller/sys/targets" @@ -41,6 +43,7 @@ func main() { flagKernelSrc = flag.String("kernel_src", "", "path to kernel sources") flagKernelBuildSrc = flag.String("kernel_build_src", "", "path to kernel image's build dir (optional)") flagKernelObj = flag.String("kernel_obj", "", "path to kernel build/obj dir") + flagModules = flag.String("modules", "", "modules info obtained from /modules (optional)") flagExportCSV = flag.String("csv", "", "export coverage data in csv format (optional)") flagExportLineJSON = flag.String("json", "", "export coverage data with source line info in json format (optional)") flagExportHTML = flag.String("html", "", "save coverage HTML report to file (optional)") @@ -72,8 +75,16 @@ func main() { if err != nil { tool.Fail(err) } + var modules []host.KernelModule + if *flagModules != "" { + m, err := loadModules(*flagModules) + if err != nil { + tool.Fail(err) + } + modules = m + } rg, err := cover.MakeReportGenerator(target, *flagVM, *flagKernelObj, - *flagKernelSrc, *flagKernelBuildSrc, nil, nil, nil, false) + *flagKernelSrc, *flagKernelBuildSrc, nil, nil, modules, false) if err != nil { tool.Fail(err) } @@ -140,3 +151,15 @@ func readPCs(files []string) ([]uint64, error) { } return pcs, nil } + +func loadModules(fname string) ([]host.KernelModule, error) { + data, err := os.ReadFile(fname) + if err != nil { + return nil, err + } + var modules []host.KernelModule + if err := json.Unmarshal(data, &modules); err != nil { + return nil, err + } + return modules, nil +} -- cgit mrf-deployment