aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAndrey Konovalov <andreyknvl@google.com>2018-11-22 19:04:06 +0100
committerAndrey Konovalov <andreyknvl@gmail.com>2019-01-16 19:19:53 +0100
commitb5df78dc5d994bc61f1ecee2c5c85313178f392e (patch)
treec285f3be9e8d0ef32e607186ec9ce9eae6901cce /tools
parentc0d4a12ee72a2279eada43d9476d2f8a074c3818 (diff)
all: support extra coverage
Right now syzkaller only supports coverage collected from the threads that execute syscalls. However some useful things happen in background threads, and it would be nice to collect coverage from those threads as well. This change adds extra coverage support to syzkaller. This coverage is not associated with a particular syscall, but rather with the whole program. Executor passes extra coverage over the same ipc mechanism to syz-fuzzer with syscall number set to -1. syz-fuzzer then passes this coverage to syz-manager with the call name "extra". This change requires the following kcov patch: https://github.com/xairy/linux/pull/2
Diffstat (limited to 'tools')
-rw-r--r--tools/syz-execprog/execprog.go30
1 files changed, 18 insertions, 12 deletions
diff --git a/tools/syz-execprog/execprog.go b/tools/syz-execprog/execprog.go
index 5965677be..1a4468063 100644
--- a/tools/syz-execprog/execprog.go
+++ b/tools/syz-execprog/execprog.go
@@ -148,7 +148,7 @@ func (ctx *Context) execute(pid int, env *ipc.Env, entry *prog.LogEntry) {
log.Logf(0, "result: failed=%v hanged=%v err=%v\n\n%s",
failed, hanged, err, output)
}
- if info != nil && len(info.Calls) != 0 {
+ if info != nil {
ctx.printCallResults(info)
if *flagHints {
ctx.printHints(entry.P, info)
@@ -220,21 +220,27 @@ func (ctx *Context) printHints(p *prog.Prog, info *ipc.ProgInfo) {
log.Logf(0, "ncomps=%v ncandidates=%v", ncomps, ncandidates)
}
+func (ctx *Context) dumpCallCoverage(coverFile string, info *ipc.CallInfo) {
+ if len(info.Cover) == 0 {
+ return
+ }
+ buf := new(bytes.Buffer)
+ for _, pc := range info.Cover {
+ fmt.Fprintf(buf, "0x%x\n", cover.RestorePC(pc, 0xffffffff))
+ }
+ err := osutil.WriteFile(coverFile, buf.Bytes())
+ if err != nil {
+ log.Fatalf("failed to write coverage file: %v", err)
+ }
+}
+
func (ctx *Context) dumpCoverage(coverFile string, info *ipc.ProgInfo) {
for i, inf := range info.Calls {
log.Logf(0, "call #%v: signal %v, coverage %v", i, len(inf.Signal), len(inf.Cover))
- if len(inf.Cover) == 0 {
- continue
- }
- buf := new(bytes.Buffer)
- for _, pc := range inf.Cover {
- fmt.Fprintf(buf, "0x%x\n", cover.RestorePC(pc, 0xffffffff))
- }
- err := osutil.WriteFile(fmt.Sprintf("%v.%v", coverFile, i), buf.Bytes())
- if err != nil {
- log.Fatalf("failed to write coverage file: %v", err)
- }
+ ctx.dumpCallCoverage(fmt.Sprintf("%v.%v", coverFile, i), &inf)
}
+ log.Logf(0, "extra: signal %v, coverage %v", len(info.Extra.Signal), len(info.Extra.Cover))
+ ctx.dumpCallCoverage(fmt.Sprintf("%v.extra", coverFile), &info.Extra)
}
func (ctx *Context) getProgramIndex() int {