Skip to content

Commit 5f3897e

Browse files
committed
syz-cluster: use base-commit hint from patch series for triage
If the series author provided a base-commit, use it. If applying the series against the base-commit fails, fall back to the default bisection method.
1 parent f7cfc62 commit 5f3897e

File tree

9 files changed

+111
-62
lines changed

9 files changed

+111
-62
lines changed

pkg/email/lore/parse.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,13 @@ type Thread struct {
2525

2626
// Series represents a single patch series sent over email.
2727
type Series struct {
28-
Subject string
29-
MessageID string
30-
Version int
31-
Corrupted string // If non-empty, contains a reason why the series better be ignored.
32-
Tags []string
33-
Patches []Patch
28+
Subject string
29+
MessageID string
30+
Version int
31+
Corrupted string // If non-empty, contains a reason why the series better be ignored.
32+
Tags []string
33+
Patches []Patch
34+
BaseCommitHint string
3435
}
3536

3637
type Patch struct {
@@ -88,6 +89,13 @@ func PatchSeries(emails []*Email) []*Series {
8889
if !ok {
8990
continue
9091
}
92+
if series.BaseCommitHint == "" { // Usually base-commit is in patch 0 or 1. Check them all to be safe.
93+
regex := regexp.MustCompile(`(?m)^base-commit:\s*([0-9a-fA-F]{40})$`)
94+
matches := regex.FindStringSubmatch(email.Body)
95+
if len(matches) >= 2 {
96+
series.BaseCommitHint = matches[1]
97+
}
98+
}
9199
seq := patch.Seq.ValueOr(1)
92100
if seq == 0 {
93101
// The cover email is not of interest.

syz-cluster/pkg/api/api.go

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,16 +127,17 @@ type NewFinding struct {
127127
}
128128

129129
type Series struct {
130-
ID string `json:"id"` // Only included in the reply.
131-
ExtID string `json:"ext_id"`
132-
Title string `json:"title"`
133-
AuthorEmail string `json:"author_email"`
134-
Cc []string `json:"cc"`
135-
Version int `json:"version"`
136-
Link string `json:"link"`
137-
SubjectTags []string `json:"subject_tags"`
138-
PublishedAt time.Time `json:"published_at"`
139-
Patches []SeriesPatch `json:"patches"`
130+
ID string `json:"id"` // Only included in the reply.
131+
ExtID string `json:"ext_id"`
132+
Title string `json:"title"`
133+
AuthorEmail string `json:"author_email"`
134+
Cc []string `json:"cc"`
135+
Version int `json:"version"`
136+
Link string `json:"link"`
137+
SubjectTags []string `json:"subject_tags"`
138+
PublishedAt time.Time `json:"published_at"`
139+
Patches []SeriesPatch `json:"patches"`
140+
BaseCommitHint string `json:"base_commit"`
140141
}
141142

142143
func (s *Series) PatchBodies() [][]byte {

syz-cluster/pkg/db/entities.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ import (
1010
)
1111

1212
type Series struct {
13-
ID string `spanner:"ID"`
14-
ExtID string `spanner:"ExtID"`
15-
AuthorName string `spanner:"AuthorName"`
16-
AuthorEmail string `spanner:"AuthorEmail"`
17-
Title string `spanner:"Title"`
18-
Link string `spanner:"Link"`
19-
Version int64 `spanner:"Version"`
13+
ID string `spanner:"ID"`
14+
ExtID string `spanner:"ExtID"`
15+
AuthorName string `spanner:"AuthorName"`
16+
AuthorEmail string `spanner:"AuthorEmail"`
17+
Title string `spanner:"Title"`
18+
Link string `spanner:"Link"`
19+
Version int64 `spanner:"Version"`
20+
BaseCommitHint string `spanner:"BaseCommitHint"`
2021
// In LKML patches, there are often hints at the target tree for the patch.
2122
SubjectTags []string `spanner:"SubjectTags"`
2223
PublishedAt time.Time `spanner:"PublishedAt"`
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE Series DROP COLUMN BaseCommitHint;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE Series ADD COLUMN BaseCommitHint STRING(256);

syz-cluster/pkg/service/series.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,15 @@ func (s *SeriesService) getSessionSeries(ctx context.Context, sessionID string,
5454

5555
func (s *SeriesService) UploadSeries(ctx context.Context, series *api.Series) (*api.UploadSeriesResp, error) {
5656
seriesObj := &db.Series{
57-
ID: uuid.NewString(),
58-
ExtID: series.ExtID,
59-
AuthorEmail: series.AuthorEmail,
60-
Title: series.Title,
61-
Version: int64(series.Version),
62-
Link: series.Link,
63-
PublishedAt: series.PublishedAt,
64-
Cc: series.Cc,
57+
ID: uuid.NewString(),
58+
ExtID: series.ExtID,
59+
AuthorEmail: series.AuthorEmail,
60+
Title: series.Title,
61+
Version: int64(series.Version),
62+
Link: series.Link,
63+
PublishedAt: series.PublishedAt,
64+
Cc: series.Cc,
65+
BaseCommitHint: series.BaseCommitHint,
6566
}
6667
for _, tag := range series.SubjectTags {
6768
const tageSizeLimit = 511
@@ -120,15 +121,16 @@ func (s *SeriesService) getSeries(ctx context.Context,
120121
return nil, fmt.Errorf("failed to fetch patches: %w", err)
121122
}
122123
ret := &api.Series{
123-
ID: series.ID,
124-
ExtID: series.ExtID,
125-
Title: series.Title,
126-
AuthorEmail: series.AuthorEmail,
127-
Version: int(series.Version),
128-
Cc: series.Cc,
129-
PublishedAt: series.PublishedAt,
130-
Link: series.Link,
131-
SubjectTags: series.SubjectTags,
124+
ID: series.ID,
125+
ExtID: series.ExtID,
126+
Title: series.Title,
127+
AuthorEmail: series.AuthorEmail,
128+
Version: int(series.Version),
129+
Cc: series.Cc,
130+
PublishedAt: series.PublishedAt,
131+
Link: series.Link,
132+
SubjectTags: series.SubjectTags,
133+
BaseCommitHint: series.BaseCommitHint,
132134
}
133135
for _, patch := range patches {
134136
var body []byte

syz-cluster/pkg/triage/commit.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,15 @@ func (cs *CommitSelector) Select(series *api.Series, tree *api.Tree, lastBuild *
8181
}
8282
return SelectResult{Reason: reasonNotApplies}, nil
8383
}
84+
85+
func (cs *CommitSelector) TrySelectWithHint(series *api.Series) (SelectResult, error) {
86+
if series.BaseCommitHint == "" {
87+
return SelectResult{}, nil
88+
}
89+
var git GitTreeOps
90+
baseCommit, err := git.Git.Commit(series.BaseCommitHint)
91+
if err != nil {
92+
return SelectResult{}, err
93+
}
94+
return SelectResult{Commit: baseCommit.Hash}, nil
95+
}

syz-cluster/series-tracker/main.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -154,13 +154,14 @@ func (sf *SeriesFetcher) handleSeries(ctx context.Context, series *lore.Series,
154154
date = time.Now()
155155
}
156156
apiSeries := &api.Series{
157-
ExtID: series.MessageID,
158-
AuthorEmail: first.Author,
159-
Title: series.Subject,
160-
Version: series.Version,
161-
SubjectTags: series.Tags,
162-
Link: loreLink(series.MessageID),
163-
PublishedAt: date,
157+
ExtID: series.MessageID,
158+
AuthorEmail: first.Author,
159+
Title: series.Subject,
160+
Version: series.Version,
161+
SubjectTags: series.Tags,
162+
Link: loreLink(series.MessageID),
163+
PublishedAt: date,
164+
BaseCommitHint: series.BaseCommitHint,
164165
}
165166
sp := seriesProcessor{}
166167
for i, patch := range series.Patches {

syz-cluster/workflow/triage-step/main.go

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,24 @@ func (triager *seriesTriager) GetVerdict(ctx context.Context, sessionID string)
113113
func (triager *seriesTriager) prepareFuzzingTask(ctx context.Context, series *api.Series, trees []*api.Tree,
114114
target *triage.MergedFuzzConfig) (*api.FuzzTask, error) {
115115
var skipErr error
116+
selector := triage.NewCommitSelector(triager.ops, triager.DebugTracer)
117+
118+
// First try to use hints from the series description.
119+
if series.BaseCommitHint != "" {
120+
for _, tree := range trees {
121+
triager.Log("considering tree %q with a hint", tree.Name)
122+
result, err := selector.TrySelectWithHint(series)
123+
if err != nil {
124+
return nil, fmt.Errorf("failed to run TrySelectWithHint for %q: %w", tree.Name, err)
125+
}
126+
if result.Commit != "" {
127+
triager.Log("selected base commit with hint: %s", result.Commit)
128+
return buildFuzzTask(series, tree, target, result.Commit), nil
129+
}
130+
triager.Log("failed to find a base commit with hint for %q: %s", tree.Name, result.Reason)
131+
}
132+
}
133+
116134
for _, tree := range trees {
117135
triager.Log("considering tree %q", tree.Name)
118136
arch := "amd64"
@@ -127,7 +145,6 @@ func (triager *seriesTriager) prepareFuzzingTask(ctx context.Context, series *ap
127145
return nil, fmt.Errorf("failed to query the last build for %q: %w", tree.Name, err)
128146
}
129147
triager.Log("%q's last build: %q", tree.Name, lastBuild)
130-
selector := triage.NewCommitSelector(triager.ops, triager.DebugTracer)
131148
result, err := selector.Select(series, tree, lastBuild)
132149
if err != nil {
133150
// TODO: the workflow step must be retried.
@@ -141,24 +158,29 @@ func (triager *seriesTriager) prepareFuzzingTask(ctx context.Context, series *ap
141158
continue
142159
}
143160
triager.Log("selected base commit: %s", result.Commit)
144-
base := api.BuildRequest{
145-
TreeName: tree.Name,
146-
TreeURL: tree.URL,
147-
ConfigName: target.KernelConfig,
148-
CommitHash: result.Commit,
149-
Arch: arch,
150-
}
151-
fuzz := &api.FuzzTask{
152-
Base: base,
153-
Patched: base,
154-
FuzzConfig: *target.FuzzConfig,
155-
}
156-
fuzz.Patched.SeriesID = series.ID
157-
return fuzz, nil
161+
return buildFuzzTask(series, tree, target, result.Commit), nil
158162
}
159163
return nil, skipErr
160164
}
161165

166+
func buildFuzzTask(series *api.Series, tree *api.Tree, target *triage.MergedFuzzConfig, commit string) *api.FuzzTask {
167+
arch := "amd64"
168+
base := api.BuildRequest{
169+
TreeName: tree.Name,
170+
TreeURL: tree.URL,
171+
ConfigName: target.KernelConfig,
172+
CommitHash: commit,
173+
Arch: arch,
174+
}
175+
fuzz := &api.FuzzTask{
176+
Base: base,
177+
Patched: base,
178+
FuzzConfig: *target.FuzzConfig,
179+
}
180+
fuzz.Patched.SeriesID = series.ID
181+
return fuzz
182+
}
183+
162184
type SkipTriageError struct {
163185
Reason error
164186
}

0 commit comments

Comments
 (0)