aboutsummaryrefslogtreecommitdiffstats
path: root/syz-cluster/workflow
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2025-07-18 12:21:39 +0200
committerAleksandr Nogikh <nogikh@google.com>2025-07-22 14:49:22 +0000
commit0b3a8483a73330b481a0d9fef2e276eb06465bc0 (patch)
treeaebd4c3a914f6c69d6d6f89c8b2e68a6c5d868af /syz-cluster/workflow
parent6ce0983056e7e9efff04681de67e6310b88fdc16 (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.go31
-rw-r--r--syz-cluster/workflow/fuzz-step/main.go47
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{