diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2025-07-18 12:21:39 +0200 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2025-07-22 14:49:22 +0000 |
| commit | 0b3a8483a73330b481a0d9fef2e276eb06465bc0 (patch) | |
| tree | aebd4c3a914f6c69d6d6f89c8b2e68a6c5d868af /syz-cluster/workflow | |
| parent | 6ce0983056e7e9efff04681de67e6310b88fdc16 (diff) | |
all: determine patched symbols for focused fuzzing
Hash the code section of the individual symbols from vmlinux.o and use
it to determine the functions that changed their bodies between the base
and the patched build.
If the number of affected symbols is reasonable (<5%), fuzz it with the
highest priority.
Diffstat (limited to 'syz-cluster/workflow')
| -rw-r--r-- | syz-cluster/workflow/build-step/main.go | 31 | ||||
| -rw-r--r-- | syz-cluster/workflow/fuzz-step/main.go | 47 |
2 files changed, 69 insertions, 9 deletions
diff --git a/syz-cluster/workflow/build-step/main.go b/syz-cluster/workflow/build-step/main.go index 1abf5bc4a..3797681ea 100644 --- a/syz-cluster/workflow/build-step/main.go +++ b/syz-cluster/workflow/build-step/main.go @@ -10,6 +10,10 @@ import ( "errors" "flag" "fmt" + "log" + "os" + "path/filepath" + "github.com/google/syzkaller/pkg/build" "github.com/google/syzkaller/pkg/debugtracer" "github.com/google/syzkaller/pkg/osutil" @@ -18,9 +22,6 @@ import ( "github.com/google/syzkaller/syz-cluster/pkg/api" "github.com/google/syzkaller/syz-cluster/pkg/app" "github.com/google/syzkaller/syz-cluster/pkg/triage" - "log" - "os" - "path/filepath" ) var ( @@ -261,8 +262,14 @@ func buildKernel(tracer debugtracer.DebugTracer, req *api.BuildRequest) (*BuildR return nil, err } tracer.Log("build finished successfully") + + err = saveSymbolHashes(tracer) + if err != nil { + tracer.Log("failed to save symbol hashes: %s", err) + } // Note: Output directory has the following structure: // |-- image + // |-- symbol_hashes.json // |-- kernel // |-- kernel.config // `-- obj @@ -270,6 +277,24 @@ func buildKernel(tracer debugtracer.DebugTracer, req *api.BuildRequest) (*BuildR return ret, nil } +func saveSymbolHashes(tracer debugtracer.DebugTracer) error { + hashes, err := build.ElfSymbolHashes(filepath.Join(*flagRepository, "vmlinux.o")) + if err != nil { + return fmt.Errorf("failed to query symbol hashes: %w", err) + } + tracer.Log("extracted hashes for %d symbols", len(hashes)) + file, err := os.Create(filepath.Join(*flagOutput, "symbol_hashes.json")) + if err != nil { + return fmt.Errorf("failed to open symbol_hashes.json: %w", err) + } + defer file.Close() + err = json.NewEncoder(file).Encode(hashes) + if err != nil { + return fmt.Errorf("failed to serialize: %w", err) + } + return nil +} + func ensureFlags(args ...string) { for i := 0; i+1 < len(args); i += 2 { if args[i] == "" { diff --git a/syz-cluster/workflow/fuzz-step/main.go b/syz-cluster/workflow/fuzz-step/main.go index 6996ae8a0..f7ed5ef39 100644 --- a/syz-cluster/workflow/fuzz-step/main.go +++ b/syz-cluster/workflow/fuzz-step/main.go @@ -10,6 +10,12 @@ import ( "errors" "flag" "fmt" + "io" + "net/http" + "os" + "path/filepath" + "time" + "github.com/google/syzkaller/pkg/config" "github.com/google/syzkaller/pkg/log" "github.com/google/syzkaller/pkg/manager" @@ -19,11 +25,6 @@ import ( "github.com/google/syzkaller/syz-cluster/pkg/api" "github.com/google/syzkaller/syz-cluster/pkg/app" "golang.org/x/sync/errgroup" - "io" - "net/http" - "os" - "path/filepath" - "time" ) var ( @@ -93,7 +94,12 @@ func run(baseCtx context.Context, client *api.Client, timeout time.Duration, if err != nil { return fmt.Errorf("failed to load configs: %w", err) } - manager.PatchFocusAreas(patched, series.PatchBodies()) + + baseSymbols, patchedSymbols, err := readSymbolHashes() + if err != nil { + app.Errorf("failed to read symbol hashes: %v", err) + } + manager.PatchFocusAreas(patched, series.PatchBodies(), baseSymbols, patchedSymbols) if *flagCorpusURL != "" { err := downloadCorpus(baseCtx, patched.Workdir, *flagCorpusURL) @@ -282,6 +288,35 @@ func reportFinding(ctx context.Context, client *api.Client, bug *manager.UniqueB return client.UploadFinding(ctx, finding) } +func readSymbolHashes() (base, patched map[string]string, err error) { + // These are saved by the build step. + base, err = readJSONMap("/base/symbol_hashes.json") + if err != nil { + return nil, nil, fmt.Errorf("failed to read base hashes: %w", err) + } + patched, err = readJSONMap("/patched/symbol_hashes.json") + if err != nil { + return nil, nil, fmt.Errorf("failed to read patched hashes: %w", err) + } + log.Logf(0, "extracted %d symbol hashes for base and %d for patched", len(base), len(patched)) + return +} + +func readJSONMap(file string) (map[string]string, error) { + f, err := os.Open(file) + if err != nil { + return nil, err + } + defer f.Close() + + var data map[string]string + err = json.NewDecoder(f).Decode(&data) + if err != nil { + return nil, err + } + return data, nil +} + func compressArtifacts(dir string) (io.Reader, error) { var buf bytes.Buffer lw := &LimitedWriter{ |
