aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2021-12-14 17:27:37 +0100
committerMarco Elver <me@marcoelver.com>2021-12-16 17:27:08 +0100
commit44068e196185e2f5a7c94629b6245cdde008b140 (patch)
tree7bb3bcf150c9715fb5ca933c989915501e6dcba6
parent8dd6a5e3524be635d738d091a2eab895d47da723 (diff)
pkg/mgrconfig: add "interests"
We have "suppressions" parameter to suppress non-interesting reports. Add "interests" parameter which is an opposite of "suppressions" -- everything that's not in "interests" is suppressed. It's matched against bug title, guilty file and maintainer emails.
-rw-r--r--pkg/mgrconfig/config.go4
-rw-r--r--pkg/report/report.go53
-rw-r--r--pkg/repro/repro.go3
-rw-r--r--syz-manager/manager.go6
4 files changed, 60 insertions, 6 deletions
diff --git a/pkg/mgrconfig/config.go b/pkg/mgrconfig/config.go
index a2e850db1..7384b75c5 100644
--- a/pkg/mgrconfig/config.go
+++ b/pkg/mgrconfig/config.go
@@ -153,6 +153,10 @@ type Config struct {
// Completely ignore reports matching these regexps (don't save nor reboot),
// must match the first line of crash message.
Ignores []string `json:"ignores,omitempty"`
+ // List of regexps to select bugs of interest.
+ // If this list is not empty and none of the regexps match a bug, it's suppressed.
+ // Regexps are matched against bug title, guilty file and maintainer emails.
+ Interests []string `json:"interests,omitempty"`
// Type of virtual machine to use, e.g. "qemu", "gce", "android", "isolated", etc.
Type string `json:"type"`
diff --git a/pkg/report/report.go b/pkg/report/report.go
index 163773e04..9346f0322 100644
--- a/pkg/report/report.go
+++ b/pkg/report/report.go
@@ -30,9 +30,10 @@ type reporterImpl interface {
}
type Reporter struct {
+ typ string
impl reporterImpl
suppressions []*regexp.Regexp
- typ string
+ interests []*regexp.Regexp
}
type Report struct {
@@ -109,6 +110,10 @@ func NewReporter(cfg *mgrconfig.Config) (*Reporter, error) {
if err != nil {
return nil, err
}
+ interests, err := compileRegexps(cfg.Interests)
+ if err != nil {
+ return nil, err
+ }
config := &config{
target: cfg.SysTarget,
kernelSrc: cfg.KernelSrc,
@@ -124,7 +129,13 @@ func NewReporter(cfg *mgrconfig.Config) (*Reporter, error) {
if err != nil {
return nil, err
}
- return &Reporter{rep, supps, typ}, nil
+ reporter := &Reporter{
+ typ: typ,
+ impl: rep,
+ suppressions: supps,
+ interests: interests,
+ }
+ return reporter, nil
}
const (
@@ -209,7 +220,34 @@ func (reporter *Reporter) ContainsCrash(output []byte) bool {
}
func (reporter *Reporter) Symbolize(rep *Report) error {
- return reporter.impl.Symbolize(rep)
+ if err := reporter.impl.Symbolize(rep); err != nil {
+ return err
+ }
+ if !reporter.isInteresting(rep) {
+ rep.Suppressed = true
+ }
+ return nil
+}
+
+func (reporter *Reporter) isInteresting(rep *Report) bool {
+ if len(reporter.interests) == 0 {
+ return true
+ }
+ if matchesAnyString(rep.Title, reporter.interests) ||
+ matchesAnyString(rep.guiltyFile, reporter.interests) {
+ return true
+ }
+ for _, title := range rep.AltTitles {
+ if matchesAnyString(title, reporter.interests) {
+ return true
+ }
+ }
+ for _, recipient := range rep.Recipients {
+ if matchesAnyString(recipient.Address.Address, reporter.interests) {
+ return true
+ }
+ }
+ return false
}
func extractReportType(rep *Report) Type {
@@ -647,6 +685,15 @@ func matchesAny(line []byte, res []*regexp.Regexp) bool {
return false
}
+func matchesAnyString(str string, res []*regexp.Regexp) bool {
+ for _, re := range res {
+ if re.MatchString(str) {
+ return true
+ }
+ }
+ return false
+}
+
// replace replaces [start:end] in where with what, inplace.
func replace(where []byte, start, end int, what []byte) []byte {
if len(what) >= end-start {
diff --git a/pkg/repro/repro.go b/pkg/repro/repro.go
index 06afec8c2..8726cbfd3 100644
--- a/pkg/repro/repro.go
+++ b/pkg/repro/repro.go
@@ -631,6 +631,9 @@ func (ctx *context) testImpl(inst *vm.Instance, command string, duration time.Du
ctx.reproLogf(2, "program did not crash")
return false, nil
}
+ if err := ctx.reporter.Symbolize(rep); err != nil {
+ return false, fmt.Errorf("failed to symbolize report: %v", err)
+ }
if rep.Suppressed {
ctx.reproLogf(2, "suppressed program crash: %v", rep.Title)
return false, nil
diff --git a/syz-manager/manager.go b/syz-manager/manager.go
index 2a0468102..3779f8365 100644
--- a/syz-manager/manager.go
+++ b/syz-manager/manager.go
@@ -664,6 +664,9 @@ func (mgr *Manager) emailCrash(crash *Crash) {
}
func (mgr *Manager) saveCrash(crash *Crash) bool {
+ if err := mgr.reporter.Symbolize(crash.Report); err != nil {
+ log.Logf(0, "failed to symbolize report: %v", err)
+ }
if crash.Type == report.MemoryLeak {
mgr.mu.Lock()
mgr.memoryLeakFrames[crash.Frame] = true
@@ -689,9 +692,6 @@ func (mgr *Manager) saveCrash(crash *Crash) bool {
crash.Title = "suppressed report"
mgr.stats.crashSuppressed.inc()
}
- if err := mgr.reporter.Symbolize(crash.Report); err != nil {
- log.Logf(0, "failed to symbolize report: %v", err)
- }
mgr.stats.crashes.inc()
mgr.mu.Lock()