aboutsummaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-06-21 14:38:08 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-06-22 16:40:45 +0200
commit2a075d57ab619ae5333c823cc260a722ab0c47fe (patch)
tree0877143833caae9b98744a237b0e3a3694348a6b /pkg
parentc31f96a8c65c0757078ea77218905c73fc1068d4 (diff)
pkg/report: allow to specify suppressions per OS
Currently all (linux-specific) suppressions are hardcoded in mgrconfig. This is very wrong. Move them to pkg/report and allow to specify per OS. Add gvisor-specific suppressions. This required a bit of refactoring. Introduce mgrconfig.KernelObj finally. Make report.NewReporter and vm.Create accept mgrconfig directly instead of passing it as multiple scattered args. Remove tools/syz-parse and it always did the same as tools/syz-symbolize. Simplify global vars in syz-manager/cover.go. Create reporter eagerly in manager. Use sort.Slice more. Overall -90 lines removed.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/instance/instance.go8
-rw-r--r--pkg/report/freebsd.go9
-rw-r--r--pkg/report/fuchsia.go9
-rw-r--r--pkg/report/gvisor.go13
-rw-r--r--pkg/report/linux.go32
-rw-r--r--pkg/report/linux_test.go28
-rw-r--r--pkg/report/netbsd.go9
-rw-r--r--pkg/report/report.go51
-rw-r--r--pkg/report/report_test.go6
-rw-r--r--pkg/report/stub.go9
10 files changed, 92 insertions, 82 deletions
diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go
index b5f44376c..e7ab3c9ec 100644
--- a/pkg/instance/instance.go
+++ b/pkg/instance/instance.go
@@ -82,7 +82,7 @@ func (env *Env) BuildKernel(compilerBin, userspaceDir, cmdlineFile, sysctlFile s
if err := kernel.Build(cfg.KernelSrc, compilerBin, kernelConfig); err != nil {
return osutil.PrependContext("kernel build failed", err)
}
- cfg.Vmlinux = filepath.Join(cfg.KernelSrc, "vmlinux")
+ cfg.KernelObj = cfg.KernelSrc
cfg.Image = filepath.Join(cfg.Workdir, "syz-image")
cfg.SSHKey = filepath.Join(cfg.Workdir, "syz-key")
if err := kernel.CreateImage(cfg.TargetOS, cfg.TargetVMArch, cfg.Type,
@@ -118,13 +118,11 @@ func (env *Env) Test(numVMs int, reproSyz, reproOpts, reproC []byte) ([]error, e
if err := mgrconfig.Complete(env.cfg); err != nil {
return nil, err
}
- reporter, err := report.NewReporter(env.cfg.TargetOS, env.cfg.Type,
- env.cfg.KernelSrc, filepath.Dir(env.cfg.Vmlinux), nil, env.cfg.ParsedIgnores)
+ reporter, err := report.NewReporter(env.cfg)
if err != nil {
return nil, err
}
- vmEnv := mgrconfig.CreateVMEnv(env.cfg, false)
- vmPool, err := vm.Create(env.cfg.Type, vmEnv)
+ vmPool, err := vm.Create(env.cfg, false)
if err != nil {
return nil, fmt.Errorf("failed to create VM pool: %v", err)
}
diff --git a/pkg/report/freebsd.go b/pkg/report/freebsd.go
index f16f2c15d..6e3bbb7e5 100644
--- a/pkg/report/freebsd.go
+++ b/pkg/report/freebsd.go
@@ -6,26 +6,21 @@ package report
import (
"bytes"
"regexp"
-
- "github.com/google/syzkaller/pkg/symbolizer"
)
type freebsd struct {
kernelSrc string
kernelObj string
- symbols map[string][]symbolizer.Symbol
ignores []*regexp.Regexp
}
-func ctorFreebsd(kernelSrc, kernelObj string, symbols map[string][]symbolizer.Symbol,
- ignores []*regexp.Regexp) (Reporter, error) {
+func ctorFreebsd(kernelSrc, kernelObj string, ignores []*regexp.Regexp) (Reporter, []string, error) {
ctx := &freebsd{
kernelSrc: kernelSrc,
kernelObj: kernelObj,
- symbols: symbols,
ignores: ignores,
}
- return ctx, nil
+ return ctx, nil, nil
}
func (ctx *freebsd) ContainsCrash(output []byte) bool {
diff --git a/pkg/report/fuchsia.go b/pkg/report/fuchsia.go
index 67a3e2ae9..4e227fc93 100644
--- a/pkg/report/fuchsia.go
+++ b/pkg/report/fuchsia.go
@@ -6,26 +6,21 @@ package report
import (
"bytes"
"regexp"
-
- "github.com/google/syzkaller/pkg/symbolizer"
)
type fuchsia struct {
kernelSrc string
kernelObj string
- symbols map[string][]symbolizer.Symbol
ignores []*regexp.Regexp
}
-func ctorFuchsia(kernelSrc, kernelObj string, symbols map[string][]symbolizer.Symbol,
- ignores []*regexp.Regexp) (Reporter, error) {
+func ctorFuchsia(kernelSrc, kernelObj string, ignores []*regexp.Regexp) (Reporter, []string, error) {
ctx := &fuchsia{
kernelSrc: kernelSrc,
kernelObj: kernelObj,
- symbols: symbols,
ignores: ignores,
}
- return ctx, nil
+ return ctx, nil, nil
}
func (ctx *fuchsia) ContainsCrash(output []byte) bool {
diff --git a/pkg/report/gvisor.go b/pkg/report/gvisor.go
index 357051fb0..fa1c8476e 100644
--- a/pkg/report/gvisor.go
+++ b/pkg/report/gvisor.go
@@ -6,20 +6,23 @@ package report
import (
"bytes"
"regexp"
-
- "github.com/google/syzkaller/pkg/symbolizer"
)
type gvisor struct {
ignores []*regexp.Regexp
}
-func ctorGvisor(kernelSrc, kernelObj string, symbols map[string][]symbolizer.Symbol,
- ignores []*regexp.Regexp) (Reporter, error) {
+func ctorGvisor(kernelSrc, kernelObj string, ignores []*regexp.Regexp) (Reporter, []string, error) {
ctx := &gvisor{
ignores: ignores,
}
- return ctx, nil
+ suppressions := []string{
+ "fatal error: runtime: out of memory",
+ "fatal error: runtime: cannot allocate memory",
+ "panic: failed to start executor binary",
+ "panic: executor failed: pthread_create failed",
+ }
+ return ctx, suppressions, nil
}
func (ctx *gvisor) ContainsCrash(output []byte) bool {
diff --git a/pkg/report/linux.go b/pkg/report/linux.go
index 0fc67f80d..f29235b69 100644
--- a/pkg/report/linux.go
+++ b/pkg/report/linux.go
@@ -32,17 +32,15 @@ type linux struct {
eoi []byte
}
-func ctorLinux(kernelSrc, kernelObj string, symbols map[string][]symbolizer.Symbol,
- ignores []*regexp.Regexp) (Reporter, error) {
+func ctorLinux(kernelSrc, kernelObj string, ignores []*regexp.Regexp) (Reporter, []string, error) {
vmlinux := ""
+ var symbols map[string][]symbolizer.Symbol
if kernelObj != "" {
vmlinux = filepath.Join(kernelObj, "vmlinux")
- if symbols == nil {
- var err error
- symbols, err = symbolizer.ReadSymbols(vmlinux)
- if err != nil {
- return nil, err
- }
+ var err error
+ symbols, err = symbolizer.ReadSymbols(vmlinux)
+ if err != nil {
+ return nil, nil, err
}
}
ctx := &linux{
@@ -95,7 +93,23 @@ func ctorLinux(kernelSrc, kernelObj string, symbols map[string][]symbolizer.Symb
[]byte("FAULT_INJECTION: forcing a failure"),
[]byte("FAULT_FLAG_ALLOW_RETRY missing"),
}
- return ctx, nil
+ suppressions := []string{
+ "fatal error: runtime: out of memory",
+ "fatal error: runtime: cannot allocate memory",
+ "panic: failed to start executor binary",
+ "panic: executor failed: pthread_create failed",
+ "panic: failed to create temp dir",
+ "fatal error: unexpected signal during runtime execution", // presubmably OOM turned into SIGBUS
+ "signal SIGBUS: bus error", // presubmably OOM turned into SIGBUS
+ "Out of memory: Kill process .* \\(syz-fuzzer\\)",
+ "Out of memory: Kill process .* \\(sshd\\)",
+ "Killed process .* \\(syz-fuzzer\\)",
+ "Killed process .* \\(sshd\\)",
+ "lowmemorykiller: Killing 'syz-fuzzer'",
+ "lowmemorykiller: Killing 'sshd'",
+ "INIT: PANIC: segmentation violation!",
+ }
+ return ctx, suppressions, nil
}
func (ctx *linux) ContainsCrash(output []byte) bool {
diff --git a/pkg/report/linux_test.go b/pkg/report/linux_test.go
index 0543fcbe0..338ab27a0 100644
--- a/pkg/report/linux_test.go
+++ b/pkg/report/linux_test.go
@@ -5,38 +5,32 @@ package report
import (
"fmt"
- "regexp"
"testing"
"github.com/google/syzkaller/pkg/symbolizer"
+ "github.com/google/syzkaller/syz-manager/mgrconfig"
)
func TestLinuxIgnores(t *testing.T) {
- reporter, err := NewReporter("linux", "", "", "", nil, nil)
+ cfg := &mgrconfig.Config{
+ TargetOS: "linux",
+ }
+ reporter, err := NewReporter(cfg)
if err != nil {
t.Fatal(err)
}
- ignores1 := []*regexp.Regexp{
- regexp.MustCompile("BUG: bug3"),
- }
- reporter1, err := NewReporter("linux", "", "", "", nil, ignores1)
+ cfg.Ignores = []string{"BUG: bug3"}
+ reporter1, err := NewReporter(cfg)
if err != nil {
t.Fatal(err)
}
- ignores2 := []*regexp.Regexp{
- regexp.MustCompile("BUG: bug3"),
- regexp.MustCompile("BUG: bug1"),
- }
- reporter2, err := NewReporter("linux", "", "", "", nil, ignores2)
+ cfg.Ignores = []string{"BUG: bug3", "BUG: bug1"}
+ reporter2, err := NewReporter(cfg)
if err != nil {
t.Fatal(err)
}
- ignores3 := []*regexp.Regexp{
- regexp.MustCompile("BUG: bug3"),
- regexp.MustCompile("BUG: bug1"),
- regexp.MustCompile("BUG: bug2"),
- }
- reporter3, err := NewReporter("linux", "", "", "", nil, ignores3)
+ cfg.Ignores = []string{"BUG: bug3", "BUG: bug1", "BUG: bug2"}
+ reporter3, err := NewReporter(cfg)
if err != nil {
t.Fatal(err)
}
diff --git a/pkg/report/netbsd.go b/pkg/report/netbsd.go
index 6c4dbedf9..5457327c9 100644
--- a/pkg/report/netbsd.go
+++ b/pkg/report/netbsd.go
@@ -5,26 +5,21 @@ package report
import (
"regexp"
-
- "github.com/google/syzkaller/pkg/symbolizer"
)
type netbsd struct {
kernelSrc string
kernelObj string
- symbols map[string][]symbolizer.Symbol
ignores []*regexp.Regexp
}
-func ctorNetbsd(kernelSrc, kernelObj string, symbols map[string][]symbolizer.Symbol,
- ignores []*regexp.Regexp) (Reporter, error) {
+func ctorNetbsd(kernelSrc, kernelObj string, ignores []*regexp.Regexp) (Reporter, []string, error) {
ctx := &netbsd{
kernelSrc: kernelSrc,
kernelObj: kernelObj,
- symbols: symbols,
ignores: ignores,
}
- return ctx, nil
+ return ctx, nil, nil
}
func (ctx *netbsd) ContainsCrash(output []byte) bool {
diff --git a/pkg/report/report.go b/pkg/report/report.go
index bd702b1d0..2e8d13a0f 100644
--- a/pkg/report/report.go
+++ b/pkg/report/report.go
@@ -12,7 +12,7 @@ import (
"regexp"
"strings"
- "github.com/google/syzkaller/pkg/symbolizer"
+ "github.com/google/syzkaller/syz-manager/mgrconfig"
)
type Reporter interface {
@@ -37,6 +37,8 @@ type Report struct {
// StartPos/EndPos denote region of output with oops message(s).
StartPos int
EndPos int
+ // Suppressed indicates whether the report should not be reported to user.
+ Suppressed bool
// Corrupted indicates whether the report is truncated of corrupted in some other way.
Corrupted bool
// corruptedReason contains reason why the report is marked as corrupted.
@@ -45,28 +47,29 @@ type Report struct {
Maintainers []string
}
-// NewReporter creates reporter for the specified OS/vmType:
-// kernelSrc: path to kernel sources directory
-// kernelObj: path to kernel build directory (can be empty for in-tree build)
-// symbols: kernel symbols (result of pkg/symbolizer.ReadSymbols on kernel object file)
-// ignores: optional list of regexps to ignore (must match first line of crash message)
-func NewReporter(os, vmType, kernelSrc, kernelObj string, symbols map[string][]symbolizer.Symbol,
- ignores []*regexp.Regexp) (Reporter, error) {
- if vmType == "gvisor" {
- os = vmType
+// NewReporter creates reporter for the specified OS/Type.
+func NewReporter(cfg *mgrconfig.Config) (Reporter, error) {
+ typ := cfg.TargetOS
+ if cfg.Type == "gvisor" {
+ typ = cfg.Type
}
- ctor := ctors[os]
+ ctor := ctors[typ]
if ctor == nil {
- return nil, fmt.Errorf("unknown os: %v", os)
+ return nil, fmt.Errorf("unknown OS: %v", typ)
}
- if kernelObj == "" {
- kernelObj = kernelSrc // assume in-tree build
+ ignores, err := compileRegexps(cfg.Ignores)
+ if err != nil {
+ return nil, err
+ }
+ rep, suppressions, err := ctor(cfg.KernelSrc, cfg.KernelObj, ignores)
+ if err != nil {
+ return nil, err
}
- rep, err := ctor(kernelSrc, kernelObj, symbols, ignores)
+ supps, err := compileRegexps(append(suppressions, cfg.Suppressions...))
if err != nil {
return nil, err
}
- return reporterWrapper{rep}, nil
+ return reporterWrapper{rep, supps}, nil
}
var ctors = map[string]fn{
@@ -79,10 +82,23 @@ var ctors = map[string]fn{
"windows": ctorStub,
}
-type fn func(string, string, map[string][]symbolizer.Symbol, []*regexp.Regexp) (Reporter, error)
+type fn func(string, string, []*regexp.Regexp) (Reporter, []string, error)
+
+func compileRegexps(list []string) ([]*regexp.Regexp, error) {
+ compiled := make([]*regexp.Regexp, len(list))
+ for i, str := range list {
+ re, err := regexp.Compile(str)
+ if err != nil {
+ return nil, fmt.Errorf("failed to compile %q: %v", str, err)
+ }
+ compiled[i] = re
+ }
+ return compiled, nil
+}
type reporterWrapper struct {
Reporter
+ suppressions []*regexp.Regexp
}
func (wrap reporterWrapper) Parse(output []byte) *Report {
@@ -91,6 +107,7 @@ func (wrap reporterWrapper) Parse(output []byte) *Report {
return nil
}
rep.Title = sanitizeTitle(replaceTable(dynamicTitleReplacement, rep.Title))
+ rep.Suppressed = matchesAny(rep.Output, wrap.suppressions)
return rep
}
diff --git a/pkg/report/report_test.go b/pkg/report/report_test.go
index 14d6c45ce..a2d833837 100644
--- a/pkg/report/report_test.go
+++ b/pkg/report/report_test.go
@@ -16,6 +16,7 @@ import (
"testing"
"github.com/google/syzkaller/pkg/osutil"
+ "github.com/google/syzkaller/syz-manager/mgrconfig"
)
var flagUpdate = flag.Bool("update", false, "update test files accordingly to current results")
@@ -214,7 +215,10 @@ func forEachFile(t *testing.T, dir string, fn func(t *testing.T, reporter Report
if err != nil {
t.Fatal(err)
}
- reporter, err := NewReporter(os, "", "", "", nil, nil)
+ cfg := &mgrconfig.Config{
+ TargetOS: os,
+ }
+ reporter, err := NewReporter(cfg)
if err != nil {
t.Fatal(err)
}
diff --git a/pkg/report/stub.go b/pkg/report/stub.go
index 04f17084a..32bcb0085 100644
--- a/pkg/report/stub.go
+++ b/pkg/report/stub.go
@@ -5,26 +5,21 @@ package report
import (
"regexp"
-
- "github.com/google/syzkaller/pkg/symbolizer"
)
type stub struct {
kernelSrc string
kernelObj string
- symbols map[string][]symbolizer.Symbol
ignores []*regexp.Regexp
}
-func ctorStub(kernelSrc, kernelObj string, symbols map[string][]symbolizer.Symbol,
- ignores []*regexp.Regexp) (Reporter, error) {
+func ctorStub(kernelSrc, kernelObj string, ignores []*regexp.Regexp) (Reporter, []string, error) {
ctx := &stub{
kernelSrc: kernelSrc,
kernelObj: kernelObj,
- symbols: symbols,
ignores: ignores,
}
- return ctx, nil
+ return ctx, nil, nil
}
func (ctx *stub) ContainsCrash(output []byte) bool {