From a90d2b19fb0b8b7526a51b8bbeb9b887b84503e6 Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Wed, 3 Sep 2025 20:07:34 +0200 Subject: syz-cluster: pass fuzz config to the fuzz step as json Instead of passing the values individually, save the FuzzConfig object as JSON and pass it as an artifact. This will simplify adding more new fields. --- syz-cluster/workflow/fuzz-step/main.go | 51 ++++++++++++++-------- .../workflow/fuzz-step/workflow-template.yaml | 12 ++--- 2 files changed, 36 insertions(+), 27 deletions(-) (limited to 'syz-cluster/workflow') diff --git a/syz-cluster/workflow/fuzz-step/main.go b/syz-cluster/workflow/fuzz-step/main.go index 8704d1d73..fa690dc93 100644 --- a/syz-cluster/workflow/fuzz-step/main.go +++ b/syz-cluster/workflow/fuzz-step/main.go @@ -29,14 +29,12 @@ import ( ) var ( - flagConfig = flag.String("config", "", "syzkaller config") - flagSession = flag.String("session", "", "session ID") - flagBaseBuild = flag.String("base_build", "", "base build ID") - flagPatchedBuild = flag.String("patched_build", "", "patched build ID") - flagTime = flag.String("time", "1h", "how long to fuzz") - flagWorkdir = flag.String("workdir", "/workdir", "base workdir path") - flagCorpusURL = flag.String("corpus_url", "", "an URL to download corpus from") - flagSkipCoverCheck = flag.Bool("skip_cover_check", false, "don't check whether we reached the patched code") + flagConfig = flag.String("config", "", "path to the fuzz config") + flagSession = flag.String("session", "", "session ID") + flagBaseBuild = flag.String("base_build", "", "base build ID") + flagPatchedBuild = flag.String("patched_build", "", "patched build ID") + flagTime = flag.String("time", "1h", "how long to fuzz") + flagWorkdir = flag.String("workdir", "/workdir", "base workdir path") ) const testName = "Fuzzing" @@ -54,6 +52,8 @@ func main() { if !prog.GitRevisionKnown() { log.Fatalf("the binary is built without the git revision information") } + + config := readFuzzConfig() ctx := context.Background() if err := reportStatus(ctx, client, api.TestRunning, nil); err != nil { app.Fatalf("failed to report the test: %v", err) @@ -67,7 +67,7 @@ func main() { // the final test result back. runCtx, cancel := context.WithTimeout(context.Background(), d) defer cancel() - err = run(runCtx, client, d, store) + err = run(runCtx, config, client, d, store) status := api.TestPassed // TODO: what about TestFailed? if errors.Is(err, errSkipFuzzing) { status = api.TestSkipped @@ -82,6 +82,21 @@ func main() { } } +func readFuzzConfig() *api.FuzzConfig { + raw, err := os.ReadFile(*flagConfig) + if err != nil { + app.Fatalf("failed to read config: %v", err) + return nil + } + var req api.FuzzConfig + err = json.Unmarshal(raw, &req) + if err != nil { + app.Fatalf("failed to unmarshal request: %v, %s", err, raw) + return nil + } + return &req +} + func logFinalState(store *manager.DiffFuzzerStore) { log.Logf(0, "status at the end:\n%s", store.PlainTextDump()) @@ -98,8 +113,8 @@ func logFinalState(store *manager.DiffFuzzerStore) { var errSkipFuzzing = errors.New("skip") -func run(baseCtx context.Context, client *api.Client, timeout time.Duration, - store *manager.DiffFuzzerStore) error { +func run(baseCtx context.Context, config *api.FuzzConfig, 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) @@ -110,7 +125,7 @@ func run(baseCtx context.Context, client *api.Client, timeout time.Duration, const MB = 1000000 log.EnableLogCaching(100000, 10*MB) - base, patched, err := loadConfigs("/configs", *flagConfig, true) + base, patched, err := loadConfigs("/configs", config.Config, true) if err != nil { return fmt.Errorf("failed to load configs: %w", err) } @@ -125,12 +140,12 @@ func run(baseCtx context.Context, client *api.Client, timeout time.Duration, } manager.PatchFocusAreas(patched, series.PatchBodies(), baseSymbols.Text, patchedSymbols.Text) - if *flagCorpusURL != "" { - err := downloadCorpus(baseCtx, patched.Workdir, *flagCorpusURL) + if config.CorpusURL != "" { + err := downloadCorpus(baseCtx, patched.Workdir, config.CorpusURL) if err != nil { return fmt.Errorf("failed to download the corpus: %w", err) } else { - log.Logf(0, "downloaded the corpus from %s", *flagCorpusURL) + log.Logf(0, "downloaded the corpus from %s", config.CorpusURL) } } @@ -167,7 +182,7 @@ func run(baseCtx context.Context, client *api.Client, timeout time.Duration, BaseCrashes: baseCrashes, Store: store, MaxTriageTime: timeout / 2, - FuzzToReachPatched: fuzzToReachPatched(), + FuzzToReachPatched: fuzzToReachPatched(config), BaseCrashKnown: func(ctx context.Context, title string) (bool, error) { ret, err := client.BaseFindingStatus(ctx, &api.BaseFindingInfo{ BuildID: *flagBaseBuild, @@ -396,8 +411,8 @@ func readSectionHashes(file string) (build.SectionHashes, error) { return data, nil } -func fuzzToReachPatched() time.Duration { - if *flagSkipCoverCheck { +func fuzzToReachPatched(config *api.FuzzConfig) time.Duration { + if config.SkipCoverCheck { return 0 } // Allow up to 30 minutes after the corpus triage to reach the patched code. diff --git a/syz-cluster/workflow/fuzz-step/workflow-template.yaml b/syz-cluster/workflow/fuzz-step/workflow-template.yaml index 460659a61..5cf77e6b4 100644 --- a/syz-cluster/workflow/fuzz-step/workflow-template.yaml +++ b/syz-cluster/workflow/fuzz-step/workflow-template.yaml @@ -10,33 +10,27 @@ spec: - name: fuzz-step inputs: parameters: - - name: config - value: "" - name: base-build-id value: "" - name: patched-build-id value: "" - - name: corpus-url - value: "" - - name: skip-cover-check - value: "false" artifacts: - name: base-kernel path: /base - name: patched-kernel path: /patched + - name: config + path: /tmp/config.json timeout: 4h container: image: ${IMAGE_PREFIX}fuzz-step:${IMAGE_TAG} imagePullPolicy: IfNotPresent command: ["/bin/fuzz-step"] args: [ - "--config", "{{inputs.parameters.config}}", + "--config", "/tmp/config.json", "--session", "{{workflow.parameters.session-id}}", "--base_build", "{{inputs.parameters.base-build-id}}", "--patched_build", "{{inputs.parameters.patched-build-id}}", - "--corpus_url", "{{inputs.parameters.corpus-url}}", - "--skip_cover_check={{inputs.parameters.skip-cover-check}}", "--time", "3h", "--workdir", "/workdir", "--vv", "1" -- cgit mrf-deployment