Skip to content

Commit 48e0634

Browse files
committed
syz-cluster: use the virtio networking device with KMSAN
e1000 is temporarily not an option due to a boot-time bug: https://lkml.org/lkml/2025/10/2/143 Refactor the config generation logic to accomodate merging multiple config chunks.
1 parent 8b4f0dd commit 48e0634

File tree

6 files changed

+201
-28
lines changed

6 files changed

+201
-28
lines changed

syz-cluster/pkg/api/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ type FuzzConfig struct {
3434
Track string `json:"track"` // E.g. KASAN.
3535
Focus []string `json:"focus"`
3636
CorpusURLs []string `json:"corpus_urls"`
37+
KMSAN bool `json:"kmsan"` // Needed for some temporary workarounds.
3738
// Don't expect kernel coverage for the patched area.
3839
SkipCoverCheck bool `json:"skip_cover_check"`
3940
// Only report the bugs that match the regexp.

syz-cluster/pkg/fuzzconfig/generate.go

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,50 +19,59 @@ var baseConfigJSON []byte
1919
//go:embed patched.cfg
2020
var patchedConfigJSON []byte
2121

22+
//go:embed kmsan.cfg
23+
var kmsanConfigJSON []byte
24+
2225
// GenerateBase produces a syz-manager config for the base kernel.
2326
// The caller must still invoke mgrconfig.Complete.
2427
func GenerateBase(cfg *api.FuzzConfig) (*mgrconfig.Config, error) {
25-
var baseRaw json.RawMessage
26-
err := config.LoadData(baseConfigJSON, &baseRaw)
27-
if err != nil {
28-
return nil, fmt.Errorf("failed to read the base config: %w", err)
29-
}
30-
base, err := mgrconfig.LoadPartialData(baseRaw)
31-
if err != nil {
32-
return nil, fmt.Errorf("failed to load the config: %w", err)
33-
}
34-
err = applyFuzzConfig(base, cfg)
35-
if err != nil {
36-
return nil, err
37-
}
38-
return base, nil
28+
return generateConfig(cfg, false)
3929
}
4030

41-
// GeneratePatched produces a syz-manager config for the base kernel.
31+
// GeneratePatched produces a syz-manager config for the patched kernel.
4232
// The caller must still invoke mgrconfig.Complete.
4333
func GeneratePatched(cfg *api.FuzzConfig) (*mgrconfig.Config, error) {
44-
var baseRaw, deltaRaw json.RawMessage
45-
err := config.LoadData(baseConfigJSON, &baseRaw)
46-
if err != nil {
47-
return nil, fmt.Errorf("failed to read the base config: %w", err)
34+
return generateConfig(cfg, true)
35+
}
36+
37+
func generateConfig(cfg *api.FuzzConfig, patched bool) (*mgrconfig.Config, error) {
38+
type patchItem struct {
39+
name string
40+
patch []byte
4841
}
49-
err = config.LoadData(patchedConfigJSON, &deltaRaw)
50-
if err != nil {
51-
return nil, fmt.Errorf("failed to read the patched config: %w", err)
42+
patchesList := []patchItem{{name: "base", patch: baseConfigJSON}}
43+
if patched {
44+
patchesList = append(patchesList, patchItem{name: "patched", patch: patchedConfigJSON})
5245
}
53-
patchedRaw, err := config.MergeJSONs(baseRaw, deltaRaw)
54-
if err != nil {
55-
return nil, fmt.Errorf("failed to merge the configs: %w", err)
46+
if cfg.KMSAN {
47+
patchesList = append(patchesList, patchItem{name: "kmsan", patch: kmsanConfigJSON})
48+
}
49+
var raw json.RawMessage
50+
for i, patch := range patchesList {
51+
var next json.RawMessage
52+
err := config.LoadData(patch.patch, &next)
53+
if err != nil {
54+
return nil, fmt.Errorf("failed to read the %s config: %w", patch.name, err)
55+
}
56+
if i == 0 {
57+
raw = next
58+
} else {
59+
var err error
60+
raw, err = config.MergeJSONs(raw, next)
61+
if err != nil {
62+
return nil, fmt.Errorf("failed to merge the configs with %s: %w", patch.name, err)
63+
}
64+
}
5665
}
57-
patched, err := mgrconfig.LoadPartialData(patchedRaw)
66+
mgrConfig, err := mgrconfig.LoadPartialData(raw)
5867
if err != nil {
5968
return nil, fmt.Errorf("failed to load the config: %w", err)
6069
}
61-
err = applyFuzzConfig(patched, cfg)
70+
err = applyFuzzConfig(mgrConfig, cfg)
6271
if err != nil {
6372
return nil, err
6473
}
65-
return patched, nil
74+
return mgrConfig, nil
6675
}
6776

6877
func applyFuzzConfig(mgrCfg *mgrconfig.Config, cfg *api.FuzzConfig) error {

syz-cluster/pkg/fuzzconfig/generate_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ func TestMultipleFocus(t *testing.T) {
4646
}, filepath.Join("testdata", "mixed", "bpf_io_uring"))
4747
}
4848

49+
func TestKMSANConfig(t *testing.T) {
50+
runTest(t, &api.FuzzConfig{
51+
Focus: []string{api.FocusBPF},
52+
KMSAN: true,
53+
}, filepath.Join("testdata", "mixed", "bpf_kmsan"))
54+
}
55+
4956
func runTest(t *testing.T, cfg *api.FuzzConfig, baseName string) {
5057
base, err := GenerateBase(cfg)
5158
require.NoError(t, err)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"vm": {
3+
"network_device": "virtio-net-pci"
4+
}
5+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{
2+
"name": "base",
3+
"target": "linux/amd64",
4+
"http": "",
5+
"rpc": ":0",
6+
"workdir": "/workdir",
7+
"kernel_obj": "/base/obj",
8+
"kernel_build_src": "/workdir",
9+
"android_split_build": false,
10+
"image": "/base/image",
11+
"ssh_user": "root",
12+
"syzkaller": "/syzkaller",
13+
"procs": 3,
14+
"max_crash_logs": 100,
15+
"sandbox": "none",
16+
"sandbox_arg": 0,
17+
"snapshot": false,
18+
"cover": true,
19+
"cover_filter": {},
20+
"raw_cover": false,
21+
"reproduce": true,
22+
"preserve_corpus": true,
23+
"enable_syscalls": [
24+
"bpf",
25+
"mkdir",
26+
"mount$bpf",
27+
"unlink",
28+
"close",
29+
"perf_event_open*",
30+
"ioctl$PERF*",
31+
"getpid",
32+
"gettid",
33+
"socketpair",
34+
"sendmsg",
35+
"recvmsg",
36+
"setsockopt$sock_attach_bpf",
37+
"socket",
38+
"ioctl$sock_kcm*",
39+
"syz_clone",
40+
"mkdirat$cgroup*",
41+
"openat$cgroup*",
42+
"write$cgroup*",
43+
"openat$tun",
44+
"write$tun",
45+
"ioctl$TUN*",
46+
"ioctl$SIOCSIFHWADDR",
47+
"openat$ppp",
48+
"syz_open_procfs$namespace",
49+
"openat$pidfd",
50+
"fstat"
51+
],
52+
"strace_bin": "",
53+
"strace_bin_on_target": false,
54+
"execprog_bin_on_target": "",
55+
"executor_bin_on_target": "",
56+
"run_fsck": true,
57+
"type": "qemu",
58+
"vm": {
59+
"cmdline": "root=/dev/sda1",
60+
"count": 3,
61+
"cpu": 2,
62+
"kernel": "/base/kernel",
63+
"mem": 7168,
64+
"network_device": "virtio-net-pci",
65+
"qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
66+
},
67+
"asset_storage": null,
68+
"Experimental": {
69+
"reset_acc_state": false,
70+
"remote_cover": true,
71+
"cover_edges": false,
72+
"descriptions_mode": "manual",
73+
"enable_kfuzztest": false
74+
}
75+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
"name": "patched",
3+
"target": "linux/amd64",
4+
"http": "",
5+
"rpc": ":0",
6+
"workdir": "/workdir",
7+
"kernel_obj": "/patched/obj",
8+
"kernel_build_src": "/workdir",
9+
"android_split_build": false,
10+
"image": "/patched/image",
11+
"ssh_user": "root",
12+
"syzkaller": "/syzkaller",
13+
"procs": 3,
14+
"max_crash_logs": 100,
15+
"sandbox": "none",
16+
"sandbox_arg": 0,
17+
"snapshot": false,
18+
"cover": true,
19+
"cover_filter": {},
20+
"raw_cover": false,
21+
"reproduce": true,
22+
"fuzzing_vms": 3,
23+
"preserve_corpus": true,
24+
"enable_syscalls": [
25+
"bpf",
26+
"mkdir",
27+
"mount$bpf",
28+
"unlink",
29+
"close",
30+
"perf_event_open*",
31+
"ioctl$PERF*",
32+
"getpid",
33+
"gettid",
34+
"socketpair",
35+
"sendmsg",
36+
"recvmsg",
37+
"setsockopt$sock_attach_bpf",
38+
"socket",
39+
"ioctl$sock_kcm*",
40+
"syz_clone",
41+
"mkdirat$cgroup*",
42+
"openat$cgroup*",
43+
"write$cgroup*",
44+
"openat$tun",
45+
"write$tun",
46+
"ioctl$TUN*",
47+
"ioctl$SIOCSIFHWADDR",
48+
"openat$ppp",
49+
"syz_open_procfs$namespace",
50+
"openat$pidfd",
51+
"fstat"
52+
],
53+
"strace_bin": "",
54+
"strace_bin_on_target": false,
55+
"execprog_bin_on_target": "",
56+
"executor_bin_on_target": "",
57+
"run_fsck": true,
58+
"type": "qemu",
59+
"vm": {
60+
"cmdline": "root=/dev/sda1",
61+
"count": 9,
62+
"cpu": 2,
63+
"kernel": "/patched/kernel",
64+
"mem": 7168,
65+
"network_device": "virtio-net-pci",
66+
"qemu_args": "-machine q35 -enable-kvm -smp 2,sockets=2,cores=1"
67+
},
68+
"asset_storage": null,
69+
"Experimental": {
70+
"reset_acc_state": false,
71+
"remote_cover": true,
72+
"cover_edges": false,
73+
"descriptions_mode": "manual",
74+
"enable_kfuzztest": false
75+
}
76+
}

0 commit comments

Comments
 (0)