diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2026-01-08 13:49:39 +0100 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2026-01-09 14:28:59 +0000 |
| commit | 96e9343c651cbec29d24b687b6f77a3226a6c1a1 (patch) | |
| tree | 40242f4a72e952eaa25b8c8cd809be743d11a470 /syz-cluster | |
| parent | 993a1e9ee26349d7e290ca7de23faeb6781d9001 (diff) | |
syz-cluster: guess base patch by blob hashes from the diff
Before traversing the list of trees, attempt to determine the base
tree/commit by looking at the SHA hashes from the supplied git diffs.
Diffstat (limited to 'syz-cluster')
| -rw-r--r-- | syz-cluster/pkg/triage/commit.go | 3 | ||||
| -rw-r--r-- | syz-cluster/pkg/triage/git.go | 5 | ||||
| -rw-r--r-- | syz-cluster/pkg/triage/tree.go | 9 | ||||
| -rw-r--r-- | syz-cluster/pkg/triage/tree_test.go | 6 | ||||
| -rw-r--r-- | syz-cluster/workflow/triage-step/main.go | 97 |
5 files changed, 99 insertions, 21 deletions
diff --git a/syz-cluster/pkg/triage/commit.go b/syz-cluster/pkg/triage/commit.go index 81c7f6150..53229e32c 100644 --- a/syz-cluster/pkg/triage/commit.go +++ b/syz-cluster/pkg/triage/commit.go @@ -12,8 +12,7 @@ import ( ) // TODO: Some further improvements: -// 1. Consider the blob hashes incorporated into the git diff. These may restrict the set of base commits. -// 2. Add support for experimental sessions: these may be way behind the current HEAD. +// 1. Add support for experimental sessions: these may be way behind the current HEAD. type TreeOps interface { HeadCommit(tree *api.Tree) (*vcs.Commit, error) diff --git a/syz-cluster/pkg/triage/git.go b/syz-cluster/pkg/triage/git.go index 390bd11b1..58437c913 100644 --- a/syz-cluster/pkg/triage/git.go +++ b/syz-cluster/pkg/triage/git.go @@ -7,6 +7,7 @@ import ( "fmt" "os" + "github.com/google/syzkaller/pkg/debugtracer" "github.com/google/syzkaller/pkg/vcs" "github.com/google/syzkaller/syz-cluster/pkg/api" ) @@ -55,3 +56,7 @@ func (ops *GitTreeOps) ApplySeries(commit string, patches [][]byte) error { } return nil } + +func (ops *GitTreeOps) BaseForDiff(patch []byte, tracer debugtracer.DebugTracer) (*vcs.BaseCommit, error) { + return ops.Git.BaseForDiff(patch, tracer) +} diff --git a/syz-cluster/pkg/triage/tree.go b/syz-cluster/pkg/triage/tree.go index 6cd920429..5d75c380a 100644 --- a/syz-cluster/pkg/triage/tree.go +++ b/syz-cluster/pkg/triage/tree.go @@ -45,3 +45,12 @@ func SelectTrees(series *api.Series, trees []*api.Tree) []*api.Tree { }) return result } + +func TreeFromBranch(trees []*api.Tree, branch string) *api.Tree { + for _, tree := range trees { + if strings.HasPrefix(branch, tree.Name+"/") { + return tree + } + } + return nil +} diff --git a/syz-cluster/pkg/triage/tree_test.go b/syz-cluster/pkg/triage/tree_test.go index 7bd9ed3ed..92d3ce014 100644 --- a/syz-cluster/pkg/triage/tree_test.go +++ b/syz-cluster/pkg/triage/tree_test.go @@ -74,3 +74,9 @@ func TestSelectTrees(t *testing.T) { }) } } + +func TestTreeFromBranch(t *testing.T) { + treeA, treeB := &api.Tree{Name: "a"}, &api.Tree{Name: "b"} + assert.Equal(t, treeA, TreeFromBranch([]*api.Tree{treeA, treeB}, "a/some_branch")) + assert.Equal(t, treeB, TreeFromBranch([]*api.Tree{treeA, treeB}, "b/some_branch")) +} diff --git a/syz-cluster/workflow/triage-step/main.go b/syz-cluster/workflow/triage-step/main.go index 37eddd5e8..ff2b51d26 100644 --- a/syz-cluster/workflow/triage-step/main.go +++ b/syz-cluster/workflow/triage-step/main.go @@ -66,7 +66,7 @@ func main() { type seriesTriager struct { debugtracer.DebugTracer client *api.Client - ops triage.TreeOps + ops *triage.GitTreeOps } func (triager *seriesTriager) GetVerdict(ctx context.Context, sessionID string) (*api.TriageResult, error) { @@ -112,12 +112,80 @@ func (triager *seriesTriager) GetVerdict(ctx context.Context, sessionID string) func (triager *seriesTriager) prepareFuzzingTask(ctx context.Context, series *api.Series, trees []*api.Tree, target *triage.MergedFuzzConfig) (*api.FuzzTask, error) { - var skipErr error + result, err := triager.selectFromBlobs(series, trees) + if err != nil { + return nil, fmt.Errorf("selection by blob failed: %w", err) + } + if result == nil { + result, err = triager.selectFromList(ctx, series, trees, target) + if err != nil { + return nil, fmt.Errorf("selection from the list failed: %w", err) + } + } + if result != nil { + triager.Log("continuing with %+v", result) + base := api.BuildRequest{ + TreeName: result.Tree.Name, + TreeURL: result.Tree.URL, + ConfigName: target.KernelConfig, + CommitHash: result.Commit, + Arch: result.Arch, + } + fuzz := &api.FuzzTask{ + Base: base, + Patched: base, + FuzzConfig: *target.FuzzConfig, + } + fuzz.Patched.SeriesID = series.ID + return fuzz, nil + } + return nil, SkipError("no base commit found") +} + +type SelectResult struct { + Tree *api.Tree + Commit string + Arch string +} + +// For now, only amd64 fuzzing is supported. +const fuzzArch = "amd64" + +func (triager *seriesTriager) selectFromBlobs(series *api.Series, trees []*api.Tree) (*SelectResult, error) { + triager.Log("attempting to guess the base commit by blob hashes") + var diff []byte + for _, patch := range series.Patches { + diff = append(diff, patch.Body...) + diff = append(diff, '\n') + } + base, err := triager.ops.BaseForDiff(diff, triager.DebugTracer) + if err != nil { + return nil, err + } else if base == nil { + triager.Log("no candidate base commit is found") + return nil, nil + } + for _, branch := range base.Branches { + tree := triage.TreeFromBranch(trees, branch) + if tree != nil { + return &SelectResult{ + Tree: tree, + Commit: base.Hash, + Arch: fuzzArch, + }, nil + } + } + triager.Log("cannot identify the tree from %q", base.Branches) + return nil, nil +} + +func (triager *seriesTriager) selectFromList(ctx context.Context, series *api.Series, trees []*api.Tree, + target *triage.MergedFuzzConfig) (*SelectResult, error) { + skipErr := SkipError("empty tree list") for _, tree := range trees { triager.Log("considering tree %q", tree.Name) - arch := "amd64" lastBuild, err := triager.client.LastBuild(ctx, &api.LastBuildReq{ - Arch: arch, + Arch: fuzzArch, ConfigName: target.KernelConfig, TreeName: tree.Name, Status: api.BuildSuccess, @@ -140,21 +208,12 @@ func (triager *seriesTriager) prepareFuzzingTask(ctx context.Context, series *ap triager.Log("failed to find a base commit for %q", tree.Name) continue } - triager.Log("selected base commit: %s", result.Commit) - base := api.BuildRequest{ - TreeName: tree.Name, - TreeURL: tree.URL, - ConfigName: target.KernelConfig, - CommitHash: result.Commit, - Arch: arch, - } - fuzz := &api.FuzzTask{ - Base: base, - Patched: base, - FuzzConfig: *target.FuzzConfig, - } - fuzz.Patched.SeriesID = series.ID - return fuzz, nil + triager.Log("result: %s", result.Commit) + return &SelectResult{ + Tree: tree, + Commit: result.Commit, + Arch: fuzzArch, + }, nil } return nil, skipErr } |
