Skip to content

Commit 4b9e0bf

Browse files
committed
pkg/aflow/flow/patching: add bug fix patching workflow
1 parent 963dd62 commit 4b9e0bf

File tree

2 files changed

+195
-0
lines changed

2 files changed

+195
-0
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2025 syzkaller project authors. All rights reserved.
2+
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
3+
4+
package patching
5+
6+
import (
7+
"github.com/google/syzkaller/pkg/aflow"
8+
"github.com/google/syzkaller/pkg/aflow/action/kernel"
9+
"github.com/google/syzkaller/pkg/vcs"
10+
)
11+
12+
var baseCommitPicker = aflow.NewFuncAction("base-commit-picker", pickBaseCommit)
13+
14+
type baseCommitArgs struct {
15+
// Can be used to override the selected base commit (for manual testing).
16+
FixedBaseCommit string
17+
}
18+
19+
type baseCommitResult struct {
20+
KernelRepo string
21+
KernelCommit string
22+
}
23+
24+
func pickBaseCommit(ctx *aflow.Context, args baseCommitArgs) (baseCommitResult, error) {
25+
// Currently we use the latest RC of the mainline tree as the base.
26+
// This is a reasonable choice overall in lots of cases, and it enables good caching
27+
// of all artifacts (we need to rebuild them only approx every week).
28+
// Potentially we can use subsystem trees for few important, well-maintained subsystems
29+
// (mm, net, etc). However, it will work poorly for all subsystems. First, there is no
30+
// machine-usable mapping of subsystems to repo/branch; second, lots of them are poorly
31+
// maintained (can be much older than latest RC); third, it will make artifact caching
32+
// much worse.
33+
// In the future we ought to support automated rebasing of patches to requested trees/commits.
34+
// We need it anyway, but it will also alleviate imperfect base commit picking.
35+
const (
36+
baseRepo = "git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git"
37+
baseBranch = "master"
38+
)
39+
40+
res := baseCommitResult{
41+
KernelRepo: baseRepo,
42+
KernelCommit: args.FixedBaseCommit,
43+
}
44+
if args.FixedBaseCommit != "" {
45+
return res, nil
46+
}
47+
48+
err := kernel.UseLinuxRepo(ctx, func(_ string, repo vcs.Repo) error {
49+
head, err := repo.Poll(baseRepo, baseBranch)
50+
if err != nil {
51+
return err
52+
}
53+
res.KernelCommit, err = repo.ReleaseTag(head.Hash)
54+
return err
55+
})
56+
return res, err
57+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
// Copyright 2025 syzkaller project authors. All rights reserved.
2+
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
3+
4+
package patching
5+
6+
import (
7+
"encoding/json"
8+
9+
"github.com/google/syzkaller/pkg/aflow"
10+
"github.com/google/syzkaller/pkg/aflow/action/crash"
11+
"github.com/google/syzkaller/pkg/aflow/action/kernel"
12+
"github.com/google/syzkaller/pkg/aflow/ai"
13+
"github.com/google/syzkaller/pkg/aflow/tool/codesearcher"
14+
)
15+
16+
type Inputs struct {
17+
ReproOpts string
18+
ReproSyz string
19+
ReproC string
20+
KernelConfig string
21+
SyzkallerCommit string
22+
CodesearchToolBin string
23+
24+
// Same as in the manager config.
25+
Syzkaller string
26+
Image string
27+
Type string
28+
VM json.RawMessage
29+
30+
// Use this fixed based kernel commit (for testing/local running).
31+
FixedBaseCommit string
32+
}
33+
34+
type Outputs struct {
35+
PatchDescription string
36+
PatchDiff string
37+
}
38+
39+
func init() {
40+
tools := codesearcher.Tools
41+
42+
aflow.Register[Inputs, Outputs](
43+
ai.WorkflowPatching,
44+
"generate a kernel patch fixing a provided bug reproducer",
45+
&aflow.Flow{
46+
Root: &aflow.Pipeline{
47+
Actions: []aflow.Action{
48+
baseCommitPicker,
49+
kernel.Checkout,
50+
kernel.Build,
51+
// Ensure we can reproduce the crash (and the build boots).
52+
crash.Reproduce,
53+
codesearcher.PrepareIndex,
54+
&aflow.LLMAgent{
55+
Name: "debugger",
56+
Reply: "BugExplanation",
57+
Temperature: 1,
58+
Instruction: debuggingInstruction,
59+
Prompt: debuggingPrompt,
60+
Tools: tools,
61+
},
62+
&aflow.LLMAgent{
63+
Name: "diff-generator",
64+
Reply: "PatchDiff",
65+
Temperature: 1,
66+
Instruction: diffInstruction,
67+
Prompt: diffPrompt,
68+
Tools: tools,
69+
},
70+
&aflow.LLMAgent{
71+
Name: "description-generator",
72+
Reply: "PatchDescription",
73+
Temperature: 1,
74+
Instruction: descriptionInstruction,
75+
Prompt: descriptionPrompt,
76+
},
77+
},
78+
},
79+
},
80+
)
81+
}
82+
83+
// TODO: mention not doing assumptions about the source code, and instead querying code using tools.
84+
// TODO: mention to extensively use provided tools to confirm everything.
85+
// TODO: use cause bisection info, if available.
86+
87+
const debuggingInstruction = `
88+
You are an experienced Linux kernel developer tasked with debugging a kernel crash root cause.
89+
You need to provide a detailed explanation of the root cause for another developer to be
90+
able to write a fix for the bug based on your explanation.
91+
Your final reply must contain only the explanation.
92+
93+
Call some codesearch tools first.
94+
`
95+
96+
const debuggingPrompt = `
97+
The crash is:
98+
99+
{{.CrashReport}}
100+
`
101+
102+
const diffInstruction = `
103+
You are an experienced Linux kernel developer tasked with creating a patch for a kernel bug.
104+
Your final reply should contain only the code diff in patch format.
105+
`
106+
107+
const diffPrompt = `
108+
The crash that corresponds to the bug is:
109+
110+
{{.CrashReport}}
111+
112+
The explanation of the root cause of the bug is:
113+
114+
{{.BugExplanation}}
115+
`
116+
117+
const descriptionInstruction = `
118+
You are an experienced Linux kernel developer tasked with writing a commit description for
119+
a kernel bug fixing commit. The description should start with a one-line summary,
120+
and then include description of the bug being fixed, and how it's fixed by the provided patch.
121+
Your final reply should contain only the text of the commit description.
122+
Phrase the one-line summary so that it is not longer than 72 characters.
123+
The rest of the description must be word-wrapped at 72 characters.
124+
`
125+
126+
const descriptionPrompt = `
127+
The crash that corresponds to the bug is:
128+
129+
{{.CrashReport}}
130+
131+
The explanation of the root cause of the bug is:
132+
133+
{{.BugExplanation}}
134+
135+
The diff of the bug fix is:
136+
137+
{{.PatchDiff}}
138+
`

0 commit comments

Comments
 (0)