aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2022-03-23 13:50:36 +0000
committerAleksandr Nogikh <wp32pw@gmail.com>2022-03-28 12:03:35 +0200
commitcdcc8b96dd9215a47ce5ce1074567a1be93eda5f (patch)
tree943129722632f399ee55e1245f7c10eaf98a5f8a /pkg
parentfc79262e5b62a97a2338b247a1c31ee1c79decc2 (diff)
all: collect raw coverage
Raw coverage might be important when e.g. analysing the origins of out-of-place coverage in coverage reports or understanding why the fuzzer could not reach deeper code. If "raw_cover" is set to true, syzkaller will remember unsorted and unduplicated coverage (PCs) for each its corpus program.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/instance/instance.go14
-rw-r--r--pkg/ipc/ipc.go22
-rw-r--r--pkg/mgrconfig/config.go5
-rw-r--r--pkg/rpctype/rpctype.go10
4 files changed, 36 insertions, 15 deletions
diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go
index 665281a47..c225f9696 100644
--- a/pkg/instance/instance.go
+++ b/pkg/instance/instance.go
@@ -452,6 +452,7 @@ type FuzzerCmdArgs struct {
Test bool
Runtest bool
Slowdown int
+ RawCover bool
}
func FuzzerCmd(args *FuzzerCmdArgs) string {
@@ -470,11 +471,16 @@ func FuzzerCmd(args *FuzzerCmdArgs) string {
if args.Verbosity != 0 {
verbosityArg = fmt.Sprintf(" -vv=%v", args.Verbosity)
}
- optionalArg := ""
+ flags := []tool.Flag{}
if args.Slowdown > 0 {
- optionalArg = " " + tool.OptionalFlags([]tool.Flag{
- {Name: "slowdown", Value: fmt.Sprint(args.Slowdown)},
- })
+ flags = append(flags, tool.Flag{Name: "slowdown", Value: fmt.Sprint(args.Slowdown)})
+ }
+ if args.RawCover {
+ flags = append(flags, tool.Flag{Name: "raw_cover", Value: "true"})
+ }
+ optionalArg := ""
+ if len(flags) > 0 {
+ optionalArg += " " + tool.OptionalFlags(flags)
}
return fmt.Sprintf("%v -executor=%v -name=%v -arch=%v%v -manager=%v -sandbox=%v"+
" -procs=%v -cover=%v -debug=%v -test=%v%v%v%v",
diff --git a/pkg/ipc/ipc.go b/pkg/ipc/ipc.go
index 5bf4738ca..6b25d4af4 100644
--- a/pkg/ipc/ipc.go
+++ b/pkg/ipc/ipc.go
@@ -289,7 +289,7 @@ func (env *Env) Exec(opts *ExecOpts, p *prog.Prog) (output []byte, info *ProgInf
return
}
- info, err0 = env.parseOutput(p)
+ info, err0 = env.parseOutput(p, opts)
if info != nil && env.config.Flags&FlagSignal == 0 {
addFallbackSignal(p, info)
}
@@ -323,7 +323,7 @@ func addFallbackSignal(p *prog.Prog, info *ProgInfo) {
}
}
-func (env *Env) parseOutput(p *prog.Prog) (*ProgInfo, error) {
+func (env *Env) parseOutput(p *prog.Prog, opts *ExecOpts) (*ProgInfo, error) {
out := env.out
ncmd, ok := readUint32(&out)
if !ok {
@@ -372,19 +372,27 @@ func (env *Env) parseOutput(p *prog.Prog) (*ProgInfo, error) {
if len(extraParts) == 0 {
return info, nil
}
- info.Extra = convertExtra(extraParts)
+ info.Extra = convertExtra(extraParts, opts.Flags&FlagDedupCover > 0)
return info, nil
}
-func convertExtra(extraParts []CallInfo) CallInfo {
+func convertExtra(extraParts []CallInfo, dedupCover bool) CallInfo {
var extra CallInfo
- extraCover := make(cover.Cover)
+ if dedupCover {
+ extraCover := make(cover.Cover)
+ for _, part := range extraParts {
+ extraCover.Merge(part.Cover)
+ }
+ extra.Cover = extraCover.Serialize()
+ } else {
+ for _, part := range extraParts {
+ extra.Cover = append(extra.Cover, part.Cover...)
+ }
+ }
extraSignal := make(signal.Signal)
for _, part := range extraParts {
- extraCover.Merge(part.Cover)
extraSignal.Merge(signal.FromRaw(part.Signal, 0))
}
- extra.Cover = extraCover.Serialize()
extra.Signal = make([]uint32, len(extraSignal))
i := 0
for s := range extraSignal {
diff --git a/pkg/mgrconfig/config.go b/pkg/mgrconfig/config.go
index 5d4a9f8f5..c13e6f452 100644
--- a/pkg/mgrconfig/config.go
+++ b/pkg/mgrconfig/config.go
@@ -132,6 +132,11 @@ type Config struct {
// eg. "0xffffffff81000000:0x10\n"
CovFilter covFilterCfg `json:"cover_filter,omitempty"`
+ // For each prog in the corpus, remember the raw array of PCs obtained from the kernel.
+ // It can be useful for debugging syzkaller descriptions and syzkaller itself.
+ // Disabled by default as it slows down fuzzing.
+ RawCover bool `json:"raw_cover"`
+
// Reproduce, localize and minimize crashers (default: true).
Reproduce bool `json:"reproduce"`
diff --git a/pkg/rpctype/rpctype.go b/pkg/rpctype/rpctype.go
index cb2f43e76..f1d889a20 100644
--- a/pkg/rpctype/rpctype.go
+++ b/pkg/rpctype/rpctype.go
@@ -14,10 +14,12 @@ import (
)
type Input struct {
- Call string
- Prog []byte
- Signal signal.Serial
- Cover []uint32
+ Call string
+ Prog []byte
+ Signal signal.Serial
+ Cover []uint32
+ CallID int // seq number of call in the prog to which the item is related (-1 for extra)
+ RawCover []uint32
}
type Candidate struct {