diff options
| -rw-r--r-- | pkg/manager/diff.go | 6 | ||||
| -rw-r--r-- | pkg/manager/diff_store.go | 37 | ||||
| -rw-r--r-- | syz-cluster/workflow/fuzz-step/main.go | 25 | ||||
| -rw-r--r-- | tools/syz-diff/diff.go | 4 |
4 files changed, 56 insertions, 16 deletions
diff --git a/pkg/manager/diff.go b/pkg/manager/diff.go index d0cb33aa3..379fd246c 100644 --- a/pkg/manager/diff.go +++ b/pkg/manager/diff.go @@ -39,6 +39,7 @@ import ( type DiffFuzzerConfig struct { Debug bool PatchedOnly chan *UniqueBug + Store *DiffFuzzerStore ArtifactsDir string // Where to store the artifacts that supplement the logs. // The fuzzer waits no more than MaxTriageTime time until it starts taking VMs away // for bug reproduction. @@ -82,13 +83,12 @@ func RunDiffFuzzer(ctx context.Context, baseCfg, newCfg *mgrconfig.Config, cfg D base.source = stream new.duplicateInto = stream - store := &DiffFuzzerStore{BasePath: cfg.ArtifactsDir} diffCtx := &diffContext{ cfg: cfg, doneRepro: make(chan *ReproResult), base: base, new: new, - store: store, + store: cfg.Store, reproAttempts: map[string]int{}, patchedOnly: cfg.PatchedOnly, } @@ -96,7 +96,7 @@ func RunDiffFuzzer(ctx context.Context, baseCfg, newCfg *mgrconfig.Config, cfg D diffCtx.http = &HTTPServer{ Cfg: newCfg, StartTime: time.Now(), - DiffStore: store, + DiffStore: cfg.Store, Pools: map[string]*vm.Dispatcher{ new.name: new.pool, base.name: base.pool, diff --git a/pkg/manager/diff_store.go b/pkg/manager/diff_store.go index 76e2b97ff..2fb7d7f19 100644 --- a/pkg/manager/diff_store.go +++ b/pkg/manager/diff_store.go @@ -4,9 +4,12 @@ package manager import ( + "bytes" "fmt" "path/filepath" + "sort" "sync" + "text/tabwriter" "time" "github.com/google/syzkaller/pkg/log" @@ -116,6 +119,40 @@ func (s *DiffFuzzerStore) List() []DiffBug { return list } +func (s *DiffFuzzerStore) PlainTextDump() []byte { + list := s.List() + sort.Slice(list, func(i, j int) bool { + // Put patched-only on top, otherwise sort by the title. + first, second := list[i].PatchedOnly(), list[j].PatchedOnly() + if first != second { + return first + } + return list[i].Title < list[j].Title + }) + var buf bytes.Buffer + w := tabwriter.NewWriter(&buf, 0, 0, 1, ' ', 0) + fmt.Fprintln(w, "Title\tOn-Base\tOn-Patched") + + printInfo := func(info *DiffBugInfo) { + if info.Crashes > 0 { + fmt.Fprintf(w, "%d crashes", info.Crashes) + } + if info.Repro != "" { + fmt.Fprintf(w, "[reproduced]") + } + } + + for _, item := range list { + fmt.Fprintf(w, "%s\t", item.Title) + printInfo(&item.Base) + fmt.Fprintf(w, "\t") + printInfo(&item.Patched) + fmt.Fprintf(w, "\n") + } + w.Flush() + return buf.Bytes() +} + func (s *DiffFuzzerStore) saveFile(title, name string, data []byte) string { hash := crashHash(title) path := filepath.Join(s.BasePath, "crashes", hash) diff --git a/syz-cluster/workflow/fuzz-step/main.go b/syz-cluster/workflow/fuzz-step/main.go index 05b145554..9120ff3cd 100644 --- a/syz-cluster/workflow/fuzz-step/main.go +++ b/syz-cluster/workflow/fuzz-step/main.go @@ -53,30 +53,33 @@ func main() { log.Fatalf("the binary is built without the git revision information") } ctx := context.Background() - if err := reportStatus(ctx, client, api.TestRunning, ""); err != nil { + if err := reportStatus(ctx, client, api.TestRunning, nil); err != nil { app.Fatalf("failed to report the test: %v", err) } artifactsDir := filepath.Join(*flagWorkdir, "artifacts") osutil.MkdirAll(artifactsDir) + store := &manager.DiffFuzzerStore{BasePath: artifactsDir} // We want to only cancel the run() operation in order to be able to also report // the final test result back. runCtx, cancel := context.WithTimeout(context.Background(), d) defer cancel() - err = run(runCtx, client, d, artifactsDir) + err = run(runCtx, client, d, store) status := api.TestPassed // TODO: what about TestFailed? if err != nil && !errors.Is(err, context.DeadlineExceeded) { app.Errorf("the step failed: %v", err) status = api.TestError } log.Logf(0, "fuzzing is finished") - if err := reportStatus(ctx, client, status, artifactsDir); err != nil { + log.Logf(0, "status at the end:\n%s", store.PlainTextDump()) + if err := reportStatus(ctx, client, status, store); err != nil { app.Fatalf("failed to update the test: %v", err) } } -func run(baseCtx context.Context, client *api.Client, timeout time.Duration, artifactsDir string) error { +func run(baseCtx context.Context, client *api.Client, timeout time.Duration, + store *manager.DiffFuzzerStore) error { series, err := client.GetSessionSeries(baseCtx, *flagSession) if err != nil { return fmt.Errorf("failed to query the series info: %w", err) @@ -128,7 +131,7 @@ func run(baseCtx context.Context, client *api.Client, timeout time.Duration, art return manager.RunDiffFuzzer(ctx, base, patched, manager.DiffFuzzerConfig{ Debug: false, PatchedOnly: bugs, - ArtifactsDir: artifactsDir, + Store: store, MaxTriageTime: timeout / 2, }) }) @@ -145,12 +148,12 @@ func run(baseCtx context.Context, client *api.Client, timeout time.Duration, art return nil case <-time.After(updatePeriod): } - artifacts := "" + var useStore *manager.DiffFuzzerStore if time.Since(lastArtifactUpdate) > artifactUploadPeriod { lastArtifactUpdate = time.Now() - artifacts = artifactsDir + useStore = store } - err := reportStatus(ctx, client, api.TestRunning, artifacts) + err := reportStatus(ctx, client, api.TestRunning, useStore) if err != nil { app.Errorf("failed to update status: %v", err) } @@ -222,7 +225,7 @@ func loadConfigs(configFolder, configName string, complete bool) (*mgrconfig.Con return base, patched, nil } -func reportStatus(ctx context.Context, client *api.Client, status, artifactsDir string) error { +func reportStatus(ctx context.Context, client *api.Client, status string, store *manager.DiffFuzzerStore) error { testResult := &api.TestResult{ SessionID: *flagSession, TestName: testName, @@ -235,10 +238,10 @@ func reportStatus(ctx context.Context, client *api.Client, status, artifactsDir if err != nil { return fmt.Errorf("failed to upload the status: %w", err) } - if artifactsDir == "" { + if store == nil { return nil } - tarGzReader, err := compressArtifacts(artifactsDir) + tarGzReader, err := compressArtifacts(store.BasePath) if err != nil { return fmt.Errorf("failed to compress the artifacts dir: %w", err) } diff --git a/tools/syz-diff/diff.go b/tools/syz-diff/diff.go index f28421dc9..c77728d4a 100644 --- a/tools/syz-diff/diff.go +++ b/tools/syz-diff/diff.go @@ -48,8 +48,8 @@ func main() { ctx := vm.ShutdownCtx() err = manager.RunDiffFuzzer(ctx, baseCfg, newCfg, manager.DiffFuzzerConfig{ - ArtifactsDir: newCfg.Workdir, - Debug: *flagDebug, + Store: &manager.DiffFuzzerStore{BasePath: newCfg.Workdir}, + Debug: *flagDebug, }) if err != nil { log.Fatal(err) |
